ميدياويكي: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);
}