User:Khanson/editsuggest.js

//script config var es_namespaces = [0, 10, 14, 6] var es_namespaces_names = {0: '', 6:'Image', 10:'\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0{\{\u00A0', 14:'Category'} if (wgContentLanguage == 'ru') { es_namespaces_names[14] = 'Категория' es_namespaces_names[6] = 'Изображение' }

var editSuggest = new function{ //global wrapper

var esForm, esText, linkName, esNS, isCtrlOrShift, txtBox, keyPrev var selRange, selScroll, selWorking

this.start = function{ if (!esForm) init if (esForm.style.display == 'none'){ esText.value = getWikiText setNS(0) showForm(true) }else{ focusTextarea //second click - hide form } }

this.insert = ev_onsubmit

function init{ txtBox = document.getElementById('wpTextbox1') //create form esForm = document.createElement('form') esForm.id = 'es_form' esForm.action = 'javascript:editSuggest.insert' esForm.style.cssText = 'position:absolute; z-index:100; border:1px solid gray; padding:1px; background:#E0E0E0; opacity:0.8' //try { esForm.style.background = 'inherit'} catch(e){esForm.style.background = 'white'} //damn IE //add label var lbl = document.createElement('span') lbl.id = 'es_label' lbl.style.cssText = 'background:inherit; width:2em; font-size:125%; cursor:pointer; padding-right:5px' addHandler(lbl, 'click', cycleNS) esForm.appendChild(lbl) //add text field esText = appendInput('text', 'es_text', 'width:350px') esText.tabIndex = 0 addHandler(esText, 'keydown', ev_onkeydown) addHandler(esText, 'keyup', ev_onkeyup) //add NS field esNS = appendInput('hidden', 'es_namespace') esNS.value = 1 //position form var pos = os_getElementPosition('wpTextbox1') esForm.style.top = (pos.top +2)+'px' esForm.style.left = (pos.left+2)+'px' //attach form and enable autosuggest document.body.appendChild(esForm) os_enableSuggestionsOn('es_text', 'es_form') os_createContainer(os_map['es_text']) esForm.style.display = 'none' //so it's not hidden by ev_onfocusTextarea return function appendInput(type, id, css){ var inp = document.createElement('input') inp.type = type if (id) inp.id = inp.name = id  if (css) inp.style.cssText = css esForm.appendChild(inp) return inp } }

// *** METHODS ***

function showForm(isOn){ isOn = isOn==true esText.disabled = !isOn esForm.style.display = isOn ? '' : 'none' var el = document.getElementById('es_textSuggest') if (el) el.style.display = isOn ? '' : 'none' //"hidden" is not enouugh here: text cursor disappears under it in Firefox if (isOn){ esText.focus esText.select fetchResults setTimeout(setTextareaFocusHandler, 20) //if we set it now, weird IE6 will execute it }else{ delHandler(txtBox, 'focus', ev_onfocusTextarea) } }

function setTextareaFocusHandler{ addHandler(txtBox, 'focus', ev_onfocusTextarea) }

function getWikiText{ //returns target to search, remembers link name linkName = selGet var targ, ma if (ma=linkName.match(/ *\[\[([^\]\|]+)\|?([^\]]+)?\]\] */)){ //user selected existing wikilink targ = ma[1]; linkName = ma[2] || '' }else targ = linkName return targ.replace(/́/g,).replace(/ +$/, ) //remove accent and spaces at the end }

function fetchResults{ var r = os_map['es_text'] //r.query = '---' //null old query so the results are always shown r.original = '' //injectSpinner(esText, 'es') os_fetchResults(r, esText.value, 0) }

function setWikiText(targ, name){ //remove space at the end var isSpace = / +$/.test(name) if (isSpace) name = name.replace(/ +$/, '') var txt if (getNS == 10){ //template txt = '{\{' + targ.substring(targ.indexOf(':')) + '|' + name + '}}' }else{ //construct wiki link txt = '[\[' if (normalize(name).indexOf(normalize(targ)) == 0) //target is substring txt += name.substring(0, targ.length) + ']]' + name.substring(targ.length) else //target is different txt += targ + '|' + name + ']]' } //insert link if (isSpace) txt += ' ' selSet(txt, true) }

function focusSuggest{esText.focus} function focusTextarea{txtBox.focus; selSelect}

function setNS(ns){ esNS.name = 'ns' + ns if (typeof es_namespaces_names[ns] != 'undefined') ns = es_namespaces_names[ns] document.getElementById('es_label').innerHTML = ns }

function getNS{ var ns = esNS.name return ns = ns ? ns.substring(2) : 0 }

function cycleNS{ var ns = getNS for (var i=0; i= es_namespaces.length) i = 0 //get next in the list setNS(es_namespaces[i]) //set new namespace }

// *** EVENTS ***

function ev_onkeydown(e){ e = e || window.event var key = (window.Event) ? e.which : e.keyCode switch (key){ //Ctrl or Shift case 16: case 17: isCtrlOrShift = true; break //Escape case 27: //if (keyPrev==27 || !esText.value) setTimeout(focusTextarea, 50) //else setTimeout(focusSuggest, 50) // bring cursor back after Escape, mwsuggest Opera issue break } keyPrev = key //if (key == 9) focusTextarea //Tab }

function ev_onfocusTextarea{ if (esForm && (esForm.style.display != 'none')) setTimeout(showForm, 20) }

function ev_onkeyup(e){ e = e || window.event var key = (window.Event) ? e.which : e.keyCode switch (key){ /*Ctrl or Shift*/ case 16: case 17: isCtrlOrShift = false; break // /*Escape*/ case 27:   //e.cancelBubble = true;  if (e.stopPropagation) e.stopPropagation   //break /*Space*/ case 32: if (!esText.value.replace(/ /g,)){ cycleNS; esText.value = }; break /*PgDnl*/ case 34: /*ScrollLock*/ case 145: cycleNS; fetchResults; break } }

function ev_onsubmit(e){ if (isCtrlOrShift){ window.open (mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace('\$1', esText.value)) }else{ setWikiText(esText.value, linkName) showForm(false) setTimeout(focusTextarea, 100) } return }

// *** misc ***

function normalize(tt){ return (tt.substring(0,1).toUpperCase + tt.substring(1)).replace(/_/g, ' ') }

function delHandler(element, event, handler){ if (window.removeEventListener) element.removeEventListener(event, handler, false) else if (window.detachEvent) element.detachEvent('on' + event, handler) }

//cross-browser textarea selection, need txtBox var

function selGet{ if (document.selection) { //IE/Opera selScroll = document.documentElement.scrollTop txtBox.focus selRange = document.selection.createRange return selRange.text }else if (txtBox.selectionStart || txtBox.selectionStart == '0') { // Mozilla selScroll = txtBox.scrollTop //this.selStart = txtBox.selectionStart //txtBox.focus return txtBox.value.substring(txtBox.selectionStart, txtBox.selectionEnd) }else return null }

function selSelect{ if(selRange) selRange.select } //for IE only

function selSet(txt, isSelect){ txtBox.focus if (document.selection) { //IE/Opera selRange.text = txt selRange.select //no need to restore scroll if the action is not instant //document.documentElement.scrollTop = this.selScroll //restore window scroll position }else if (txtBox.selectionStart || txtBox.selectionStart == '0') { // Mozilla var p1 = txtBox.selectionStart, p2 = txtBox.selectionEnd txtBox.value = txtBox.value.substring(0, p1) + txt + txtBox.value.substring(p2, txtBox.value.length) txtBox.selectionStart = p1 + txt.length //restore cursor position at end txtBox.selectionEnd = txtBox.selectionStart txtarea.scrollTop = selScroll //restore txtarea scroll } if (isSelect) selMove (-txt.length) }

function selMove(mv1, mv2){ if (document.selection) { //IE/Opera if (!selRange.moveStart) return if (mv1) selRange.moveStart('character', mv1) if (mv2) selRange.moveEnd ('character', mv2) }else if (txtBox.selectionStart || txtBox.selectionStart == '0') { // Mozilla if (mv1) txtBox.selectionStart += mv1 if (mv2) txtBox.selectionEnd  += mv2 } } }

if (window.wgMWSuggestTemplate && (wgAction=='edit' || wgAction=='submit')) addOnloadHook(editSuggestButton)

function editSuggestButton{ var tlb = document.getElementById('toolbar') if (!tlb) return var btn = document.createElement('input'); btn.type = 'button' btn.style.cssText = 'background:#adbede; height:22px; vertical-align:middle; padding:0' btn.value = '[\[↓]]'; btn.title = 'Suggest link' btn.onclick = editSuggest.start; btn.id = 'editSuggest' tlb.appendChild(btn) if (window.es_accesskey){ btn.accessKey = es_accesskey btn.title += ' ['+es_accesskey+']' updateTooltipAccessKeys([btn]) } }