home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 123 / cdrom123.iso / essenc / extens / nlinkf / Linkification.xpi / chrome / linkification.jar / content / linkification / linkificationOverlay.js < prev    next >
Encoding:
Text File  |  2004-10-16  |  34.7 KB  |  1,311 lines

  1. var objLinkify =
  2. {
  3.     Linkify_Init: function()
  4.     {
  5.         this.prefService = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService).getBranch('linkification.settings.');
  6.         this.Linkify_GetPreferences();
  7.  
  8.         this.aProtocol = new Array();
  9.         this.aRecognizeProtocolAs = new Array();
  10.  
  11.         var aTextProtocolList = this.sLinkify_TextProtocolList.split(",");
  12.         var ctr;
  13.         for (ctr = 0; ctr < aTextProtocolList.length; ++ctr)
  14.         {
  15.             var aTextLinkProtocol = aTextProtocolList[ctr].split(":");
  16.             if ((aTextLinkProtocol[0].length > 0) && (aTextLinkProtocol[1].length > 0))
  17.             {
  18.                 this.aProtocol.push(aTextLinkProtocol[0]);
  19.                 this.aRecognizeProtocolAs.push(aTextLinkProtocol[1]);
  20.             }
  21.         }
  22.  
  23.         this.aSubdomain = new Array();
  24.         this.aRecognizeSubdomainAs = new Array();
  25.  
  26.         var aSubdomainProtocolList = this.sLinkify_SubdomainProtocolList.split(",");
  27.         for (ctr = 0; ctr < aSubdomainProtocolList.length; ++ctr)
  28.         {
  29.             var aTextLinkProtocol = aSubdomainProtocolList[ctr].split(":");
  30.             if ((aTextLinkProtocol[0].length > 0) && (aTextLinkProtocol[1].length > 0))
  31.             {
  32.                 this.aSubdomain.push(aTextLinkProtocol[0]);
  33.                 this.aRecognizeSubdomainAs.push(aTextLinkProtocol[1]);
  34.             }
  35.         }
  36.  
  37.         this.aExcludeTags = this.sLinkify_ExcludeTagList.split(",");
  38.         this.aSpaceTags = this.sLinkify_SpaceTagList.split(",");
  39.  
  40.         var sProtocol = "(";
  41.         for (ctr = 0; ctr < this.aProtocol.length; ++ctr)
  42.         {
  43.             sProtocol += "(?:" + this.aProtocol[ctr] + ")|";
  44.         }
  45.         sProtocol = sProtocol.substr(0, sProtocol.length - 1) + ")";
  46.  
  47.         var sSubdomain = "(";
  48.         for (ctr = 0; ctr < this.aSubdomain.length; ++ctr)
  49.         {
  50.             sSubdomain += "(" + this.aSubdomain[ctr] + ")|";
  51.         }
  52.         sSubdomain = sSubdomain.substr(0, sSubdomain.length - 1) + ")";
  53.  
  54.         var sDomainSuffixList = "(museum)|(com\\.[a-z]{2})|(org\\.[a-z]{2})|(net\\.[a-z]{2})|(ac\\.[a-z]{2})|(co\\.[a-z]{2})|(aero)|(coop)|(info)|(name)|(biz)|(com)|(edu)|(gov)|(int)|(mil)|(net)|(org)|(pro)|(cc)";
  55.         var sAllDomainSuffix = "(" + sDomainSuffixList + "|([a-z]{2}))";
  56.         var sRegDomainSuffix = "(" + sDomainSuffixList + ")";
  57.  
  58.         var sIPAddress = "((((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|[0-9])\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|[0-9]))";
  59.         var sDomain = "(\\w+(\\-\\w+)*(\\.\\w+(\\-\\w+)*)*)";
  60.         var sDomainOther = "((\\w+(\\-\\w+)*)(\\.\\w+(\\-\\w+)*)+)";
  61.  
  62.         var sUserAuth = "(([\\w\\.\\%][\\-\\@]?)+(\\:([\\w\\.\\%]\\-?)+)?\\@)";
  63.         var sPortAndPathOptional = "((:\\d+)?((([\\/\\#\\?]+((\\&(amp;)?)|[\\w\\~\\%\\=\\-\\+\\,\\.\\:\\/\\|\\$\\;])+)+[\\&\\w\\/\\#\\%\\=\\+\\:\\/\\|\\$])|([\\/\\#\\?\\$]+)|(\\b)))";
  64.         var sPortAndPathRequired = "((:\\d+)?((([\\/\\#\\?]+((\\&(amp;)?)|[\\w\\~\\%\\=\\-\\+\\,\\.\\:\\/\\|\\$\\;])+)+[\\&\\w\\/\\#\\%\\=\\+\\:\\/\\|\\$])|([\\/\\#\\?\\$]+)))";
  65.  
  66.         var sRegExpHTTP = sProtocol + "(\\:\\/\\/" + sUserAuth + "?(((localhost)|" + sIPAddress + "|(" + sDomain + "\\." + sAllDomainSuffix + "))" + sPortAndPathOptional + "))";
  67.         var sRegExpWWW = sUserAuth + "?(" + sSubdomain + "\\." + sDomain + "\\." + sAllDomainSuffix + ")" + sPortAndPathOptional;
  68.         var sRegExpOther = "((" + sUserAuth + sDomainOther + "\\." + sRegDomainSuffix + sPortAndPathOptional + ")|(" + sDomainOther + "\\." + sRegDomainSuffix + sPortAndPathRequired + "))";
  69.         var sRegExpIP = "((" + sUserAuth + sIPAddress + sPortAndPathOptional + ")|(" + sIPAddress + sPortAndPathRequired + "))";
  70.         var sRegExpEmail = "((([\\w\\.\\-\\+])+\\@)((" + sIPAddress + ")|(" + sDomainOther + ")))";
  71.  
  72.         this.aRegExpListConfined = new Array();
  73.         this.aRegExpListConfined.push(new RegExp("^" + sRegExpHTTP + "$", "i"));
  74.         this.aRegExpListConfined.push(new RegExp("^" + sRegExpWWW + "$", "i"));
  75.         this.aRegExpListConfined.push(new RegExp("^" + sRegExpOther + "$", "i"));
  76.         this.aRegExpListConfined.push(new RegExp("^" + sRegExpIP + "$", "i"));
  77.         this.aRegExpListConfined.push(new RegExp("^" + sRegExpEmail + "$", "i"));
  78.  
  79.         this.aRegExpList = new Array();
  80.         this.aRegExpList.push(new RegExp(sRegExpHTTP, "i"));
  81.         this.aRegExpList.push(new RegExp(sRegExpWWW, "i"));
  82.         this.aRegExpList.push(new RegExp(sRegExpOther, "i"));
  83.         this.aRegExpList.push(new RegExp(sRegExpIP, "i"));
  84.         this.aRegExpList.push(new RegExp(sRegExpEmail, "i"));
  85.  
  86.         this.aRegExpDesc = new Array();
  87.         this.aRegExpDesc.push("HTTP");
  88.         this.aRegExpDesc.push("WWW");
  89.         this.aRegExpDesc.push("Other");
  90.         this.aRegExpDesc.push("StandaloneIP");
  91.         this.aRegExpDesc.push("Email");
  92.  
  93.         this.aRegExpTarget = new Array();
  94.         this.aRegExpTarget.push("");
  95.         this.aRegExpTarget.push("");
  96.         this.aRegExpTarget.push("http://$1");
  97.         this.aRegExpTarget.push("http://$1");
  98.         this.aRegExpTarget.push("mailto:$1");
  99.  
  100.         var sRegExpAll = "(";
  101.         for (ctr = 0; ctr < this.aRegExpList.length; ++ctr)
  102.         {
  103.             sRegExpAll += this.aRegExpList[ctr].source + "|";
  104.         }
  105.         sRegExpAll = sRegExpAll.substr(0, sRegExpAll.length - 1) + ")";
  106.         this.rRegExpAll = new RegExp(sRegExpAll, "i");
  107.  
  108.         this.nStockRegExps = this.aRegExpList.length;
  109.  
  110.         this.bAllLinkified = false;
  111.         // End Init Globals
  112.     },
  113.  
  114.     Linkify_Process: function(ndTarget)
  115.     {
  116.         this.Linkify_GetPreferences();
  117.         this.Linkify_GetBody(ndTarget);
  118.  
  119.         if (!this.bLinkify_Toggle && !this.bFromPopup)
  120.         {
  121.             return false;
  122.         }
  123.  
  124.         if (!this.bFromPopup)
  125.         {
  126.             var aSiteList = this.sLinkify_SiteList.split(",");
  127.  
  128.             var sLocation = window._content.document.location.href;
  129.             sLocation = sLocation.substr(sLocation.indexOf("://") + 3);
  130.             sLocation = sLocation.substr(0, sLocation.indexOf("/"));
  131.  
  132.             var ctr;
  133.             for (ctr = 0; ctr < aSiteList.length; ++ctr)
  134.             {
  135.                 if (aSiteList[ctr].length > sLocation.length)
  136.                 {
  137.                     continue;
  138.                 }
  139.  
  140.                 if (sLocation.substr(sLocation.length - aSiteList[ctr].length).toLowerCase() == aSiteList[ctr].toLowerCase())
  141.                 {
  142.                     return false;
  143.                 }
  144.             }
  145.         }
  146.  
  147.         this.bAllLinkified = true;
  148.  
  149.         if (this.ndBody)
  150.         {
  151.             if (!this.bFromPopup)
  152.             {
  153.                 if (this.ndDocument.getElementsByTagName("applet").length > 0)
  154.                 {
  155.                     this.bAllLinkified = false;
  156.                     return false;
  157.                 }
  158.             }
  159.  
  160.             this.nCharNum = 0;
  161.             this.nCharNumNoSpaces = 0;
  162.  
  163.             this.aSpaceBeforeIndex = new Array();
  164.             this.aPath = new Array();
  165.             this.aPathStart = new Array();
  166.             this.aPathLength = new Array();
  167.  
  168.             this.aText = new Array();
  169.             this.aTextStart = new Array();
  170.             this.aLinkType = new Array();
  171.  
  172.             if (!this.bFromPopup && this.bLinkify_CharLimitEnabled)
  173.             {
  174.                 var objRange = document.createRange();
  175.                 objRange.setEnd(this.ndBody, this.ndBody.childNodes.length);
  176.                 objRange.setStart(this.ndBody, 0);
  177.                 if (objRange.toString().length > this.nLinkify_CharLimit)
  178.                 {
  179.                     this.bAllLinkified = false;
  180.                     return false;
  181.                 }
  182.             }
  183.  
  184.             this.sText = this.Linkify_GetText(this.ndBody);
  185.             this.Linkify_GetAllLinks();
  186.             this.Linkify_ReplaceText();
  187.         }
  188.  
  189.         return false;
  190.     },
  191.  
  192.     Linkify_GetBody: function(ndTarget)
  193.     {
  194.         this.ndDocument = ndTarget;
  195.         this.ndBody = this.ndDocument.getElementsByTagName("body");
  196.         if (this.ndBody)
  197.         {
  198.             this.ndBody = this.ndBody[0];
  199.         }
  200.     },
  201.  
  202.     Linkify_InArray: function(sSearch, aArray)
  203.     {
  204.         for (var ctr = 0; ctr < aArray.length; ++ctr)
  205.         {
  206.             var rMatch = new RegExp("^(" + aArray[ctr] + ")$", "i");
  207.             if (rMatch.test(sSearch))
  208.             {
  209.                 return ctr;
  210.             }
  211.         }
  212.  
  213.         return -1;
  214.     },
  215.  
  216.     Linkify_GetText: function(ndParent)
  217.     {
  218.         this.aSpaceBeforeIndex = new Array();
  219.         var sText = "";
  220.         var sPath = "";
  221.  
  222.         if (arguments.length == 2)
  223.         {
  224.             sPath = arguments[1];
  225.         }
  226.  
  227.         var ndChildren = ndParent.childNodes;
  228.         var nNumChildren = ndChildren.length;
  229.         var sCurrentPath;
  230.         for (var ctr = 0; ctr < nNumChildren; ++ctr)
  231.         {
  232.             sCurrentPath = sPath + "" + ctr + "-";
  233.  
  234.             var sNodeName = ndChildren[ctr].nodeName;
  235.             if (sNodeName == "#text")
  236.             {
  237.                 var sNodeText = ndChildren[ctr].nodeValue;
  238.  
  239.                 this.aPathStart[this.aPathStart.length] = this.nCharNum;
  240.                 this.aPathLength[this.aPathLength.length] = sNodeText.length;
  241.                 this.aPath[this.aPath.length] = sCurrentPath.substr(0, sCurrentPath.length - 1);
  242.  
  243.                 sText += sNodeText;
  244.                 this.nCharNum += sNodeText.length;
  245.             }
  246.             else
  247.             {
  248.                 if (this.Linkify_InArray(sNodeName, this.aExcludeTags) > -1)
  249.                 {
  250.                     var sNodeText = " ";
  251.  
  252.                     this.aPathStart[this.aPathStart.length] = this.nCharNum;
  253.                     this.aPathLength[this.aPathLength.length] = sNodeText.length;
  254.                     this.aPath[this.aPath.length] = sCurrentPath.substr(0, sCurrentPath.length - 1);
  255.  
  256.                     sText += sNodeText;
  257.                     this.nCharNum += sNodeText.length;
  258.                     continue;
  259.                 }
  260.  
  261.                 if (this.Linkify_InArray(sNodeName, this.aSpaceTags) > -1)
  262.                 {
  263.                     var sNodeText = " ";
  264.  
  265.                     this.aPathStart[this.aPathStart.length] = this.nCharNum;
  266.                     this.aPathLength[this.aPathLength.length] = sNodeText.length;
  267.                     this.aPath[this.aPath.length] = sCurrentPath.substr(0, sCurrentPath.length - 1);
  268.  
  269.                     sText += sNodeText;
  270.  
  271.                     this.nCharNum += sNodeText.length;
  272.                     sText += this.Linkify_GetText(ndChildren[ctr], sCurrentPath) + " ";
  273.                     this.nCharNum += 1;
  274.  
  275.                     continue;
  276.                 }
  277.                 else
  278.                 {
  279.                     sText += this.Linkify_GetText(ndChildren[ctr], sCurrentPath);
  280.                 }
  281.             }
  282.         }
  283.  
  284.         return sText;
  285.     },
  286.  
  287.     Linkify_GetAllLinks: function()
  288.     {
  289.         var aMatch, sMatch;
  290.         var bAddLink, sImageCheck, sFile, nLocation;
  291.         var nTempStart = 0;
  292.         var sTempText = this.sText;
  293.         while (aMatch = sTempText.match(this.rRegExpAll))
  294.         {
  295.             sMatch = aMatch[0];
  296.  
  297.             bAddLink = true;
  298.  
  299.             nLinkType = this.Linkify_GetLinkType(sMatch, false);
  300.             if (nLinkType == -1)
  301.             {
  302.                 bAddLink = false;
  303.             }
  304.  
  305.             if (!this.bLinkify_LinkifyImages)
  306.             {
  307.                 sFile = sMatch;
  308.                 if (sFile.indexOf("?") > -1)
  309.                 {
  310.                     sFile = sFile.substr(0, sFile.indexOf("?"));
  311.                 }
  312.  
  313.                 if (sFile.indexOf("#") > -1)
  314.                 {
  315.                     sFile = sFile.substr(0, sFile.indexOf("#"));
  316.                 }
  317.  
  318.                 sImageCheck = sFile.substr(sFile.length - 5).toLowerCase();
  319.                 if (sImageCheck == ".jpeg")
  320.                 {
  321.                     bAddLink = false;
  322.                 }
  323.  
  324.                 sImageCheck = sImageCheck.substr(1);
  325.                 if ((sImageCheck == ".jpg") || (sImageCheck == ".gif") || (sImageCheck == ".png") || (sImageCheck == ".bmp"))
  326.                 {
  327.                     bAddLink = false;
  328.                 }
  329.             }
  330.             nLocation = sTempText.indexOf(sMatch);
  331.  
  332.             if (bAddLink)
  333.             {
  334.                 this.aText.push(sMatch);
  335.                 this.aTextStart.push(nTempStart + nLocation);
  336.                 this.aLinkType.push(nLinkType);
  337.             }
  338.  
  339.             nTempStart += (nLocation + sMatch.length);
  340.             sTempText = sTempText.substr((nLocation + sMatch.length), (sTempText.length - nLocation + sMatch.length));
  341.         }
  342.  
  343.         return true;
  344.     },
  345.  
  346.     Linkify_GetLinkType: function(sText, bDoubleClick)
  347.     {
  348.         var nLinkType = -1;
  349.         var ctr;
  350.         for (ctr = this.aRegExpList.length - 1; ctr >= 0; --ctr)
  351.         {
  352.             if (this.aRegExpListConfined[ctr].test(sText))
  353.             {
  354.                 nLinkType = ctr;
  355.                 if (this.aRegExpDesc[ctr] == "Custom")
  356.                 {
  357.                     if (!this.bLinkify_Custom && !bDoubleClick)
  358.                     {
  359.                         nLinkType = -1;
  360.                     }
  361.                     return nLinkType;
  362.                 }
  363.                 if (this.aRegExpDesc[ctr] == "Email")
  364.                 {
  365.                     if (!this.bLinkify_Email && !bDoubleClick)
  366.                     {
  367.                         nLinkType = -1;
  368.                     }
  369.                     return nLinkType;
  370.                 }
  371.             }
  372.         }
  373.  
  374.         if ((this.aRegExpDesc[nLinkType] == "HTTP") && !this.bLinkify_HTTP && !bDoubleClick)
  375.         {
  376.             nLinkType = -1;
  377.         }
  378.         else if ((this.aRegExpDesc[nLinkType] == "WWW") && !this.bLinkify_WWW && !bDoubleClick)
  379.         {
  380.             nLinkType = -1;
  381.         }
  382.         else if ((this.aRegExpDesc[nLinkType] == "StandaloneIP") && !this.bLinkify_IP && !bDoubleClick)
  383.         {
  384.             nLinkType = -1;
  385.         }
  386.         else if ((this.aRegExpDesc[nLinkType] == "Other") && !this.bLinkify_Other && !bDoubleClick)
  387.         {
  388.             nLinkType = -1;
  389.         }
  390.  
  391.         return nLinkType;
  392.     },
  393.  
  394.     Linkify_GetCharIndex: function(nChar)
  395.     {
  396.         for (var ctr = (this.aPathStart.length - 1); ctr >= 0; --ctr)
  397.         {
  398.             if (this.aPathStart[ctr] <= nChar)
  399.             {
  400.                 return ctr;
  401.             }
  402.         }
  403.  
  404.         return -1;
  405.     },
  406.  
  407.     Linkify_TraversePath: function(aNodePath)
  408.     {
  409.         var ndNode = this.ndBody;
  410.         for (var ctr = 0; ctr < aNodePath.length; ++ctr)
  411.         {
  412.             var nNode = parseInt(aNodePath[ctr], 10);
  413.             ndNode = ndNode.childNodes[nNode];
  414.         }
  415.  
  416.         return ndNode;
  417.     },
  418.  
  419.     Linkify_FindCharacter: function(ndNode, nCharNum)
  420.     {
  421.         var nStart = 0;
  422.         var nEnd = ndNode.childNodes.length;
  423.         var nMid;
  424.  
  425.         if (arguments.length == 4)
  426.         {
  427.             nStart = arguments[2];
  428.             nEnd = arguments[3];
  429.         }
  430.  
  431.         if (ndNode.nodeName == "#text")
  432.         {
  433.                 aReturn = new Array();
  434.                 aReturn.push(ndNode);
  435.                 aReturn.push(nCharNum);
  436.  
  437.                 return aReturn;
  438.         }
  439.  
  440.         while ((nEnd - nStart) == 1)
  441.         {
  442.             ndNode = ndNode.childNodes[nStart];
  443.  
  444.             if (ndNode.nodeName == "#text")
  445.             {
  446.                 aReturn = new Array();
  447.                 aReturn.push(ndNode);
  448.                 aReturn.push(nCharNum);
  449.  
  450.                 return aReturn;
  451.             }
  452.  
  453.             nStart = 0;
  454.             nEnd = ndNode.childNodes.length;
  455.         }
  456.  
  457.         nMid = Math.ceil((nStart + nEnd) / 2);
  458.  
  459.         var objRange = document.createRange();
  460.  
  461.         objRange.setEnd(ndNode, nMid);
  462.         objRange.setStart(ndNode, nStart);
  463.  
  464.         var sFirstHalf = objRange.toString();
  465.         if (sFirstHalf.length > nCharNum)
  466.         {
  467.             return this.Linkify_FindCharacter(ndNode, nCharNum, nStart, nMid);
  468.         }
  469.         nCharNum -= sFirstHalf.length;
  470.  
  471.         objRange.setEnd(ndNode, nEnd);
  472.         objRange.setStart(ndNode, nMid);
  473.  
  474.         return this.Linkify_FindCharacter(ndNode, nCharNum, nMid, nEnd);
  475.     },
  476.  
  477.     Linkify_IsTextNodeWithinExcludeTag: function(ndNode)
  478.     {
  479.         while (ndNode.nodeName.toLowerCase() != "body")
  480.         {
  481.             if (this.Linkify_InArray(ndNode.parentNode.nodeName, this.aExcludeTags) > -1)
  482.             {
  483.                 return true;
  484.             }
  485.  
  486.             ndNode = ndNode.parentNode;
  487.         }
  488.  
  489.         return false;
  490.     },
  491.  
  492.     Linkify_IsTextNodeWithinMouseEventTag: function(ndNode)
  493.     {
  494.         if (this.bLinkify_OnClick)
  495.         {
  496.             return false;
  497.         }
  498.  
  499.         while (ndNode.nodeName.toLowerCase() != "#document")
  500.         {
  501.             if (ndNode.getAttribute("onclick") || ndNode.parentNode.getAttribute("onmousedown"))
  502.             {
  503.                 return true;
  504.             }
  505.  
  506.             if (ndNode.nodeName.toLowerCase() == "body")
  507.             {
  508.                 break;
  509.             }
  510.  
  511.             ndNode = ndNode.parentNode;
  512.         }
  513.  
  514.         return false;
  515.     },
  516.  
  517.     Linkify_IsTextNodeWithinSpaceTag: function(ndNode)
  518.     {
  519.         var aSideIsSpace = new Array();
  520.         aSideIsSpace.push(false);
  521.         aSideIsSpace.push(false);
  522.  
  523.         var sPosition = "";
  524.         if (ndNode.nodeName.toLowerCase() != "body")
  525.         {
  526.             if ((ndNode.previousSibling) && (this.Linkify_InArray(ndNode.previousSibling.nodeName, this.aSpaceTags) > -1))
  527.             {
  528.                 aSideIsSpace[0] = true;
  529.             }
  530.             if ((ndNode.nextSibling) && (this.Linkify_InArray(ndNode.nextSibling.nodeName, this.aSpaceTags) > -1))
  531.             {
  532.                 aSideIsSpace[1] = true;
  533.             }
  534.         }
  535.  
  536.         while (ndNode.nodeName.toLowerCase() != "body")
  537.         {
  538.             if (aSideIsSpace[0] && aSideIsSpace[1])
  539.             {
  540.                 return aSideIsSpace;
  541.             }
  542.  
  543.             var ndFirst = ndNode.parentNode.firstChild;
  544.             var ndLast = ndNode.parentNode.lastChild;
  545.  
  546.             if (ndFirst != ndLast)
  547.             {
  548.                 if (ndFirst == ndNode)
  549.                 {
  550.                     if (sPosition == "Last")
  551.                     {
  552.                         return aSideIsSpace;
  553.                     }
  554.                     sPosition = "First"
  555.                 }
  556.                 else if (ndLast == ndNode)
  557.                 {
  558.                     if (sPosition == "First")
  559.                     {
  560.                         return aSideIsSpace;
  561.                     }
  562.                     sPosition = "Last"
  563.                 }
  564.                 else
  565.                 {
  566.                     if ((sPosition == "First") && (ndNode.previousSibling) && (this.Linkify_InArray(ndNode.previousSibling.nodeName, this.aSpaceTags) > -1))
  567.                     {
  568.                         aSideIsSpace[0] = true;
  569.                     }
  570.                     if ((sPosition == "Last") && (ndNode.nextSibling) && (this.Linkify_InArray(ndNode.nextSibling.nodeName, this.aSpaceTags) > -1))
  571.                     {
  572.                         aSideIsSpace[1] = true;
  573.                     }
  574.                     return aSideIsSpace;
  575.                 }
  576.             }
  577.  
  578.             var nSpaceIndex = this.Linkify_InArray(ndNode.parentNode.nodeName, this.aSpaceTags);
  579.             if (nSpaceIndex > -1)
  580.             {
  581.                 if ((sPosition == "First") || (sPosition == ""))
  582.                 {
  583.                     aSideIsSpace[0] = true;
  584.                 }
  585.  
  586.                 if ((sPosition == "Last") || (sPosition == ""))
  587.                 {
  588.                     aSideIsSpace[1] = true;
  589.                 }
  590.             }
  591.  
  592.             ndNode = ndNode.parentNode;
  593.         }
  594.  
  595.         return aSideIsSpace;
  596.     },
  597.  
  598.     Linkify_GroupTextNodes: function(ndNode)
  599.     {
  600.         if (ndNode.nodeName != "#text")
  601.         {
  602.             return false;
  603.         }
  604.  
  605.         var nCharNum = -1;
  606.         var nPreLimit = -1;
  607.         var nPostLimit = -1;
  608.         if (arguments.length == 4)
  609.         {
  610.             nCharNum = arguments[1];
  611.             nPreLimit = arguments[2];
  612.             nPostLimit = arguments[3];
  613.         }
  614.  
  615.         var aTextNodes = new Array();
  616.         aTextNodes.push(ndNode);
  617.  
  618.         var objRange = document.createRange();
  619.         objRange.setEnd(ndNode, 0);
  620.         objRange.setStart(this.ndBody, 0);
  621.  
  622.         var nPreLength = nCharNum;
  623.         while (objRange.toString().length > 0)
  624.         {
  625.             var ndPreviousNode = this.Linkify_FindCharacter(this.ndBody, objRange.toString().length - 1)[0];
  626.  
  627.             if (this.Linkify_IsTextNodeWithinSpaceTag(ndPreviousNode)[1])
  628.             {
  629.                 break;
  630.             }
  631.             if (this.Linkify_IsTextNodeWithinExcludeTag(ndPreviousNode))
  632.             {
  633.                 break;
  634.             }
  635.  
  636.             nPreLength += ndPreviousNode.nodeValue.length;
  637.             aTextNodes.splice(0, 0, ndPreviousNode);
  638.             objRange.setEnd(ndPreviousNode, 0);
  639.  
  640.             if ((nPreLength > -1) && (nPreLimit > -1) && (nPreLength > nPreLimit))
  641.             {
  642.                 break;
  643.             }
  644.         }
  645.  
  646.         objRange.setEnd(ndNode, ndNode.nodeValue.length);
  647.  
  648.         var ndNextNode = ndNode;
  649.         var nPostLength = ndNode.nodeValue.length - nCharNum;
  650.         while (objRange.toString().length > 0)
  651.         {
  652.             var ndTempNode = this.Linkify_FindCharacter(this.ndBody, objRange.toString().length + 1)[0];
  653.             if (ndTempNode == ndNextNode)
  654.             {
  655.                 break;
  656.             }
  657.             var ndNextNode = ndTempNode;
  658.  
  659.             var aNodeSpaces = this.Linkify_IsTextNodeWithinSpaceTag(ndNextNode);
  660.             var bNodeExcluded = this.Linkify_IsTextNodeWithinExcludeTag(ndNextNode)
  661.             if (aNodeSpaces[0] || bNodeExcluded)
  662.             {
  663.                 break;
  664.             }
  665.             if (aNodeSpaces[1])
  666.             {
  667.                 aTextNodes.push(ndNextNode);
  668.                 break;
  669.             }
  670.  
  671.             nPostLength += ndNextNode.nodeValue.length;
  672.             aTextNodes.push(ndNextNode);
  673.             objRange.setEnd(ndNextNode, ndNextNode.nodeValue.length);
  674.  
  675.             if ((nPostLength > -1) && (nPostLimit > -1) && (nPostLength > nPostLimit))
  676.             {
  677.                 break;
  678.             }
  679.         }
  680.  
  681.         return aTextNodes;
  682.     },
  683.  
  684.     Linkify_ReplaceText: function()
  685.     {
  686.         for (var ctr = (this.aTextStart.length - 1); ctr >= 0; --ctr)
  687.         {
  688.             var nLinkType = this.aLinkType[ctr];
  689.  
  690.             var sText = this.aText[ctr];
  691.  
  692.             var nTextStart = this.aTextStart[ctr];
  693.             var nTextEnd = nTextStart + sText.length;
  694.  
  695.             var nIndex = this.Linkify_GetCharIndex(nTextStart);
  696.             var nEndIndex = this.Linkify_GetCharIndex(nTextEnd - 1);
  697.  
  698.             var aIndexPath = this.aPath[nIndex].split("-");
  699.             var aEndIndexPath = this.aPath[nEndIndex].split("-");
  700.  
  701.             var bTextBeginsNode = false;
  702.             var bTextEndsNode = false;
  703.  
  704.             if (this.aPathStart[nIndex] == nTextStart)
  705.             {
  706.                 bTextBeginsNode = true;
  707.                 while (aIndexPath.length > aEndIndexPath.length)
  708.                 {
  709.                     aIndexPath.splice(aIndexPath.length - 1, 1);
  710.                 }
  711.             }
  712.  
  713.             if ((this.aPathStart[nEndIndex] + this.aPathLength[nEndIndex]) == (nTextStart + sText.length))
  714.             {
  715.                 bTextEndsNode = true;
  716.                 while (aEndIndexPath.length > aIndexPath.length)
  717.                 {
  718.                     aEndIndexPath.splice(aEndIndexPath.length - 1, 1);
  719.                 }
  720.             }
  721.  
  722.             if (aIndexPath.length != aEndIndexPath.length)
  723.             {
  724.                 continue;
  725.             }
  726.  
  727.             while (bTextBeginsNode && bTextEndsNode && (aIndexPath.length > 1) && (aIndexPath[aIndexPath.length - 2] != aEndIndexPath[aEndIndexPath.length - 2]))
  728.             {
  729.                 aIndexPath.splice(aIndexPath.length - 1, 1);
  730.                 aEndIndexPath.splice(aEndIndexPath.length - 1, 1);
  731.             }
  732.  
  733.             var ndNode = this.Linkify_TraversePath(aIndexPath);
  734.             var ndParent = ndNode.parentNode;
  735.  
  736.             if (this.Linkify_IsTextNodeWithinMouseEventTag(ndParent))
  737.             {
  738.                 continue;
  739.             }
  740.  
  741.             var ndEndNode = this.Linkify_TraversePath(aEndIndexPath);
  742.  
  743.             if (!bTextEndsNode)
  744.             {
  745.                 ndEndNode.splitText(nTextEnd - this.aPathStart[nEndIndex]);
  746.             }
  747.  
  748.             if (!bTextBeginsNode)
  749.             {
  750.                 ndNode.splitText(nTextStart - this.aPathStart[nIndex]);
  751.                 ndNode = ndNode.nextSibling;
  752.                 if (this.aPath[nIndex] == this.aPath[nEndIndex])
  753.                 {
  754.                     ndEndNode = ndEndNode.nextSibling;
  755.                 }
  756.             }
  757.  
  758.             var ndNewNode = this.ndDocument.createElement("a");
  759.  
  760.             var sLinkLocation = this.Linkify_GetLinkLocation(nLinkType, sText);
  761.             ndNewNode.setAttribute("href", sLinkLocation);
  762.             ndNewNode.setAttribute("class", "linkification-ext");
  763.  
  764.             var sStyle = "";
  765.             if (this.bLinkify_HighlightText)
  766.             {
  767.                 sStyle += "color:" + this.sLinkify_TextColor;
  768.             }
  769.             if (this.bLinkify_HighlightBG)
  770.             {
  771.                 if (sStyle.length > 0)
  772.                 {
  773.                     sStyle += "; ";
  774.                 }
  775.                 sStyle += "background-color:" + this.sLinkify_BackgroundColor;
  776.             }
  777.             if (sStyle.length > 0)
  778.             {
  779.                 ndNewNode.setAttribute("style", sStyle);
  780.             }
  781.  
  782.             while (ndNode != ndEndNode)
  783.             {
  784.                 var ndClone = ndNode.cloneNode(true);
  785.                 ndNewNode.appendChild(ndClone);
  786.                 ndNode = ndNode.nextSibling;
  787.                 ndParent.removeChild(ndNode.previousSibling);
  788.             }
  789.  
  790.             var ndClone = ndEndNode.cloneNode(true);
  791.             ndNewNode.appendChild(ndClone);
  792.  
  793.             ndParent.replaceChild(ndNewNode, ndEndNode);
  794.         }
  795.     },
  796.  
  797.     Linkify_GetLinkLocation: function(nLinkType, sText)
  798.     {
  799.         if (this.aRegExpDesc[nLinkType] == "HTTP")
  800.         {
  801.             sText.match(this.aRegExpList[nLinkType]);
  802.  
  803.             var sProtocol = RegExp.$1;
  804.             var sAddress = RegExp.$2;
  805.             sProtocol = sProtocol.toLowerCase();
  806.  
  807.             var nUseProtocol = this.Linkify_InArray(sProtocol, this.aProtocol);
  808.             var sUseProtocol = "";
  809.             if (nUseProtocol > -1)
  810.             {
  811.                 sUseProtocol = this.aRecognizeProtocolAs[nUseProtocol];
  812.             }
  813.  
  814.             if (sUseProtocol == "")
  815.             {
  816.                 return sText;
  817.             }
  818.             else
  819.             {
  820.                 return sUseProtocol + sAddress;
  821.             }
  822.         }
  823.         else if (this.aRegExpDesc[nLinkType] == "WWW")
  824.         {
  825.             sText.match(this.aRegExpList[nLinkType]);
  826.  
  827.             var sSubdomain = RegExp.$6;
  828.             sSubdomain = sSubdomain.toLowerCase();
  829.  
  830.             var nUseProtocol = this.Linkify_InArray(sSubdomain, this.aSubdomain);
  831.             var sUseProtocol = "http";
  832.             if (nUseProtocol > -1)
  833.             {
  834.                 sUseProtocol = this.aRecognizeSubdomainAs[nUseProtocol];
  835.             }
  836.  
  837.             return sUseProtocol + "://" + sText;
  838.         }
  839.         else
  840.         {
  841.             return sText.replace(this.aRegExpList[nLinkType], this.aRegExpTarget[nLinkType]);
  842.         }
  843.  
  844.         return "";
  845.     },
  846.  
  847.     Linkify_Undo: function()
  848.     {
  849.         if (!this.bAllLinkified)
  850.         {
  851.             return false;
  852.         }
  853.  
  854.         this.bAllLinkified = false;
  855.  
  856.         var aAnchors = window._content.document.getElementsByTagName("a");
  857.         for (var ctr = aAnchors.length - 1; ctr >= 0; --ctr)
  858.         {
  859.             if (aAnchors[ctr].getAttribute("class") == "linkification-ext")
  860.             {
  861.                 while (aAnchors[ctr].childNodes.length > 0)
  862.                 {
  863.                     aAnchors[ctr].parentNode.insertBefore(aAnchors[ctr].removeChild(aAnchors[ctr].firstChild), aAnchors[ctr]);
  864.                 }
  865.                 aAnchors[ctr].parentNode.removeChild(aAnchors[ctr]);
  866.             }
  867.         }
  868.     },
  869.  
  870.     Linkify_GetPreferences: function()
  871.     {
  872.         this.bLinkify_HighlightText = false;
  873.         this.bLinkify_HighlightBG = false;
  874.         this.sLinkify_TextColor = "#006620";
  875.         this.sLinkify_BackgroundColor = "#FFF9AB";
  876.         this.bLinkify_Toggle = true;
  877.         this.bLinkify_DoubleClick = true;
  878.         this.bLinkify_OnClick = true;
  879.         this.bLinkify_Popup = false;
  880.         this.bLinkify_OpenInTab = false;
  881.         this.bLinkify_OpenTabInBG = false;
  882.         this.bLinkify_SuppressReferer = true;
  883.         this.bLinkify_LinkifyImages = true;
  884.         this.bLinkify_HTTP = true;
  885.         this.bLinkify_Email = true;
  886.         this.bLinkify_WWW = true;
  887.         this.bLinkify_IP = true;
  888.         this.bLinkify_Other = true;
  889.         this.sLinkify_TextProtocolList = "h..p:http,h...s:https,f.p:ftp,news:news,nntp:nntp,telnet:telnet";
  890.         this.sLinkify_SubdomainProtocolList = "www:http,ftp:ftp";
  891.         this.sLinkify_SiteList = "localhost,.google.com";
  892.         this.sLinkify_ExcludeTagList = "a,script,select,option,textarea";
  893.         this.sLinkify_SpaceTagList = "br,table,tbody,tr,td,p,div,input,ul,ol,li";
  894.         this.bLinkify_CharLimitEnabled = true;
  895.         this.nLinkify_CharLimit = 15000;
  896.  
  897.         var sCustomRegExp = "";
  898.         var sCustomRegExpDesc = "";
  899.         var sCustomRegExpTarget = "";
  900.         var bCustomCase = false;
  901.  
  902.         if (this.prefService.prefHasUserValue('Linkify_HighlightText'))
  903.         {
  904.             this.bLinkify_HighlightText = this.prefService.getBoolPref('Linkify_HighlightText');
  905.         }
  906.         if (this.prefService.prefHasUserValue('Linkify_TextColor'))
  907.         {
  908.             this.sLinkify_TextColor = this.prefService.getCharPref('Linkify_TextColor');
  909.         }
  910.         if (this.prefService.prefHasUserValue('Linkify_HighlightBG'))
  911.         {
  912.             this.bLinkify_HighlightBG = this.prefService.getBoolPref('Linkify_HighlightBG');
  913.         }
  914.         if (this.prefService.prefHasUserValue('Linkify_BackgroundColor'))
  915.         {
  916.             this.sLinkify_BackgroundColor = this.prefService.getCharPref('Linkify_BackgroundColor');
  917.         }
  918.         if (this.prefService.prefHasUserValue('Linkify_Toggle'))
  919.         {
  920.             this.bLinkify_Toggle = this.prefService.getBoolPref('Linkify_Toggle');
  921.         }
  922.         if (this.prefService.prefHasUserValue('Linkify_DoubleClick'))
  923.         {
  924.             this.bLinkify_DoubleClick = this.prefService.getBoolPref('Linkify_DoubleClick');
  925.         }
  926.         if (this.prefService.prefHasUserValue('Linkify_OnClick'))
  927.         {
  928.             this.bLinkify_OnClick = this.prefService.getBoolPref('Linkify_OnClick');
  929.         }
  930.         if (this.prefService.prefHasUserValue('Linkify_Popup_Toggle'))
  931.         {
  932.             this.bLinkify_Popup = this.prefService.getBoolPref('Linkify_Popup_Toggle');
  933.         }
  934.         if (this.prefService.prefHasUserValue('Linkify_Custom'))
  935.         {
  936.             this.bLinkify_Custom = this.prefService.getCharPref('Linkify_Custom');
  937.         }
  938.         if (this.prefService.prefHasUserValue('Linkify_CustomCase'))
  939.         {
  940.             bCustomCase = this.prefService.getBoolPref('Linkify_CustomCase');
  941.         }
  942.         if (this.prefService.prefHasUserValue('Linkify_CustomRegExp'))
  943.         {
  944.             sCustomRegExp = this.prefService.getCharPref('Linkify_CustomRegExp');
  945.         }
  946.         if (this.prefService.prefHasUserValue('Linkify_CustomTarget'))
  947.         {
  948.             sCustomRegExpTarget = this.prefService.getCharPref('Linkify_CustomTarget');
  949.         }
  950.         if (this.prefService.prefHasUserValue('Linkify_OpenInTab'))
  951.         {
  952.             this.bLinkify_OpenInTab = this.prefService.getBoolPref('Linkify_OpenInTab');
  953.         }
  954.         if (this.prefService.prefHasUserValue('Linkify_OpenTabInBG'))
  955.         {
  956.             this.bLinkify_OpenTabInBG = this.prefService.getBoolPref('Linkify_OpenTabInBG');
  957.         }
  958.         if (this.prefService.prefHasUserValue('Linkify_SuppressReferer'))
  959.         {
  960.             this.bLinkify_SuppressReferer = this.prefService.getBoolPref('Linkify_SuppressReferer');
  961.         }
  962.         if (this.prefService.prefHasUserValue('Linkify_LinkifyImages'))
  963.         {
  964.             this.bLinkify_LinkifyImages = this.prefService.getBoolPref('Linkify_LinkifyImages');
  965.         }
  966.         if (this.prefService.prefHasUserValue('Linkify_HTTP'))
  967.         {
  968.             this.bLinkify_HTTP = this.prefService.getBoolPref('Linkify_HTTP');
  969.         }
  970.         if (this.prefService.prefHasUserValue('Linkify_Email'))
  971.         {
  972.             this.bLinkify_Email = this.prefService.getBoolPref('Linkify_Email');
  973.         }
  974.         if (this.prefService.prefHasUserValue('Linkify_WWW'))
  975.         {
  976.             this.bLinkify_WWW = this.prefService.getBoolPref('Linkify_WWW');
  977.         }
  978.         if (this.prefService.prefHasUserValue('Linkify_IP'))
  979.         {
  980.             this.bLinkify_IP = this.prefService.getBoolPref('Linkify_IP');
  981.         }
  982.         if (this.prefService.prefHasUserValue('Linkify_Other'))
  983.         {
  984.             this.bLinkify_Other = this.prefService.getBoolPref('Linkify_Other');
  985.         }
  986.         if (this.prefService.prefHasUserValue('Linkify_TextProtocolList'))
  987.         {
  988.             this.sLinkify_TextProtocolList = this.prefService.getCharPref('Linkify_TextProtocolList');
  989.         }
  990.         if (this.prefService.prefHasUserValue('Linkify_SubdomainProtocolList'))
  991.         {
  992.             this.sLinkify_SubdomainProtocolList = this.prefService.getCharPref('Linkify_SubdomainProtocolList');
  993.         }
  994.         if (this.prefService.prefHasUserValue('Linkify_SiteList'))
  995.         {
  996.             this.sLinkify_SiteList = this.prefService.getCharPref('Linkify_SiteList');
  997.         }
  998.         if (this.prefService.prefHasUserValue('Linkify_ExcludeTagList'))
  999.         {
  1000.             this.sLinkify_ExcludeTagList = this.prefService.getCharPref('Linkify_ExcludeTagList');
  1001.         }
  1002.         if (this.prefService.prefHasUserValue('Linkify_SpaceTagList'))
  1003.         {
  1004.             this.sLinkify_SpaceTagList = this.prefService.getCharPref('Linkify_SpaceTagList');
  1005.         }
  1006.         if (this.prefService.prefHasUserValue('Linkify_CharLimitEnabled'))
  1007.         {
  1008.             this.bLinkify_CharLimitEnabled = this.prefService.getBoolPref('Linkify_CharLimitEnabled');
  1009.         }
  1010.         if (this.prefService.prefHasUserValue('Linkify_CharLimit'))
  1011.         {
  1012.             this.nLinkify_CharLimit = this.prefService.getIntPref('Linkify_CharLimit');
  1013.         }
  1014.  
  1015.         if (sCustomRegExp.length > 0)
  1016.         {
  1017.             var sModifiers = "";
  1018.             if (!bCustomCase)
  1019.             {
  1020.                 sModifiers += "i";
  1021.             }
  1022.  
  1023.             this.aRegExpList[this.aRegExpList.length] = new RegExp(sCustomRegExp, sModifiers);
  1024.             this.aRegExpDesc[this.aRegExpDesc.length] = "Custom";
  1025.             this.aRegExpTarget[this.aRegExpTarget.length] = sCustomRegExpTarget;
  1026.         }
  1027.     },
  1028.  
  1029.     Linkify_ToggleSuppressReferer: function()
  1030.     {
  1031.         this.prefService.setBoolPref('Linkify_SuppressReferer', !this.bLinkify_SuppressReferer);
  1032.         this.bLinkify_SuppressReferer = !this.bLinkify_SuppressReferer;
  1033.     },
  1034.  
  1035.     Linkify_ToggleLinkify: function()
  1036.     {
  1037.         this.prefService.setBoolPref('Linkify_Toggle', !this.bLinkify_Toggle);
  1038.         this.bLinkify_Toggle = !this.bLinkify_Toggle;
  1039.     },
  1040.  
  1041.     Linkify_FromPopup: function()
  1042.     {
  1043.         if (this.bFromPopup)
  1044.         {
  1045.             return false;
  1046.         }
  1047.  
  1048.         this.bFromPopup = true;
  1049.         if (this.bAllLinkified)
  1050.         {
  1051.             this.Linkify_Undo();
  1052.             this.bAllLinkified = false;
  1053.         }
  1054.         else
  1055.         {
  1056.             this.Linkify_Process(window._content.document);
  1057.             this.bAllLinkified = true;
  1058.         }
  1059.         this.bFromPopup = false;
  1060.     },
  1061.  
  1062.     Linkify_ClickLink: function(sHREF, nButton, bFromAnchor)
  1063.     {
  1064.         if (bFromAnchor && !this.bLinkify_SuppressReferer && !this.bLinkify_OpenInTab)
  1065.         {
  1066.             return false;
  1067.         }
  1068.  
  1069.         var objReferer = getReferrer(window.document);
  1070.         if (this.bLinkify_SuppressReferer)
  1071.         {
  1072.             objReferer = null;
  1073.         }
  1074.  
  1075.         var ndBrowser = window.getBrowser();
  1076.  
  1077.         if (nButton == 1)
  1078.         {
  1079.             return true;
  1080.         }
  1081.  
  1082.         var sProtocol = sHREF.substr(0, sHREF.indexOf(":")).toLowerCase();
  1083.         if (((sProtocol != "http") && (sProtocol != "https") && (sProtocol != "ftp")) || (!this.bLinkify_OpenInTab))
  1084.         {
  1085.             ndBrowser.loadURI(sHREF, objReferer, null);
  1086.         }
  1087.         else
  1088.         {
  1089.             var objTab = ndBrowser.addTab(sHREF, objReferer, null);
  1090.             if (!this.bLinkify_OpenTabInBG)
  1091.             {
  1092.                 ndBrowser.selectedTab = objTab;
  1093.             }
  1094.         }
  1095.  
  1096.         return true;
  1097.     },
  1098.  
  1099.     Linkify_DoubleClickLink: function(objSelection)
  1100.     {
  1101.         if (!this.bLinkify_DoubleClick)
  1102.         {
  1103.             return false;
  1104.         }
  1105.  
  1106.         this.Linkify_GetBody(window._content.document);
  1107.  
  1108.  
  1109.         var objRange = document.createRange();
  1110.         objRange.setEnd(objSelection.anchorNode, objSelection.anchorOffset);
  1111.         objRange.setStart(this.ndBody, 0);
  1112.  
  1113.         var sPreText = objRange.toString();
  1114.         if (sPreText.match(/\s[^\s]*$/i))
  1115.         {
  1116.             var nWhiteSpace = sPreText.search(/\s[^\s]*$/i) + 1;
  1117.  
  1118.             if (nWhiteSpace == sPreText.length)
  1119.             {
  1120.                 sPreText = "";
  1121.             }
  1122.             else
  1123.             {
  1124.                 sPreText = sPreText.substr(nWhiteSpace);
  1125.             }
  1126.         }
  1127.  
  1128.         objRange.setEnd(this.ndBody, this.ndBody.childNodes.length);
  1129.         objRange.setStart(objSelection.anchorNode, objSelection.anchorOffset + 1);
  1130.  
  1131.         var sPostText = objRange.toString();
  1132.         if (sPostText.match(/\s/i))
  1133.         {
  1134.             var nWhiteSpace = sPostText.search(/\s/i);
  1135.             sPostText = sPostText.substr(0, nWhiteSpace);
  1136.         }
  1137.  
  1138.         var nPreLimit = sPreText.length;
  1139.         var nPostLimit = sPostText.length;
  1140.  
  1141.         var aGroupText = this.Linkify_GroupTextNodes(objSelection.anchorNode, objSelection.anchorOffset, nPreLimit, nPostLimit);
  1142.  
  1143.         if (!aGroupText)
  1144.         {
  1145.             return false;
  1146.         }
  1147.  
  1148.         var sText = "";
  1149.         for (var ctr = 0; ctr < aGroupText.length; ++ctr)
  1150.         {
  1151.             sText += aGroupText[ctr].nodeValue;
  1152.         }
  1153.  
  1154.         objRange.setStart(this.ndBody, 0);
  1155.         objRange.setEnd(aGroupText[0], 0);
  1156.  
  1157.         var nPreChars = objRange.toString().length;
  1158.  
  1159.         objRange.setEnd(objSelection.anchorNode, objSelection.anchorOffset);
  1160.  
  1161.         var nAnchorOffset = objRange.toString().length - nPreChars;
  1162.         var nTempLocation = 0;
  1163.         while (aMatch = sText.match(this.rRegExpAll))
  1164.         {
  1165.             var sMatch = aMatch[0];
  1166.             nTempLocation += sText.indexOf(sMatch);
  1167.  
  1168.             if ((nAnchorOffset < nTempLocation) || (nAnchorOffset > (nTempLocation + sMatch.length)))
  1169.             {
  1170.                 sText = sText.substr(sText.indexOf(sMatch) + sMatch.length);
  1171.                 nTempLocation += sMatch.length;
  1172.                 continue;
  1173.             }
  1174.  
  1175.             nLinkType = this.Linkify_GetLinkType(sMatch, true);
  1176.             if (nLinkType == -1)
  1177.             {
  1178.                 return false;
  1179.             }
  1180.  
  1181.             if (this.bAllLinkified)
  1182.             {
  1183.                 if (((this.aRegExpDesc[nLinkType] == "HTTP") && this.bLinkify_HTTP)
  1184.                 || ((this.aRegExpDesc[nLinkType] == "WWW") && this.bLinkify_WWW)
  1185.                 || ((this.aRegExpDesc[nLinkType] == "Other") && this.bLinkify_Other)
  1186.                 || ((this.aRegExpDesc[nLinkType] == "StandaloneIP") && this.bLinkify_IP)
  1187.                 || ((this.aRegExpDesc[nLinkType] == "Email") && this.bLinkify_Email))
  1188.                 {
  1189.                     return false;
  1190.                 }
  1191.             }
  1192.  
  1193.             var sLinkLocation = this.Linkify_GetLinkLocation(nLinkType, sMatch);
  1194.             if (sLinkLocation == "")
  1195.             {
  1196.                 return false;
  1197.             }
  1198.  
  1199.             return this.Linkify_ClickLink(sLinkLocation, 0, false);
  1200.         }
  1201.  
  1202.         return false;
  1203.     },
  1204.  
  1205.     Linkify_InitPopup: function()
  1206.     {
  1207.         var ndPopup = document.getElementById("linkifypopup");
  1208.  
  1209.         if (!ndPopup)
  1210.         {
  1211.             return false;
  1212.         }
  1213.  
  1214.         if (!this.bLinkify_Popup)
  1215.         {
  1216.             var ndParent = ndPopup.parentNode;
  1217.             ndParent.removeChild(ndPopup);
  1218.             return true;
  1219.         }
  1220.  
  1221.         ndPopup.setAttribute("label", "Unlinkify Text (Ctrl+Shift+L)");
  1222.         if (!this.bAllLinkified)
  1223.         {
  1224.             ndPopup.setAttribute("label", "Linkify Text (Ctrl+Shift+L)");
  1225.         }
  1226.     }
  1227. };
  1228.  
  1229. function Linkify_ClickWindow(e)
  1230. {
  1231.     var ndTarget = e.originalTarget;
  1232.  
  1233.     while ((ndTarget.nodeName.toLowerCase() != "a") && (ndTarget.nodeName != "#document"))
  1234.     {
  1235.         ndTarget = ndTarget.parentNode;
  1236.     }
  1237.  
  1238.     if (ndTarget.nodeName.toLowerCase() != "a")
  1239.     {
  1240.         return true;
  1241.     }
  1242.  
  1243.     var sHREF = ndTarget.getAttribute("href");
  1244.     var sClass = ndTarget.getAttribute("class");
  1245.     var sTagName = ndTarget.nodeName.toLowerCase();
  1246.  
  1247.     if ((sTagName != "a") || (sClass != "linkification-ext"))
  1248.     {
  1249.         return true;
  1250.     }
  1251.  
  1252.     if (((e.button == 0) || (e.button == 1)) && !e.shiftKey && !e.altKey && !e.ctrlKey)
  1253.     {
  1254.         var sProtocol = sHREF.substr(0, sHREF.indexOf(":")).toLowerCase();
  1255.         if ((sProtocol != "http") && (sProtocol != "https") && (sProtocol != "ftp"))
  1256.         {
  1257.             return true;
  1258.         }
  1259.  
  1260.         if (objLinkify.Linkify_ClickLink(sHREF, e.button, true))
  1261.         {
  1262.             markLinkVisited(sHREF, ndTarget);
  1263.             e.preventDefault();
  1264.         }
  1265.     }
  1266.  
  1267.     return true;
  1268. }
  1269.  
  1270. function Linkify_DoubleClickWindow(e)
  1271. {
  1272.     var ndDblClicked = e.originalTarget;
  1273.     if ((ndDblClicked.nodeName == "tab") || (ndDblClicked.nodeName == "xul:spacer") || (ndDblClicked.nodeName == "toolbar"))
  1274.     {
  1275.         return false;
  1276.     }
  1277.  
  1278.     var objSelection = window._content.getSelection();
  1279.     if (!objSelection || objSelection.isCollapsed || !objSelection.anchorNode || (objSelection.anchorNode.nodeName != "#text"))
  1280.     {
  1281.         return false;
  1282.     }
  1283.  
  1284.     objLinkify.Linkify_DoubleClickLink(objSelection);
  1285. }
  1286.  
  1287. function Linkify_LoadPopup()
  1288. {
  1289.     objLinkify.Linkify_InitPopup();
  1290.     return true;
  1291. }
  1292.  
  1293. function Linkify_LoadWindow(e)
  1294. {
  1295.     this.bFromPopup = false;
  1296.     objLinkify.Linkify_Init();
  1297.     objLinkify.Linkify_Process(e.originalTarget);
  1298.  
  1299.     var ndMainPopup = document.getElementById("contentAreaContextMenu");
  1300.     if (ndMainPopup)
  1301.     {
  1302.         ndMainPopup.addEventListener("popupshowing", Linkify_LoadPopup, true);
  1303.     }
  1304.  
  1305.     window.addEventListener("click", Linkify_ClickWindow, true);
  1306.     window.addEventListener("dblclick", Linkify_DoubleClickWindow, true);
  1307.  
  1308.     return true;
  1309. }
  1310.  
  1311. window.addEventListener('load', Linkify_LoadWindow, true);