home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / AIMP2 / aimp_2.61.583.exe / $TEMP / YandexPackSetup.msi / fil3B505E1A6DD1B3D1298587D22DA6EEBD < prev    next >
Text File  |  2010-07-12  |  15KB  |  555 lines

  1. if (!Ya.YaTranslate) {
  2.  
  3. Ya.YaTranslate = {
  4.   get tooltip() {
  5.     if (!this._tooltip) {
  6.       let tooltip;
  7.       let appInfo = Ya.nsIYa.AppInfo;
  8.       
  9.       if (appInfo.OS.isWindows) {
  10.         tooltip = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "panel");
  11.         tooltip.setAttribute("noautofocus", "true");
  12.         tooltip.setAttribute("norestorefocus", "false");
  13.         tooltip.setAttribute("level", "top");
  14.         
  15.         if (appInfo.browser.isGreaterThenFx30)
  16.           tooltip.setAttribute("yaShadow", "true");
  17.         
  18.       } else {
  19.         tooltip = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "tooltip");
  20.         tooltip.setAttribute("noautohide", "true");
  21.       }
  22.       
  23.       tooltip.setAttribute("yaIsLinux", appInfo.OS.isLinux);
  24.       
  25.       tooltip.style.MozBinding = "url('chrome://yasearch/content/translate/balloon.xbl#balloon')";
  26.       
  27.       document.getElementById("mainPopupSet").appendChild(tooltip);
  28.       
  29.       tooltip.tooltipController = this;
  30.       
  31.       this._tooltip = tooltip;
  32.     }
  33.     
  34.     return this._tooltip;
  35.   },
  36.   
  37.   get tooltipHTML() {
  38.     return this._tooltipHTML || (this._tooltipHTML = document.getElementById("aHTMLTooltip"));
  39.   },
  40.   
  41.   get contextMenu() {
  42.     return this._contextMenu || (this._contextMenu = document.getElementById("contentAreaContextMenu"));
  43.   },
  44.   
  45.   get locale() {
  46.     return this._locale || (this._locale = Ya.stringBundleSet.getString("locale.lang") || "ru");
  47.   },
  48.   
  49.   get content() {
  50.     return this._content || (this._content = document.getElementById("main-window"));
  51.   },
  52.   
  53.   get contentIsActive() {
  54.     return this.content.getAttribute("active") === "true";
  55.   },
  56.   
  57.   INTERVAL_MIN: 500,
  58.   INTERVAL_MAX: 10000,
  59.   
  60.   get intervalShow() {
  61.     return this._intervalShow || (this._intervalShow =
  62.                Math.min(Math.max(this.INTERVAL_MIN, this.Prefs.get(this.INTERVAL_SHOW_PREF, this.INTERVAL_MAX)), 10000));
  63.   },
  64.   
  65.   ENABLE_PREF: "general.ui.translate.enabled",
  66.   REVERSE_PREF: "general.ui.translate.reverse",
  67.   FROM_PREF: "general.ui.translate.from",
  68.   TO_PREF: "general.ui.translate.to",
  69.   INTERVAL_SHOW_PREF: "general.ui.translate.interval.show",
  70.   
  71.   showTimeout: null,
  72.   request: null,
  73.   balloon: null,
  74.   
  75.   _lastScrollEventTime: 0,
  76.   
  77.   _cache: {
  78.     MAX_CACHED_COUNT: 256,
  79.     
  80.     _cachedBallons: [],
  81.     
  82.     clear: function() {
  83.       this._cachedBallons = [];
  84.     },
  85.     
  86.     _balloonId: function(balloon) {
  87.       return [balloon.from, balloon.to, balloon.text.toLowerCase()].join("|");
  88.     },
  89.     
  90.     storeBalloon: function(balloon) {
  91.       let cached = {};
  92.       for (let name in {from: 0, to: 0, text: 0, url: 0, translations: 0})
  93.         cached[name] = balloon[name];
  94.       
  95.       cached.balloonId = this._balloonId(balloon);
  96.       
  97.       if (this._cachedBallons.unshift(cached) > this.MAX_CACHED_COUNT)
  98.         this._cachedBallons.splice(-this.MAX_CACHED_COUNT/2);
  99.     },
  100.     
  101.     restoreBalloon: function(balloon) {
  102.       let cached;
  103.       let balloonId = this._balloonId(balloon);
  104.       
  105.       this._cachedBallons.some(function(aBalloon) {
  106.         return (balloonId === aBalloon.balloonId) && (cached = aBalloon);
  107.       });
  108.       
  109.       if (cached)
  110.         for (let name in {url: 0, translations: 0})
  111.           balloon[name] = cached[name];
  112.       
  113.       return balloon;
  114.     }
  115.   },
  116.   
  117.   isPopupOpen: function(aPopupNode) {
  118.     return aPopupNode && (["open", "showing"].indexOf(aPopupNode.state) > -1);
  119.   },
  120.   
  121.   init: function() {
  122.     Components.utils.import("resource://yasearch/Preferences.jsm", this);
  123.     
  124.     this.onEnableChanged();
  125.     this.onReverseChanged();
  126.     this.onDirectionChanged();
  127.     this.Prefs.observe(this.ENABLE_PREF, this.onEnableChanged, this);
  128.     this.Prefs.observe(this.REVERSE_PREF, this.onReverseChanged, this);
  129.     this.Prefs.observe(this.FROM_PREF, this.onDirectionChanged, this);
  130.     this.Prefs.observe(this.TO_PREF, this.onDirectionChanged, this);
  131.     
  132.     YaProgressListener.addListener(this);
  133.   },
  134.   
  135.   destroy: function() {
  136.     this.clearShowTimeout();
  137.     
  138.     YaProgressListener.removeListener(this);
  139.     
  140.     this.Prefs.ignore(this.ENABLE_PREF, this.onEnableChanged, this);
  141.     this.Prefs.ignore(this.REVERSE_PREF, this.onReverseChanged, this);
  142.     this.Prefs.ignore(this.FROM_PREF, this.onDirectionChanged, this);
  143.     this.Prefs.ignore(this.TO_PREF, this.onDirectionChanged, this);
  144.     
  145.     if (this.request) {
  146.       this.request.abort();
  147.       this.request = null;
  148.     }
  149.     
  150.     this.hideBalloon();
  151.     
  152.     if (this._tooltip) {
  153.       this._tooltip.tooltipController = null;
  154.       this._tooltip = null;
  155.     }
  156.     
  157.     this._tooltipHTML = null;
  158.     this._contextMenu = null;
  159.     this._content = null;
  160.     
  161.     this._cache.clear();
  162.     
  163.     Ya.YaTranslate = null;
  164.   },
  165.   
  166.   _enable: false,
  167.   
  168.   set enable(value) {
  169.     this._enable = !!value;
  170.     this.enableShowEvents(value);
  171.   },
  172.   
  173.   get enable() {
  174.     return this._enable;
  175.   },
  176.   
  177.   _available: false,
  178.   
  179.   set available(value) {
  180.     this._available = !!value;
  181.     this.onEnableChanged();
  182.   },
  183.   
  184.   get available() {
  185.     return this._available;
  186.   },
  187.   
  188.   showEventsStatus: false,
  189.   
  190.   enableShowEvents: function(aEnabled) {
  191.     if (aEnabled == this.showEventsStatus)
  192.       return;
  193.     
  194.     this.showEventsStatus = aEnabled;
  195.     
  196.     let content = this.content;
  197.     let events = ["mousemove", "mouseout", "scroll"];
  198.     
  199.     for (let i = events.length; i--;) {
  200.       if (aEnabled)
  201.         content.addEventListener(events[i], this, false, true);
  202.       else
  203.         content.removeEventListener(events[i], this, false, true);
  204.     }
  205.   },
  206.   
  207.   isUserPage: function(event) {
  208.     try {
  209.       return !!(event.view && event.view.top === gBrowser.mCurrentBrowser.contentWindow);
  210.     } catch(e) {}
  211.     
  212.     return false;
  213.   },
  214.   
  215.   isCyrillic: function(aString) {
  216.     return !!(aString && /^[\u0400-\u04ff\-]+$/.test(aString));
  217.   },
  218.   
  219.   translateIt: function(balloon) {
  220.     if (
  221.         this.isPopupOpen(this.tooltip) &&
  222.         this.balloon &&
  223.         this.balloon.text == balloon.text &&
  224.         this.balloon.nodeRef === balloon.nodeRef &&
  225.         this.balloon.begin == balloon.begin
  226.         )
  227.       return true;
  228.     
  229.     var cyrillic = this.isCyrillic(balloon.text);
  230.     
  231.     var wrong = ((this.direction.from == "ru") != cyrillic);
  232.     if (wrong && !this.reverse)
  233.       return false;
  234.     
  235.     if (wrong) {
  236.       balloon.from = this.direction.to;
  237.       balloon.to = this.direction.from;
  238.     }
  239.     else {
  240.       balloon.from = this.direction.from;
  241.       balloon.to = this.direction.to;
  242.     }
  243.     
  244.     if (balloon.from == "ru" && balloon.to == "it")
  245.       return false;
  246.     
  247.     balloon = this._cache.restoreBalloon(balloon);
  248.     
  249.     this.balloon = balloon;
  250.     
  251.     if (balloon.translations) {
  252.       this.showBalloon(balloon);
  253.     } else {
  254.       if (this.request)
  255.         this.request.abort();
  256.       
  257.       this.request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
  258.       var target = this.request.QueryInterface(Ci.nsIDOMEventTarget);
  259.       target.addEventListener("load", this, false);
  260.       target.addEventListener("error", this, false);
  261.       
  262.       this.request.open("GET", "http://export.yandex.ru/bar/translate.xml" +
  263.         "?text=" + encodeURIComponent(balloon.text) +
  264.         "&from=" + balloon.from +
  265.         "&to=" + balloon.to +
  266.         "&locale=" + this.locale,
  267.         true);
  268.       
  269.       this.request.send(null);
  270.     }
  271.     
  272.     return true;
  273.   },
  274.   
  275.   response: function(event) {
  276.     let request = event.target;
  277.     let status = request.status;
  278.     
  279.     if (this.request === request)
  280.       this.request = null;
  281.     
  282.     if (status < 200 || status > 399)
  283.       return;
  284.     
  285.     let xml = Ya.nsIYa.safeE4Xml(request.responseXML, null, "translate");
  286.     if (!xml || parseInt(xml.error.@status, 10) != 0)
  287.       return;
  288.     
  289.     let balloon = this.balloon;
  290.       
  291.     ["from", "to", "url"]
  292.     .forEach(function(elName) {
  293.       let el = xml[elName][0];
  294.         balloon[elName] = el ? el.toString() : "";
  295.     });
  296.     
  297.     balloon.translations = [];
  298.     
  299.     for each (let translate in xml.translations.translation) {
  300.       let word = translate.@word.toString();
  301.       let part = {};
  302.       let parts = [];
  303.       
  304.       for each (let variant in translate.variant) {
  305.         let partOfSpeech = variant.@class.toString();
  306.         if (parts.indexOf(partOfSpeech) == -1) {
  307.           parts.push(partOfSpeech);
  308.           part[partOfSpeech] = [];
  309.         }
  310.         
  311.         let variantStr = variant.toString();
  312.         if (part[partOfSpeech].indexOf(variantStr) == -1)
  313.           part[partOfSpeech].push(variantStr);
  314.       }
  315.       
  316.       if (parts.length) {
  317.         balloon.translations.push({
  318.           word: word,
  319.           parts: parts,
  320.           part: part
  321.         });
  322.       }
  323.     }
  324.     
  325.     this._cache.storeBalloon(balloon);
  326.     
  327.     if (!request.doNotShow)
  328.       this.showBalloon(balloon);
  329.   },
  330.   
  331.   clearShowTimeout: function() {
  332.     if (this.showTimeout) {
  333.       clearTimeout(this.showTimeout);
  334.       this.showTimeout = null;
  335.     }
  336.   },
  337.   
  338.   doNotShowBalloonNow: function() {
  339.     this.clearShowTimeout();
  340.     
  341.     if (this.request)
  342.       this.request.doNotShow = true;
  343.   },
  344.   
  345.   showBalloon: function(balloon) {
  346.     if (!(balloon.translations && balloon.translations.length) ||
  347.         this.isPopupOpen(this.contextMenu) ||
  348.         balloon.contentIsActive != this.contentIsActive) {
  349.       
  350.       this.hideBalloon();
  351.       return;
  352.     }
  353.     
  354.     if (this.isPopupOpen(this.tooltipHTML))
  355.       this.tooltipHTML.hidePopup();
  356.     
  357.     let tooltip = this.tooltip;
  358.     tooltip.hidePopup();
  359.     
  360.     tooltip.from = balloon.from;
  361.     tooltip.to = balloon.to;
  362.     tooltip.url = balloon.url;
  363.     tooltip.translations = balloon.translations;
  364.     
  365.     tooltip.openPopupAtScreen(balloon.x, balloon.y, false);
  366.   },
  367.   
  368.   hideBalloon: function() {
  369.     if (this._tooltip)
  370.       this._tooltip.hidePopup();
  371.     
  372.     if (this.balloon && this.balloon.nodeRef)
  373.       this.balloon.nodeRef = null;
  374.   },
  375.   
  376.   onEnableChanged: function() {
  377.     if (!this.Prefs)
  378.       return;
  379.     
  380.     if (this.isPopupOpen(this.tooltip))
  381.       this.hideBalloon();
  382.     
  383.     this.enable = this.available && this.Prefs.get(this.ENABLE_PREF, false);
  384.   },
  385.   
  386.   onReverseChanged: function() {
  387.     if (!this.Prefs)
  388.       return;
  389.     
  390.     this.reverse = this.Prefs.get(this.REVERSE_PREF, false);
  391.   },
  392.   
  393.   onDirectionChanged: function() {
  394.     this.direction = {
  395.       from: this.Prefs.get(this.FROM_PREF, "en"),
  396.       to: this.Prefs.get(this.TO_PREF, "ru")
  397.     };
  398.   },
  399.   
  400.   observe: function(aSubject) {
  401.     switch (aSubject) {
  402.       case "pagehide":
  403.         let [, browser] = arguments;
  404.         if (browser !== gBrowser.mCurrentBrowser)
  405.           return;
  406.       
  407.       case "onWindowLocationChange":
  408.         this.doNotShowBalloonNow();
  409.         this.hideBalloon();
  410.         break;
  411.     }
  412.   },
  413.   
  414.   handleEvent: function(event) {
  415.     switch (event.type) {
  416.       case "mousemove":
  417.         this.clearShowTimeout();
  418.         this.showTimeout = setTimeout(this.onMouseHoverWithoutContext, this.intervalShow,
  419.                                       this, event, event.rangeParent, event.rangeOffset);
  420.         break;
  421.       
  422.       case "mouseout":
  423.         if (!this.isPopupOpen(this.tooltip))
  424.           this.doNotShowBalloonNow();
  425.         break;
  426.       
  427.       case "scroll":
  428.         var timeNow = Date.now();
  429.         if (timeNow - this._lastScrollEventTime > 200) {
  430.           this._lastScrollEventTime = timeNow;
  431.           this.doNotShowBalloonNow();
  432.           this.hideBalloon();
  433.         }
  434.         break;
  435.       
  436.       case "load":
  437.         this.response(event);
  438.         break;
  439.       
  440.       case "error":
  441.         break;
  442.     }
  443.   },
  444.   
  445.   _getNodeWeakReference: function(aNode) {
  446.     try {
  447.       return (aNode instanceof Ci.nsISupportsWeakReference) ? aNode.GetWeakReference() : null;
  448.     } catch (e) {}
  449.     
  450.     return null;
  451.   },
  452.   
  453.   _checkForNewNode: function(aRangeParent, aRangeOffset) {
  454.     if (!this.isPopupOpen(this.tooltip) || this.tooltip.contains(aRangeParent))
  455.       return false;
  456.     
  457.     let balloon = this.balloon;
  458.     
  459.     if (balloon && balloon.nodeRef) {
  460.       if (aRangeOffset < balloon.begin || aRangeOffset > balloon.end)
  461.         return true;
  462.       
  463.       if (balloon.nodeRef !== this._getNodeWeakReference(aRangeParent.parentNode))
  464.         return true;
  465.     }
  466.     
  467.     return false;
  468.   },
  469.   
  470.   checkForNewNode: function(aRangeParent, aRangeOffset) {
  471.     if (this._checkForNewNode(aRangeParent, aRangeOffset))
  472.       this.hideBalloon();
  473.   },
  474.   
  475.   onMouseHoverWithoutContext: function(aSelf, aEvent, aNode, aOffset) {
  476.     aSelf.clearShowTimeout();
  477.     
  478.     if (aSelf.isUserPage(aEvent) && !aSelf.onMouseHover(aEvent, aNode, aOffset))
  479.       aSelf.hideBalloon();
  480.   },
  481.   
  482.   onMouseHover: function(event, node, offset) {
  483.     if (!(node && node.nodeType === Node.TEXT_NODE))
  484.       return false;
  485.     
  486.     try {
  487.       var nodeDocument = node.ownerDocument;
  488.       var parent = nodeDocument.elementFromPoint(event.clientX, event.clientY);
  489.     } catch (e) {}
  490.     
  491.     if (!(parent && node.parentNode === parent))
  492.       return false;
  493.     
  494.     function length(s, reverse) {
  495.       if (reverse)
  496.         s = s.split("").reverse().join("");
  497.       
  498.       return (s.match(/^[\u0041-\u005a\u0061-\u007a\u00c0-\u1fff\-\'\u2019]+/) || [""])[0].length;
  499.     }
  500.     
  501.     var text = node.nodeValue;
  502.     var left = text.substr(0, offset),
  503.         right = text.substr(offset);
  504.     
  505.     var begin = offset - length(left, true);
  506.     var end = offset + length(right, false);
  507.     
  508.     if (end - begin <= 0)
  509.       text = "";
  510.     else
  511.       text = text.substr(begin, end - begin);
  512.     
  513.     if (!text || /(^\-)|(\-$)|(\-{2,})|([\'\u2019]{2,})/.test(text))
  514.       return false;
  515.     
  516.     /* fx37
  517.     if (isGreaterThenFx36) {// Bug 396392
  518.       let nodeRange = nodeDocument.createRange();
  519.       nodeRange.setStart(node, begin);
  520.       nodeRange.setEnd(node, end);
  521.       
  522.       if ("getBoundingClientRect" in nodeRange) {
  523.         let nodeBCR = nodeRange.getBoundingClientRect();
  524.  
  525.         if (nodeBCR.left > event.clientX || nodeBCR.right < event.clientX ||
  526.             nodeBCR.top > event.clientY || nodeBCR.bottom < event.clientY)
  527.           return false;
  528.       }
  529.     }
  530.     */
  531.     
  532.     return this.translateIt({
  533.       text: text,
  534.       x: event.screenX,
  535.       y: event.screenY,
  536.       nodeRef: this._getNodeWeakReference(parent),
  537.       begin: begin,
  538.       end: end,
  539.       contentIsActive: this.contentIsActive
  540.     });
  541.   }
  542. }
  543.  
  544. window.addEventListener("load", function(aLoadEvent) {
  545.   aLoadEvent.currentTarget.removeEventListener("load", arguments.callee, false);
  546.   
  547.   aLoadEvent.currentTarget.addEventListener("unload", function(aUnloadEvent) {
  548.     aUnloadEvent.currentTarget.removeEventListener("unload", arguments.callee, false);
  549.     Ya.YaTranslate.destroy();
  550.   }, false);
  551.   
  552.   Ya.YaTranslate.init();
  553. }, false);
  554.  
  555. }