Участник:Js/selection.js

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
/* Script that shows popup menu on text selection:
1) in view mode on articles: external search sites
2) in edit mode: jump to "this place" in edit window
This is BETA version.

 Optional parameters: */
//selNoSearch = true  //disable search (leaves only "jump to edit window functionality"
//selSearchOnEdit = true //enable search also in editing mode
//selNoJump = true // disable ""jump to edit window" (leaving only search
selOpenInBg = true //try to open sites in background windows (works only in Opera)
selOpenInFrame = true //open sites in the bottom iframe (disabled for Yandex since it breaks out of frame)



var searchSelSites = {
'MediaWiki':mw.config.get('wgServer')+mw.config.get('wgScript')+'?title=Special:Search&ns0=1&useskin=chick&search=',
'Yandex':'http://www.yandex.ru/yandsearch?text="$1"',
'Google':'http://www.google.com/search?q="$1"'
}

$(searchSelected)


var selText, popup, savedSel, txtarea, content, isSearch, isJump, jumpPos, jumpPosNext, jumpNextBtn


function searchSelected(){

if (mw.config.get('wgAction')=='view' /*&& wgNamespaceNumber==0 */ && !window.selNoSearch){ //viewing
  content = document.getElementById('content') || document.getElementById('mw_content')
  isSearch = true
}else if ((mw.config.get('wgAction')=='edit' || mw.config.get('wgAction')=='submit') && mw.config.get('wgNamespaceNumber')>=0){ //editing
  content = document.getElementById('wikiPreview')
  if (!window.selNoJump) txtarea = document.getElementById('wpTextbox1')
  if (window.selSearchOnEdit) isSearch = true
}
 
if ((isSearch) || txtarea) addHandler(content, 'mouseup', onMouseUp)
//  && wgNamespaceNumber==0  // !!!

function onMouseUp(e){ //mouseup fires when user just finished selection
 hidePopup()
 e = e || window.event
 if (e.shiftKey || e.button == 2) return // shift key or right click
 selText = getSelectedText().replace(/^ +/, '').replace(/ +$/, '') //trim spaces
 if (!selText || selText.length < 2) return
 savedSel = null
 isJump = txtarea && (jumpPos=findInTextarea(selText)) != -1
 if (isJump || isSearch) showPopup(e)
}

/*
function clickPopup(e){
 e = e || window.event
 var li = e.target || e.srcElement
 log(li, ':', li.engine)
 if (li.engine){
   restoreSelection(savedSel)
   jsMsg(li.engine)
 }else{
   hidePopup()
   clickJump()
 }
}
*/

function clickSearch(e){
 e = e || window.event
 var li = e.target || e.srcElement
 restoreSelection(savedSel)
 var url = li.engine
 if (url.indexOf('$1') != -1) url = url.replace('$1', encodeURIComponent(selText))
 else url += encodeURIComponent(selText)
 if (window.selOpenInFrame && !/yandex\.ru/.test(url)) openFrame(url)
 else{
   window.open(url)
   if (window.selOpenInBg) self.focus()
 }
}


function clickJump(){
 hidePopup()
 jumpPosNext = jumpPos + selText.length
 if (!jumpNextBtn) 
   jumpNextBtn = addToolbarButton(' ↓ ', clickJumpNext, '', 'Find this again: '+selText) 
 setSelectedText(txtarea, jumpPos, jumpPosNext)
 //help user find selected text
 if (txtarea.setSelectionRange){ //in Mozilla/Opera
   txtarea.focus()
   txtarea.scrollTop = txtarea.scrollHeight * jumpPos / txtarea.value.length - 50
   //try to scroll the window to textarea better 
   if (window.pageYOffset + window.innerHeight < txtarea.offsetHeight + 200) 
     window.scrollTo(0,txtarea.offsetHeight - 100)	 
 }
}

function clickJumpNext(){
 jumpPos = findInTextarea(selText, jumpPosNext)
 if (jumpPos == -1) jumpPos = findInTextarea(selText) //jump from start
 clickJump()
 //jumpNextBtn.parentNode.removeChild(jumpNextBtn)
}

function findInTextarea(word, from){
 return txtarea.value.replace(/\r/g,'').indexOf(word, from) //IE has additional \r which have to be removed
}


function showPopup(e){
 savedSel = rememberSelection()
 if (!popup) createPopup()
 popup.style.left = getMouseX(e) + 5 + 'px'
 popup.style.top = getMouseY(e) + 10 + 'px'
 popup.style.display = 'block'
}

function hidePopup(){
 if (!popup) return
 popup.style.display = 'none'
 popup = null
}

function createPopup(){
 //create div
 popup = document.createElement('ul')
 popup.className = 'popup'
 popup.style.cssText = 'position:absolute; z-index:50;\
  border:1px outset gray; background-color:#EEEEEE; padding:0; margin-left:0.2em;\
  list-style-type:none; list-style-image:none'
 var li, count = 0
 if (isJump) 
   addMenuElem('&nbsp;↓&nbsp;', clickJump, 'Jump to this selection in textarea').style.textAlign = 'center'
 if (isSearch)
  for (var i in searchSelSites )
    addMenuElem(i, clickSearch).engine = searchSelSites[i]
 document.body.appendChild(popup)
 //aux func
 function addMenuElem(name, func, tooltip){
   li = document.createElement('li')
   //var dd = document.createElement('div')
   //li.appendChild(dd)
   li.style.cssText = 'cursor:pointer; padding:2px'
   if (isSearch) li.style.width = '60px'
   if (count++ != 0) li.style.borderTop = '1px solid gray'
   li.innerHTML = name
   li.title = tooltip || ''
   li.onclick = func
   popup.appendChild(li)
   return li
 }
}


function openFrame(url){
 var newEl = document.createElement('div')
 newEl.oldScroll = windowScrolled()
 newEl.innerHTML = decodeURI(url)
 newEl.style.cssText = 'background:#F0F0F0; border: 2px outset gray; margin-top:20px; padding:5px' 
 newEl.onclick = closeFrame 
 document.body.appendChild(newEl)
 newEl = document.createElement('iframe')
 newEl.style.cssText = 'width:99%; height:'  
  + (window.selFrameHeight || '600px')
 document.body.appendChild(newEl)
 newEl.src= url
 window.scrollTo(0,newEl.offsetHeight + 100) 
}

function closeFrame(e){
 e = e || window.event
 var el = e.target || e.srcElement 
 zz1 = el
 window.scrollTo(0, el.oldScroll)
 restoreSelection(savedSel)
 document.body.removeChild(el.nextSibling)
 document.body.removeChild(el)
}


function addToolbarButton(name, onclick, id, tooltip, accesskey){
 var toolbar = document.getElementById('toolbar')
 if (!toolbar) return
 var newBtn = document.createElement('input')
 newBtn.type = 'button'
 newBtn.style.cssText = 'background:#adbede; height:22px; vertical-align:middle'
 newBtn.value = name || '*'
 if (onclick) newBtn.onclick = onclick
 if (id) newBtn.id = id
 if (tooltip) newBtn.title = tooltip
 if (accesskey) newBtn.accessKey = accesskey
 toolbar.appendChild(newBtn)
 return newBtn
}
//function addToolbarButton(btn){
 

//Common methods

function getSelectedText(){ // returns selected text
 if (window.getSelection) return window.getSelection().toString()
 else if (document.selection) return document.selection.createRange().text
 else return ''
} //note: Netscape 4 uses document.getSelection but it's too old to support

function setSelectedText(obj, i1, i2){
 if (obj.setSelectionRange) { //Mozilla/Opera
   obj.focus()
   obj.setSelectionRange(i1, i2)
 }else if (obj.createTextRange){ //IE
   var r = obj.createTextRange()
   r.collapse()
   r.moveEnd('character', i2)
   r.moveStart('character', i1)
   r.select()
 }
}

function rememberSelection(){ // returns currently selected range
 if (window.getSelection)  return window.getSelection().getRangeAt(0)
 else if (document.selection) return document.selection.createRange()
 else return null
}

function restoreSelection(r){
 if (!r) return
 if (window.getSelection) window.getSelection().addRange(r)
 else if (document.selection) r.select()
}

function windowScrolled(){
if (self.pageYOffset) // all except Explorer
 return self.pageYOffset
else if (document.documentElement && document.documentElement.scrollTop)	// Explorer 6 Strict
 return document.documentElement.scrollTop
else if (document.body) // all other Explorers
 return document.body.scrollTop
}

function getMouseX(e){
 if (e.pageX) return e.pageX
 else if (e.clientX) return  e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft
 else return ''
}

function getMouseY(e){
 if (e.pageY) return e.pageY
 else if (e.clientY) return  e.clientY + document.body.scrollTop + document.documentElement.scrollTop
 else return ''
}


}