Участник: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(' ↓ ', 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 ''
}
}