ميدياويكي:Gadget-dictionaryLookupHover.js

من كوبتيكبيديا
اذهب إلى التنقل اذهب إلى البحث

ملاحظة: بعد النشر، أنت قد تحتاج إلى إفراغ الكاش الخاص بمتصفحك لرؤية التغييرات.

  • فايرفوكس / سافاري: أمسك Shift أثناء ضغط Reload، أو اضغط على إما Ctrl-F5 أو Ctrl-R (⌘-R على ماك)
  • جوجل كروم: اضغط Ctrl-Shift-R (⌘-Shift-R على ماك)
  • إنترنت إكسبلورر/إيدج: أمسك Ctrl أثناء ضغط Refresh، أو اضغط Ctrl-F5
  • أوبرا: اضغط Ctrl-F5.
/* mw.loader.load('//en.wikinews.org/w/index.php?title=MediaWiki:Gadget-dictionaryLookupHover.js&action=raw&ctype=text/javascript'); */

if (!window.disableWiktLookup) {
//set wiktLookup.useNewWindow to true to force new window.
if (!window.wiktLookup) var wiktLookup = {};
wiktLookup.key = wiktLookup.key ? wiktLookup.key : 'l';

wiktLookup.validLangs = {ar: "ar", en: "en", fr: "fr", nl: "nl", es: 'es', it: 'it', ja: 'ja', pt: 'pt', ru: 'ru'};
wiktLookup.wiktDomain = 'ar'; //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[mw.config.get('wgContentLanguage')]) {
  wiktLookup.wiktDomain = wiktLookup.validLangs[mw.config.get('wgContentLanguage')];
} else if (wiktLookup.validLangs[mw.config.get('wgContentLanguage').replace(wiktLookup.stripAfterDash)]) {
  wiktLookup.wiktDomain = wiktLookup.validLangs[mw.config.get('wgContentLanguage').replace(wiktLookup.stripAfterDash)];
}

if (!wiktLookup.preferLang) wiktLookup.preferLang = (window.wgContentLanguage ? mw.config.get('wgContentLanguage') : wiktLookup.wiktDomain );

if (wiktLookup.disableByDefault === undefined) wiktLookup.disableByDefault = false;

wiktLookup.getOptions = function () {
 var opt = '';
 if (wiktLookup.count)
  opt += '&count=' + wiktLookup.count;
 if (wiktLookup.showWord)
  opt += '&showWord=' + wiktLookup.showWord;
 if (wiktLookup.audio)
  opt += '&audio=' + wiktLookup.audio;
 if (wiktLookup.noRedir)
  opt += '&rd=500';
 if (wiktLookup.exit)
  opt += '&exit=true';

 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 && e.type === 'dblclick' && !wiktLookup.reverseShift) {
    return true; //don't do anything if shift is pressed down. for compat with other things.
  }
  if (!e.shiftKey && e.type === 'dblclick' && wiktLookup.reverseShift) {
    return true; //if reverse shift is on, require shift key for double click.
  }
  var clientX, clientY, coordsAbs, langOverride;
  if (e.clientX) {//this implies has Y as well
   clientX = e.clientX;
   clientY = e.clientY;
  }
  // stolen from http://www.codetoad.com/javascript_get_selected_text.asp
  var text;
  if (window.getSelection) {
    text = wiktLookup.rangeToWord(window.getSelection());
    if (!clientX) {
     try {
       //mostly for from keyboard requests
       var parent = window.getSelection().anchorNode.parentNode;
       clientX = parent.offsetLeft + 7*window.getSelection().anchorOffset; //this is very rough
       clientY = parent.offsetTop + parent.offsetHeight; //at bottom of elm 
       coordsAbs = true;
       parent = parent.offsetParent;
       while ( parent ) {
         clientX += parent.offsetLeft;
         clientY += parent.offsetTop;
         parent = parent.offsetParent;
       }
     } catch (e) {}
    }
    try { //figure out what language the current node is.
          //and determine if we're in an enabled section
          // aka <span class="wiktLookup-enable">blah</span>
          //wiktLookup.disableByDefault
      var enabled = !wiktLookup.disableByDefault;
      var foundAnEnableSection = false;
      var foundLangSection = false;
      var cur = window.getSelection().anchorNode.parentNode;
      for (var i = 0; i < 9; i++) {
        if (!foundAnEnableSection && cur.className.indexOf('wiktLookup-disable') !== -1) {
          return; //die
        }
        if (!foundAnEnableSection && cur.className.indexOf('wiktLookup-enable') !== -1) {
          enabled = true;
          foundAnEnableSection = true;
          if (foundLangSection) break;
        }
        if (!foundLangSection && cur.lang) {
          langOverride = cur.lang.replace(wiktLookup.stripAfterDash);
          if (foundAnEnableSection) break;
        } else {
          if (cur.parentNode) {cur = cur.parentNode;}
          else {break;}
        }
      }
      if (!enabled) {
        return; //die
      }
    }
    catch (e) { 
      /*ignore error*/
      if (!enabled) {
        return; //die
      } 
    }
  }
  else if (document.getSelection) {
    text = wiktLookup.rangeToWord(document.getSelection());
  }

  if (!clientX) {
   clientX = 400;
   clientY = 200;
   //good as numbers as any...
  }

  if (text && text.length < 32) {
  //If we have the text. we be done.
    return wiktLookup.lookupWord(text, clientX, clientY, coordsAbs, langOverride);
  }

  // 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], clientX, clientY, coordsAbs, langOverride);
    }
    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, clientX, clientY, coordsAbs, langOverride);;
 
      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, absCoords,langOveride) {
  if (!word.match(/(?:^[\wa-zA-Zа-яА-Яà-žÀ-ŽΑ-ῥԱ-ևぁ-ヶ促-杁ㄱ-하ⁿßſ]|[\wa-zA-Zа-яА-Яà-žÀ-ŽΑ-ῥԱ-ևぁ-ヶ促-杁ㄱ-하ⁿßſ]\s?$)/)) {
    //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 (!wiktLookup.supported()) {
      //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.src = 'about:blank'; //don't display old results.
    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=' + (langOveride ? langOveride : wiktLookup.preferLang) + wiktLookup.getOptions();
    var left, top;
    if (!absCoords) {
      var left = x + wiktLookup.getScrollX();
      if (left + (wiktLookup.width ? wiktLookup.width  : 420) > wiktLookup.getInnerWidth() && left - (wiktLookup.width ? wiktLookup.width  : 420) > 0) {
        left -=  (wiktLookup.width ? wiktLookup.width  : 420);
      }
      top = (y + wiktLookup.getScrollY() + 10);
    }
    else {
      top = y + 10;
      left = (x + (wiktLookup.width ? wiktLookup.width  : 420) > wiktLookup.getInnerWidth() ? wiktLookup.getInnerWidth() -  (wiktLookup.width ? wiktLookup.width  : 420) : x );
    }
    frame.style.top = top +'px';
    frame.style.left= left +'px';
    document.getElementById('dict-popup-container').style.display = 'block';
}

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;
  }


window.addEventListener('keypress', function(event) { 
  if (!event) event = window.event;
  if (!(event.ctrlKey && event.shiftKey)) return true;
  var key = (event.charCode ? event.charCode : event.keyCode);

  if (key && (String.fromCharCode(key) === wiktLookup.key || String.fromCharCode(key) === wiktLookup.key.toUpperCase())) {
    wiktLookup.findWord(event);
 
    if (event.preventDefault) event.preventDefault(); 
    return false;
  }
  return true;
});
}
wiktLookup.supported = function () {
 if (navigator && navigator.userAgent && navigator.userAgent.indexOf('Gecko') !== -1 && navigator.productSub  && navigator.productSub <= 20090823 && navigator.productSub > 2000000) {
  //old moz has broken support for html entities.
  //FIXME: figure out exact date when gecko was fixed.
  return false;
 }

 if (wiktLookup.useNewWindow) return false;
 if (window.XSLTProcessor || document.selectNodes ) return true; //note: second part for IE
 
 return false;
}

$(wiktLookup.setup);

$(function () {
  if (!wiktLookup.definitionBegin) wiktLookup.definitionBegin = 'Definition (';
  if (!wiktLookup.definitionEnd) wiktLookup.definitionEnd = '):';
  if (!wiktLookup.hideText) wiktLookup.hideText = 'hide';

  var div = document.createElement('div');
  div.id = 'dict-popup-container';
  var frame = document.createElement('iframe');
  frame.style.border = 'none';
  if (wiktLookup.mode !== 'bottom') frame.style.position = 'absolute';
  frame.style.display = 'none';
  frame.style.zIndex = '102';
  if (wiktLookup.mode === 'bottom') {
    frame.style.width = '98%';
  }
  else {
    frame.style.width = (wiktLookup.width ? wiktLookup.width + 'px' : '420px'); //default 300 if unset
  }
  frame.style.height = (wiktLookup.height ? wiktLookup.height + 'px' : '180px'); //default 150 if unset.
  frame.id = 'dict-popup-frame';
  frame.src = 'about:blank';

  if (wiktLookup.mode === 'bottom') {
    div.style.padding = '0.3em';
    div.style.display = 'none';
    div.style.position = 'fixed';
    div.style.margin = '0';
    div.style.bottom = '0';
    div.style.zIndex = '50';
    div.style.background = 'url(//upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Wiktionary-logo.svg/840px-Wiktionary-logo.svg.png) white no-repeat 30%';
    div.style.borderTop = 'solid thin black';
    div.style.width = '100%';

    div.appendChild(document.createTextNode(wiktLookup.definitionBegin));
    var link = document.createElement('a');
    link.href = '#';
    link.onclick = wiktLookup.hide;
    link.appendChild(document.createTextNode(wiktLookup.hideText));
    div.appendChild(link);
    div.appendChild(document.createTextNode(wiktLookup.definitionEnd));
  }
  div.appendChild(frame);
  document.body.appendChild(div);

});

wiktLookup.hide = function() {
  try {
    var frame = document.getElementById('dict-popup-frame');
    if (frame.src !== 'javascript:%22%20%22') frame.src = 'javascript:%22%20%22'; //transparent
    //not using about:blank due to bug with font re-sizing on firefox.
    frame.style.display = 'none';
    document.getElementById('dict-popup-container').style.display = 'none';
  } catch(e) {/*ignore*/ }
}
window.addEventListener('click', wiktLookup.hide);
}