Diferencia entre revisiones de «MediaWiki:Gadget-dictionaryLookupHover.js»
Contenido eliminado Contenido añadido
Página nueva: →** This is the Stable version of the gadget js.**: /* Stolen from fr wikinews, and than subsequently heavily modified by Bawolff. This script is based on the french one created by... |
(Sin diferencias)
|
Revisión del 12:56 8 nov 2009
/*** This is the Stable version of the gadget js.***/
/*
Stolen from fr wikinews, and than subsequently heavily modified by Bawolff. This script is based on the french one created by [[en:wiktionary:User:Bequw]] and [[en:wiktionary:User:Conrad.Irwin]].
The current version of this is maintained by Bawolff. please don't hesitate to contact me (bawolff) if you have any issues, comments, bugs, need help, or whatever.
*/
/*global wgUserLanguage, wgContentLanguage, window, hookEvent, addOnloadHook, XSLTProcessor*/
/*jslint browser: true, undef: true, nomen: true, eqeqeq: true, bitwise: true, newcap: true, immed: true, maxerr: 80 */
/*members TEXT_NODE, addEventListener, appendChild, attachEvent, body,
border, charAt, clientWidth, clientX, clientY, cloneContents,
cloneRange, collapse, createElement, createRange, data, detach, display,
documentElement, en, endContainer, endOffset, event, expand, findWord,
firstChild, focus, fr, fra, frc, fre, getElementById, getInnerWidth,
getRangeAt, getScrollX, getScrollY, getSelection, height, id,
innerWidth, left, length, lookupWord, match, nl, nodeType, ondblclick,
open, pageXOffset, pageYOffset, position, preferLang, preventDefault,
rangeOffset, rangeParent, rangeToWord, readyState, replace, returnValue,
scrollLeft, scrollTop, selection, setEnd, setStart, setup, shiftKey,
split, src, startContainer, startOffset, stopPropagation,
stripAfterDash, style, substring, text, toString, top, useNewWindow,
validLangs, wgUserLanguage, width, wiktDomain, wiktLookup, zIndex
*/
//set wiktLookup.useNewWindow to true to force new window.
if (!window.wiktLookup) var wiktLookup = {};
/*
Options:
count
showWord
*/
wiktLookup.validLangs = {en: "en", fr: "fr", frc: "fr", fra: "fr", fre: "fr", nl: "nl"};
wiktLookup.wiktDomain = 'en'; //default
wiktLookup.stripAfterDash = /-.*$/;
if (wiktLookup.validLangs[wgUserLanguage]) {
wiktLookup.wiktDomain = wiktLookup.validLangs[wgUserLanguage];
} else if (wiktLookup.validLangs[wgUserLanguage.replace(wiktLookup.stripAfterDash)]) {
wiktLookup.wiktDomain = wiktLookup.validLangs[wgUserLanguage.replace(wiktLookup.stripAfterDash)];
} else if (wiktLookup.validLangs[wgContentLanguage]) {
wiktLookup.wiktDomain = wiktLookup.validLangs[wgContentLanguage];
} else if (wiktLookup.validLangs[wgContentLanguage.replace(wiktLookup.stripAfterDash)]) {
wiktLookup.wiktDomain = wiktLookup.validLangs[wgContentLanguage.replace(wiktLookup.stripAfterDash)];
}
if (!wiktLookup.preferLang) wiktLookup.preferLang = (window.wgUserLanguage ? wgUserLanguage : wiktLookup.wiktDomain );
wiktLookup.getOptions = function () {
var opt = '';
if (wiktLookup.count)
opt += '&count=' + wiktLookup.count;
if (wiktLookup.showWord)
opt += '&showWord=' + wiktLookup.showWord;
if (wiktLookup.noRedir)
opt += '&rd=500';
return opt;
}
wiktLookup.rangeToWord = function (selection) {
//includes apostraphes
//fixme: if at begin of container.
var finalText = selection.toString();
try {
var expandWord = /['\-]/ //list of chars that are not actual word boundries.
var range = selection.getRangeAt(0);
var rangeBefore = range.cloneRange();
if (rangeBefore.startOffset !== 0 ) {
rangeBefore.setStart(rangeBefore.startContainer, rangeBefore.startOffset - 1);
var textNode = rangeBefore.cloneContents().firstChild;
if (textNode.nodeType === 3 && expandWord.test(textNode.data.charAt(0))) {
for (var i = 0; i < 30 /*to stop run-away*/; i++) {
rangeBefore.setStart(rangeBefore.startContainer, rangeBefore.startOffset - 1);
textNode = rangeBefore.cloneContents().firstChild;
if ((textNode.nodeType !== 3) || (textNode.nodeType === 3 && textNode.data.match(/^\s/))) {
rangeBefore.setStart(rangeBefore.startContainer, rangeBefore.startOffset + 1);
finalText = rangeBefore.toString();
rangeBefore.detach();
range.detach();
return finalText;
}
else if (rangeBefore.startOffset === 0) { //at the end of the range. this might add periods, which are stripped later.
finalText = rangeBefore.toString();
rangeBefore.detach();
range.detach();
return finalText;
}
}
}
}
rangeBefore.detach(); //done with it.
var rangeAfter = range.cloneRange();
rangeAfter.setEnd(rangeAfter.endContainer, rangeAfter.endOffset + 1);
var textNode = rangeAfter.cloneContents().firstChild; //double var...
if (textNode.nodeType === 3 && expandWord.test(textNode.data.charAt(textNode.data.length - 1))) {
for (var i = 0; i < 30 /*to stop run-away*/; i++) {
rangeAfter.setEnd(rangeAfter.endContainer, rangeAfter.endOffset + 1);
textNode = rangeAfter.cloneContents().firstChild;
if ((textNode.nodeType !== 3) || (textNode.nodeType === 3 && textNode.data.match(/\s$/))) {
rangeAfter.setEnd(rangeAfter.endContainer, rangeAfter.endOffset - 1);
finalText = rangeAfter.toString();
rangeAfter.detach();
range.detach();
return finalText;
} else if (rangeAfter.endOffset - rangeAfter.endContainer.data.length === 0) { // this assumes this is a text node... this might add periods, which are stripped later.
finalText = rangeAfter.toString();
rangeAfter.detach();
range.detach();
return finalText;
}
}
}
rangeAfter.detach(); //no match, and done with this range.
} catch (e) {
if (window.range) {range.detach();}
return finalText;
}
return finalText;
}
wiktLookup.findWord = function (e) {
if (!e) {e = window.event;}
if (e.shiftKey) {
return true; //don't do anything if shift is pressed down. for compat with other things.
}
// stolen from http://www.codetoad.com/javascript_get_selected_text.asp
var text;
if (window.getSelection) {
text = wiktLookup.rangeToWord(window.getSelection());
}
else if (document.getSelection) {
text = wiktLookup.rangeToWord(document.getSelection());
}
if (text && text.length < 32) {
//If we have the text. we be done.
return wiktLookup.lookupWord(text, e.clientX, e.clientY);
}
// seems to work somewhat on moz. Hopefully moz will be picked up above. So this shouldn't be neccesary.
if (e.rangeParent && e.rangeParent.nodeType === document.TEXT_NODE) {
//mozilla part
var rangeOffset = e.rangeOffset;
var my_rangestr = e.rangeParent.data; //the event is dynamic!
// which word the rangeOffset is in
var wordlist1 = my_rangestr.substring(0, rangeOffset).split(/\s+/);
var wordlist2 = my_rangestr.substring(rangeOffset, my_rangestr.length).split(/\s+/);
if (my_rangestr.length > 0) {
wiktLookup.lookupWord(wordlist1[wordlist1.length - 1]+wordlist2[0], e.clientX, e.clientY);
}
e.preventDefault();
e.stopPropagation();
}
//IE specific stuff. Try this as a last resort.
else {
try {
if (document.readyState !== "complete") return false;
//IE
var my_range = document.selection.createRange();
my_range.collapse();
my_range.expand("word");
wiktLookup.lookupWord(my_range.text);
e.returnValue = false;
return false;
} catch (err) { /*ignore*/
}
}
}
wiktLookup.getScrollX = function () {
//standard
if (window.pageXOffset !== undefined) { return window.pageXOffset; }
//IE 6 in standards mode
if (document.documentElement && document.documentElement.scrollLeft !== undefined) { return document.documentElement.scrollLeft; }
//other IE
if (document.body && document.body.scrollLeft !== undefined) { return document.body.scrollLeft; }
return 0; //default
}
wiktLookup.getScrollY = function() {
//standard
if (window.pageYOffset !== undefined) { return window.pageYOffset; }
//IE 6 in standards mode
if (document.documentElement && document.documentElement.scrollTop !== undefined) { return document.documentElement.scrollTop; }
//other IE
if (document.body && document.body.scrollTop !== undefined) { return document.body.scrollTop; }
return 0;
}
wiktLookup.getInnerWidth = function() {
//standard
if (window.innerWidth !== undefined) { return window.innerWidth; }
//IE 6 in standards mode
if (document.documentElement && document.documentElement.clientWidth !== undefined) { return document.documentElement.clientWidth; }
//other IE
if (document.body && document.body.clientWidth !== undefined) { return document.body.clientWidth; }
return 0;
}
wiktLookup.lookupWord = function(word, x, y) {
if (!word.match(/(?:^[àâçéèêëîïôûùüÿÀÂÇÉÈÊËÎÏÔÛÙÜŸ]|[àâçéèêëîïôûùüÿÀÂÇÉÈÊËÎÏÔÛÙÜŸ]$)/)) {
//this regex doesn't work if word starts or ends with accents.
//is this regex even needed?
var word2 = word.match(/\b(?:[\S]|(?!\.\s)\.)*\b/); //strip quotation marks
}
var s = word2 ? word2[0] : word //if regex failed, fall back to word
if (!s) {return false;} // test if null or empty.
s = encodeURIComponent(s);
if (!window.XSLTProcessor || wiktLookup.useNewWindow) {
//This includes IE, which doesn't recognize the mime type mediawiki uses.
// in future this could put the window where user clicked.
var newwin = window.open('http://' + wiktLookup.wiktDomain + '.wiktionary.org/wiki/' + s + '?uselang=' + wiktLookup.preferLang,'temp','height=450,width=800,location,menubar,toolbar,status,resizable,scrollbars');
if (newwin) {
newwin.focus();
}
return true;
}
var frame = document.getElementById('dict-popup-frame');
frame.style.display = 'block';
frame.src = 'http://' + wiktLookup.wiktDomain + '.wiktionary.org/w/api.php?action=parse&redirects&prop=text&format=xml&xslt=MediaWiki:extractFirst.xsl&page=' + s + '&lang=' + wiktLookup.preferLang + wiktLookup.getOptions();
var left = x + wiktLookup.getScrollX();
if (left + 420 > wiktLookup.getInnerWidth() && left - 420 > 0) {
left -= 420;
}
frame.style.top = (y + wiktLookup.getScrollY() + 10) +'px';
frame.style.left= left +'px';
}
wiktLookup.setup = function () {
if (document.addEventListener) {
document.addEventListener("dblclick", wiktLookup.findWord, true); //capture
} else if (document.attachEvent) {
document.attachEvent("ondblclick", wiktLookup.findWord);
}
else {
document.ondblclick = wiktLookup.findWord;
}
}
addOnloadHook(wiktLookup.setup);
addOnloadHook(function () {
var frame = document.createElement('iframe');
frame.style.border = 'none';
frame.style.position = 'absolute';
frame.style.display = 'none';
frame.style.zIndex = '102';
frame.style.width = '420px'; //default 300
frame.style.height = '180px'; //default 150
frame.id = 'dict-popup-frame';
document.body.appendChild(frame);
});
hookEvent('click', function() {
try {
document.getElementById('dict-popup-frame').href = 'about:blank'; //transparent. at least on firefox.
document.getElementById('dict-popup-frame').style.display = 'none';
} catch(e) {/*ignore*/ }
});