home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 10218 / 10218.xpi / content / compiler.js next >
Encoding:
JavaScript  |  2010-02-09  |  27.1 KB  |  790 lines

  1. var videosurf_enhanced_enabled_sites_cache = {};
  2. var VS_VID_REGS                            = [];
  3. var VS_CACHED_RELATED_VIDEOS               = [];
  4. var VS_LOCAL_IMAGES                        = [];
  5.  
  6. var VideoSurfEnhancer = {
  7. prefManager: null,
  8.  
  9. getPrefManager: function(prefix) {
  10.     if(!prefix) {
  11.         prefix = "extensions.videosurf_enhanced.";
  12.     }
  13.     pm = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch).getBranch(prefix);
  14.     return pm;
  15. }, //getPrefManager
  16.  
  17. getPref: function(name, prefix) {
  18.     var pref = VideoSurfEnhancer.getPrefManager(prefix);
  19.     var prefType=pref.getPrefType(name);
  20.  
  21.     if (prefType==pref.PREF_INVALID) {
  22.         return null;
  23.     }
  24.  
  25.     switch (prefType) {
  26.         case pref.PREF_STRING: return pref.getCharPref(name);
  27.         case pref.PREF_BOOL: return pref.getBoolPref(name);
  28.         case pref.PREF_INT: return pref.getIntPref(name);
  29.     }
  30.  
  31. }, //getPref
  32.  
  33. setPref: function(name, value, prefix) {
  34.     var pref = VideoSurfEnhancer.getPrefManager(prefix);
  35.     var prefType=typeof(value);
  36.  
  37.     switch (prefType) {
  38.         case "string":
  39.         case "boolean":
  40.         break;
  41.         case "number":
  42.             if (value % 1 != 0) {
  43.                 throw new Error("Cannot set preference to non integral number");
  44.             }
  45.         break;
  46.         default:
  47.         throw new Error("Cannot set preference with datatype: " + prefType);
  48.     }
  49.  
  50.     // set new value using correct method
  51.     switch (prefType) {
  52.         case "string": pref.setCharPref(name, value); break;
  53.         case "boolean": pref.setBoolPref(name, value); break;
  54.         case "number": pref.setIntPref(name, Math.floor(value)); break;
  55.     }
  56.  
  57.     videosurf_enhanced_enabled_sites_cache = {} //Bust the cache when preferences change to be safe
  58. }, //setPref
  59.  
  60. getUrlContents: function(aUrl){
  61.     var ioService=Components.classes["@mozilla.org/network/io-service;1"]
  62.         .getService(Components.interfaces.nsIIOService);
  63.     var scriptableStream=Components
  64.         .classes["@mozilla.org/scriptableinputstream;1"]
  65.         .getService(Components.interfaces.nsIScriptableInputStream);
  66.  
  67.     var channel=ioService.newChannel(aUrl, null, null);
  68.     var input=channel.open();
  69.     scriptableStream.init(input);
  70.     var str=scriptableStream.read(input.available());
  71.     scriptableStream.close();
  72.     input.close();
  73.  
  74.     return str;
  75. },
  76.  
  77. apiLeakCheck: function(allowedCaller) {
  78.     var stack=Components.stack;
  79.  
  80.     var leaked=false;
  81.     do {
  82.         if (2==stack.language) {
  83.             if ('chrome'!=stack.filename.substr(0, 6) &&
  84.                 allowedCaller!=stack.filename
  85.             ) {
  86.                 leaked=true;
  87.                 break;
  88.             }
  89.         }
  90.  
  91.         stack=stack.caller;
  92.     } while (stack);
  93.  
  94.     return leaked;
  95. },
  96.  
  97. hitch: function(obj, meth) {
  98.     if (!obj[meth]) {
  99.         throw "method '" + meth + "' does not exist on object '" + obj + "'";
  100.     }
  101.  
  102.     var hitchCaller=Components.stack.caller.filename;
  103.     var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length);
  104.  
  105.     return function() {
  106.         if (VideoSurfEnhancer.apiLeakCheck(hitchCaller)) {
  107.             return;
  108.         }
  109.  
  110.         // make a copy of staticArgs (don't modify it because it gets reused for
  111.         // every invocation).
  112.         var args = staticArgs.concat();
  113.  
  114.         // add all the new arguments
  115.         for (var i = 0; i < arguments.length; i++) {
  116.             args.push(arguments[i]);
  117.         }
  118.  
  119.         // invoke the original function with the correct this obj and the combined
  120.         // list of static and dynamic arguments.
  121.         return obj[meth].apply(obj, args);
  122.     };
  123. },
  124.  
  125. addStyle: function(doc, css) {    
  126.     var head, style;
  127.     head = doc.getElementsByTagName('head')[0];
  128.  
  129.     if(!head) {
  130.         return;
  131.     }
  132.     
  133.     style = doc.createElement('style');
  134.     style.type = 'text/css';
  135.     style.innerHTML = css;
  136.     
  137.     head.appendChild(style);
  138. },
  139.  
  140. injectScript: function(script, unsafeContentWin) {
  141.     if (unsafeContentWin.wrappedJSObject) unsafeContentWin=unsafeContentWin.wrappedJSObject;
  142.     var unsafeLoc=new XPCNativeWrapper(unsafeContentWin, "location").location;
  143.     var url=new XPCNativeWrapper(unsafeLoc, "href").href;
  144.  
  145.     var sandbox, script, logger, xmlhttpRequester;
  146.     var safeWin=new XPCNativeWrapper(unsafeContentWin);
  147.  
  148.     sandbox=new Components.utils.Sandbox(safeWin);
  149.  
  150.     xmlhttpRequester=new vs_xmlhttpRequester(
  151.         unsafeContentWin, window//appSvc.hiddenDOMWindow
  152.     );
  153.  
  154.     sandbox.window=safeWin;
  155.     sandbox.document=sandbox.window.document;
  156.     sandbox.unsafeWindow=unsafeContentWin;
  157.  
  158.     sandbox.VS_VID_REGS              = VS_VID_REGS;
  159.     sandbox.VS_CACHED_RELATED_VIDEOS = VS_CACHED_RELATED_VIDEOS;
  160.     sandbox.VS_LOCAL_IMAGES          = VS_LOCAL_IMAGES;
  161.  
  162.     sandbox.VS_getPref = VideoSurfEnhancer.getPref;
  163.     sandbox.VS_setPref = VideoSurfEnhancer.setPref;
  164.     sandbox.VS_getUrlContents = VideoSurfEnhancer.getUrlContents;
  165.     sandbox.VS_gBrowser = gBrowser;
  166.     sandbox.VS_addStyle=function(css) { VideoSurfEnhancer.addStyle(sandbox.document, css) };
  167.     sandbox.VS_xmlhttpRequest=VideoSurfEnhancer.hitch( xmlhttpRequester, "contentStartRequest" );
  168.     sandbox.__proto__=sandbox.window;
  169.  
  170.     sandbox.VS_isVideoPageUrl = VideoSurfEnhancer.isVideoPageUrl;
  171.  
  172.     try {
  173.         this.evalInSandbox(
  174.             "(function(){"+script+"})()",
  175.             url,
  176.             sandbox);
  177.     } catch (e) {
  178.         var e2=new Error(typeof e=="string" ? e : e.message);
  179.         e2.fileName=script.filename;
  180.         e2.lineNumber=0;
  181.         //GM_logError(e2);
  182.         alert(e2);
  183.     }
  184.     return sandbox;
  185. },
  186.  
  187. evalInSandbox: function(code, codebase, sandbox) {
  188.    if (Components.utils && Components.utils.Sandbox) {
  189.        // DP beta+
  190.        Components.utils.evalInSandbox(code, sandbox);
  191.    } else if (Components.utils && Components.utils.evalInSandbox) {
  192.        // DP alphas
  193.        Components.utils.evalInSandbox(code, codebase, sandbox);
  194.    } else if (Sandbox) {
  195.        // 1.0.x
  196.        evalInSandbox(code, sandbox, codebase);
  197.    } else {
  198.        throw new Error("Could not create sandbox.");
  199.    }
  200. },
  201.  
  202. getActiveSite: function(url) {
  203.     if(!url) {
  204.         var document = gBrowser.selectedBrowser.contentDocument;
  205.         var url = document.location.href;
  206.     }
  207.  
  208.     var activeSite = null;
  209.     var enabled = false;
  210.     var summaries_enabled = false;
  211.     var related_enabled = false;
  212.  
  213.     if(videosurf_enhanced_enabled_sites_cache[url]) {
  214.         return videosurf_enhanced_enabled_sites_cache[url]; //Use this so switching back and forth between tabs and refreshing pages has no cost
  215.     }
  216.     else {
  217.         var activeSites = VideoSurfEnhancer.getPref("enabled_sites");
  218.         var activeSitesSummaries = VideoSurfEnhancer.getPref("search_sites_summaries_enabled");
  219.         var activeSitesRelated = VideoSurfEnhancer.getPref("search_sites_related_enabled");
  220.  
  221.         var sites = VideoSurfEnhancer.getPref("sites_info").split(",");
  222.         for(var i = 0 ; i < sites.length ; i++) {
  223.             var site = sites[i].split("||");
  224.             var urlStructure = site[2];
  225.             var re = new RegExp(urlStructure);
  226.             if(re.test(url)) {                
  227.                 activeSite = sites[i];
  228.                 enabled = VideoSurfEnhancer.checkListPresence(activeSites, site[0]);
  229.                 summaries_enabled = VideoSurfEnhancer.checkListPresence(activeSitesSummaries, site[0]);
  230.                 related_enabled = VideoSurfEnhancer.checkListPresence(activeSitesRelated, site[0]);
  231.                 break;
  232.             }
  233.         }
  234.         
  235.         videosurf_enhanced_enabled_sites_cache[url] = {
  236.             "active_site"           : activeSite,
  237.             "slug"                  : activeSite ? activeSite.split("||")[0] : null,
  238.             "site_enabled"          : enabled, 
  239.             "summaries_enabled"     : summaries_enabled, 
  240.             "related_enabled"       : related_enabled, 
  241.             "is_generic_video_page" : url && VideoSurfEnhancer.isVideoPageUrl(url) && url.indexOf("videosurf.com/") == -1
  242.         };
  243.         
  244.         return videosurf_enhanced_enabled_sites_cache[url];
  245.     }
  246. },
  247.  
  248. go: function(e) {
  249.     if(e.originalTarget instanceof HTMLDocument && !e.originalTarget.VideoSurfEnhanced && !e.originalTarget.defaultView.frameElement) {
  250.  
  251.         var script        = "";        
  252.         var as            = VideoSurfEnhancer.getActiveSite(e.target.location.href);        
  253.         var isVideoPage   = as.is_generic_video_page && VideoSurfEnhancer.getPref("external_site_related_videos");
  254.         var isSpecialPage = (as['active_site'] != null && as['site_enabled']);
  255.  
  256.         VideoSurfEnhancer.setIconDisplay();    
  257.         
  258.         //var ConsSrv = Components.classes['@mozilla.org/consoleservice;1'].getService(Components.interfaces.nsIConsoleService);
  259.         //ConsSrv.logStringMessage(e.originalTarget);
  260.         
  261.         if(isSpecialPage) {
  262.             activeSite = as['active_site'];
  263.             if(activeSite == null) {
  264.                 activeSite = "embedded_video_summaries||||||"; //Yea yea, this is messy
  265.             }
  266.  
  267.             script += "VS_ACTIVE_SITE                   = '"  + activeSite              + "';";
  268.             script += "VS_ACTIVE_SITE_ENABLED           = "   + as['site_enabled']      + ";";
  269.             script += "VS_ACTIVE_SITE_SUMMARIES_ENABLED = "   + as['summaries_enabled'] + ";";
  270.             script += "VS_ACTIVE_SITE_RELATED_ENABLED   = "   + as['related_enabled']   + ";";            
  271.         }
  272.  
  273.         script += "VS_IS_VIDEO_PAGE   = " + isVideoPage   + ";";
  274.         script += "VS_IS_SPECIAL_PAGE = " + isSpecialPage + ";";
  275.  
  276.         if(isVideoPage || isSpecialPage) {
  277.             script += VideoSurfEnhancer.getUrlContents('chrome://videosurf_enhanced/content/jquery-1.3.2.min.js');
  278.             script += VideoSurfEnhancer.getUrlContents('chrome://videosurf_enhanced/content/video_summary.js');
  279.             script += VideoSurfEnhancer.getUrlContents('chrome://videosurf_enhanced/content/go.js'); //Do most of the work in here so we can develop quickly without restarting FF            
  280.         }
  281.             
  282.         VideoSurfEnhancer.injectScript(script, e.target.defaultView);
  283.         e.originalTarget.VideoSurfEnhanced = true;
  284.     }
  285. },
  286.  
  287. isVideoPageUrl: function(urlToValidate) {
  288.     url = VideoSurfEnhancer.cleanRedirectURL(urlToValidate.toLowerCase());
  289.  
  290.     var parts = VideoSurfEnhancer.parse_url(url);
  291.     
  292.     try {
  293.         var host  = VideoSurfEnhancer.explode('.', parts.host.replace(/\.go\./, 'go.'));
  294.         var p     = host.length;
  295.     
  296.         for(var i = p - 2; i >= 0 && p[i] != 'www'; i--) {
  297.             if(VS_VID_REGS[host[i]]) {
  298.                 for(var j = 0; j < VS_VID_REGS[host[i]]['expressions'].length; j++) {                
  299.                     if(VS_VID_REGS[host[i]]['expressions'][j]['regexp'].test(url)) {
  300.                         return true;
  301.                     }
  302.                 }
  303.             }
  304.         }
  305.     }
  306.     catch(e) {}
  307.  
  308.     return false;
  309. },
  310.  
  311. cleanRedirectURL: function(urlString) {
  312.     if(VideoSurfEnhancer.substr_count(urlString, 'http') > 1) {
  313.         var url = VideoSurfEnhancer.explode('http', urlString);
  314.         var knownRedirectors = [
  315.             'google',
  316.             'yahoo'
  317.         ];
  318.         
  319.         for(var index in knownRedirectors) {        
  320.             if(VideoSurfEnhancer.substr_count(url[1], knownRedirectors[index]) > 0) {
  321.                 return 'http' + VideoSurfEnhancer.urldecode(url[2]);                
  322.             }
  323.         }
  324.     }
  325.  
  326.     return urlString;
  327. },
  328.  
  329. parse_url: function(str, component) {
  330.     return {host:VideoSurfEnhancer.explode('/', str)[2]};
  331. },
  332.  
  333. substr_count: function(haystack, needle, offset, length) {
  334.     // Returns the number of times a substring occurs in the string  
  335.     // 
  336.     // version: 909.322
  337.     // discuss at: http://phpjs.org/functions/substr_count
  338.     // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  339.     // +   bugfixed by: Onno Marsman
  340.     // *     example 1: substr_count('Kevin van Zonneveld', 'e');
  341.     // *     returns 1: 3
  342.     // *     example 2: substr_count('Kevin van Zonneveld', 'K', 1);
  343.     // *     returns 2: 0
  344.     // *     example 3: substr_count('Kevin van Zonneveld', 'Z', 0, 10);
  345.     // *     returns 3: false
  346.     var pos = 0, cnt = 0;
  347.  
  348.     haystack += '';
  349.     needle += '';
  350.     if (isNaN(offset)) {offset = 0;}
  351.     if (isNaN(length)) {length = 0;}
  352.     offset--;
  353.  
  354.     while ((offset = haystack.indexOf(needle, offset+1)) != -1){
  355.         if (length > 0 && (offset+needle.length) > length){
  356.             return false;
  357.         } else{
  358.             cnt++;
  359.         }
  360.     }
  361.  
  362.     return cnt;
  363. },
  364.  
  365. explode: function(delimiter, string, limit) {
  366.     return string.split(delimiter);
  367. },
  368.  
  369. urldecode: function(str) {
  370.     // Decodes URL-encoded string  
  371.     // 
  372.     // version: 909.322
  373.     // discuss at: http://phpjs.org/functions/urldecode
  374.     // +   original by: Philip Peterson
  375.     // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  376.     // +      input by: AJ
  377.     // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  378.     // +   improved by: Brett Zamir (http://brett-zamir.me)
  379.     // +      input by: travc
  380.     // +      input by: Brett Zamir (http://brett-zamir.me)
  381.     // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  382.     // +   improved by: Lars Fischer
  383.     // +      input by: Ratheous
  384.     // +   improved by: Orlando
  385.     // %        note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
  386.     // *     example 1: urldecode('Kevin+van+Zonneveld%21');
  387.     // *     returns 1: 'Kevin van Zonneveld!'
  388.     // *     example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
  389.     // *     returns 2: 'http://kevin.vanzonneveld.net/'
  390.     // *     example 3: urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
  391.     // *     returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
  392.  
  393.     var hash_map = {}, ret = str.toString(), unicodeStr='', hexEscStr='';
  394.  
  395.     var replacer = function (search, replace, str) {
  396.         var tmp_arr = [];
  397.         tmp_arr = str.split(search);
  398.         return tmp_arr.join(replace);
  399.     };
  400.  
  401.     // The hash_map is identical to the one in urlencode.
  402.     hash_map["'"]   = '%27';
  403.     hash_map['(']   = '%28';
  404.     hash_map[')']   = '%29';
  405.     hash_map['*']   = '%2A';
  406.     hash_map['~']   = '%7E';
  407.     hash_map['!']   = '%21';
  408.     hash_map['%20'] = '+';
  409.     hash_map['\u00DC'] = '%DC';
  410.     hash_map['\u00FC'] = '%FC';
  411.     hash_map['\u00C4'] = '%D4';
  412.     hash_map['\u00E4'] = '%E4';
  413.     hash_map['\u00D6'] = '%D6';
  414.     hash_map['\u00F6'] = '%F6';
  415.     hash_map['\u00DF'] = '%DF';
  416.     hash_map['\u20AC'] = '%80';
  417.     hash_map['\u0081'] = '%81';
  418.     hash_map['\u201A'] = '%82';
  419.     hash_map['\u0192'] = '%83';
  420.     hash_map['\u201E'] = '%84';
  421.     hash_map['\u2026'] = '%85';
  422.     hash_map['\u2020'] = '%86';
  423.     hash_map['\u2021'] = '%87';
  424.     hash_map['\u02C6'] = '%88';
  425.     hash_map['\u2030'] = '%89';
  426.     hash_map['\u0160'] = '%8A';
  427.     hash_map['\u2039'] = '%8B';
  428.     hash_map['\u0152'] = '%8C';
  429.     hash_map['\u008D'] = '%8D';
  430.     hash_map['\u017D'] = '%8E';
  431.     hash_map['\u008F'] = '%8F';
  432.     hash_map['\u0090'] = '%90';
  433.     hash_map['\u2018'] = '%91';
  434.     hash_map['\u2019'] = '%92';
  435.     hash_map['\u201C'] = '%93';
  436.     hash_map['\u201D'] = '%94';
  437.     hash_map['\u2022'] = '%95';
  438.     hash_map['\u2013'] = '%96';
  439.     hash_map['\u2014'] = '%97';
  440.     hash_map['\u02DC'] = '%98';
  441.     hash_map['\u2122'] = '%99';
  442.     hash_map['\u0161'] = '%9A';
  443.     hash_map['\u203A'] = '%9B';
  444.     hash_map['\u0153'] = '%9C';
  445.     hash_map['\u009D'] = '%9D';
  446.     hash_map['\u017E'] = '%9E';
  447.     hash_map['\u0178'] = '%9F';
  448.     hash_map['\u00C6'] = '%C3%86';
  449.     hash_map['\u00D8'] = '%C3%98';
  450.     hash_map['\u00C5'] = '%C3%85';
  451.  
  452.     for (unicodeStr in hash_map) {
  453.         hexEscStr = hash_map[unicodeStr]; // Switch order when decoding
  454.         ret = replacer(hexEscStr, unicodeStr, ret); // Custom replace. No regexing
  455.     }
  456.  
  457.     // End with decodeURIComponent, which most resembles PHP's encoding functions
  458.     ret = decodeURIComponent(ret);
  459.  
  460.     return ret;
  461. },
  462.  
  463. convertImgToDataUrl: function(imagePath) {
  464.     if(!imagePath) {
  465.         return null;
  466.     }
  467.     
  468.     try{
  469.         var ioserv  = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  470.           var channel = ioserv.newChannel(imagePath, 0, null);
  471.           var stream  = channel.open();
  472.  
  473.           if(channel instanceof Components.interfaces.nsIHttpChannel && channel.responseStatus != 200) {
  474.             return null;
  475.         }
  476.  
  477.           var bstream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
  478.           bstream.setInputStream(stream);
  479.  
  480.           var size      = 0;
  481.           var file_data = "";
  482.           while(size = bstream.available()) {
  483.             file_data += bstream.readBytes(size);
  484.           }
  485.  
  486.           var data = btoa(file_data);
  487.           return "data:image;base64," + data;
  488.     }
  489.     catch(e) {
  490.         
  491.     }
  492.     
  493.     return null;
  494. },
  495.  
  496. setIconDisplay: function() {
  497.     var as = VideoSurfEnhancer.getActiveSite();
  498.     var enhanceable = (as != null && (as['active_site'] != null || as.is_generic_video_page)) ? true : false;
  499.     var disabled = (as != null && as['active_site'] != null && !as['site_enabled']) ? true : false;
  500.     var icon = document.getElementById("videosurf_enhanced-status-bar-icon");
  501.     icon.className = "statusbarpanel-iconic";
  502.     icon.setAttribute("src", "chrome://videosurf_enhanced/content/images/favicon_16.gif");
  503.     if(!enhanceable) {
  504.         icon.className += " not-supported ";
  505.         icon.setAttribute("src", "chrome://videosurf_enhanced/content/images/favicon_16_desaturated.gif");
  506.     }
  507.     if(disabled) {
  508.         icon.className += " disabled ";
  509.     }
  510.     if(VideoSurfEnhancer.getPref("hide_status_bar_icon")) {
  511.         icon.className = " hidden ";
  512.     }
  513. },
  514.  
  515. openMorePreferences: function() {
  516.     window.openDialog("chrome://videosurf_enhanced/content/options.xul", "videosurf_enhanced-prefs",  "centerscreen,chrome,modal,resizable");
  517. },
  518.  
  519. toggleExtensionEnabled: function() {
  520.     var enabled_sites = VideoSurfEnhancer.getPref('enabled_sites');
  521.     var as = VideoSurfEnhancer.getActiveSite();
  522.     VideoSurfEnhancer.setPref("enabled_sites", VideoSurfEnhancer.toggleListPresence(enabled_sites, as['slug']));
  523.     VideoSurfEnhancer.setIconDisplay();
  524. },
  525.  
  526. toggleSummariesEnabled: function() {
  527.     var summaries_enabled = VideoSurfEnhancer.getPref('search_sites_summaries_enabled');
  528.     var as = VideoSurfEnhancer.getActiveSite();
  529.     VideoSurfEnhancer.setPref("search_sites_summaries_enabled", VideoSurfEnhancer.toggleListPresence(summaries_enabled, as['slug']));
  530.     VideoSurfEnhancer.setIconDisplay();
  531. },
  532.  
  533. toggleRelatedEnabled: function() {
  534.     var related_enabled = VideoSurfEnhancer.getPref('search_sites_related_enabled');
  535.     var as = VideoSurfEnhancer.getActiveSite();
  536.     VideoSurfEnhancer.setPref("search_sites_related_enabled", VideoSurfEnhancer.toggleListPresence(related_enabled, as['slug']));
  537.     VideoSurfEnhancer.setIconDisplay();
  538. },
  539.  
  540. toggleRelatedVideoTabEnabled: function() {
  541.     var related_tab_enabled = VideoSurfEnhancer.getPref('external_site_related_videos');
  542.     VideoSurfEnhancer.setPref("external_site_related_videos", !related_tab_enabled);
  543.     VideoSurfEnhancer.setIconDisplay();
  544. },
  545.  
  546. toggleListPresence: function(list, s) {
  547.     //Adds or removes s from the comma separated list 
  548.     var newArr = [];
  549.     var arr = list.split(",");
  550.     var found = false;
  551.     for(i = 0 ; i < arr.length ; i++) {
  552.         if(arr[i] == s) {
  553.             found = true;    
  554.         } else {
  555.             if(arr[i].length > 0) {
  556.                 newArr[newArr.length] = arr[i];
  557.             }
  558.         }
  559.     }
  560.     if(!found) {
  561.         newArr[newArr.length] = s;
  562.     }
  563.     return newArr.join(",");
  564. },
  565.  
  566. checkListPresence: function(list, s) {
  567.     var arr = list.split(",");
  568.     var found = false;
  569.     for(i = 0 ; i < arr.length ; i++) {
  570.         if(arr[i] == s) {
  571.             found = true;
  572.             break;
  573.         }
  574.     }
  575.     return found;    
  576. },
  577.  
  578. updateContextMenuState: function() {
  579.     //It seems setAttribute is necessary here... just doing ().checked = true does not work
  580.     var summaries_option = document.getElementById("videosurf_enhanced-context-menu-addsummaries");
  581.     var related_option = document.getElementById("videosurf_enhanced-context-menu-addrelated");
  582.     var enabled_option = document.getElementById("videosurf_enhanced-context-menu-enabled");
  583.     var not_supported_option = document.getElementById("videosurf_enhanced-context-menu-not-supported");
  584.     var generic_video_option = document.getElementById("videosurf_enhanced-context-menu-generic-video");
  585.  
  586.     summaries_option.setAttribute("checked", "true");
  587.     related_option.setAttribute("checked", "true");
  588.     related_option.className = "";
  589.  
  590.     var as = VideoSurfEnhancer.getActiveSite();
  591.     if(as && as['slug'] != null) {
  592.         enabled_option.setAttribute("label", "Enable for "+as['active_site'].split("||")[1]+"");
  593.  
  594.         enabled_option.setAttribute("checked", as['site_enabled'] ? "true" : "false");
  595.         summaries_option.setAttribute("checked", as['summaries_enabled'] ? "true" : "false");
  596.         related_option.setAttribute("checked", as['related_enabled'] ? "true" : "false");
  597.  
  598.         summaries_option.setAttribute("disabled", as['site_enabled'] ? "false" : "true");
  599.         related_option.setAttribute("disabled", as['site_enabled'] ? "false" : "true");
  600.         
  601.         not_supported_option.className = "hidden";
  602.         not_supported_option.setAttribute("disabled", "true");
  603.         document.getElementById("videosurf_enhanced-context-menu-separator-2").className = "visible";
  604.         enabled_option.className = "visible";
  605.         summaries_option.className = "visible";
  606.         related_option.className = "visible";
  607.  
  608.         if(!VideoSurfEnhancer.checkListPresence(VideoSurfEnhancer.getPref("sites_summaries_supported"), as['slug'])) {
  609.             //summaries_option.className = "hidden";
  610.             summaries_option.setAttribute("checked", "false");
  611.             summaries_option.setAttribute("disabled", "true");
  612.         }
  613.  
  614.         if(!VideoSurfEnhancer.checkListPresence(VideoSurfEnhancer.getPref("sites_related_supported"), as['slug'])) {
  615.             //related_option.className = "hidden";
  616.             related_option.setAttribute("checked", "false");
  617.             related_option.setAttribute("disabled", "true");
  618.         }
  619.  
  620.     } else {
  621.         if(!as.is_generic_video_page) {
  622.             not_supported_option.className = "visible";
  623.             not_supported_option.setAttribute("disabled", "true");
  624.         }
  625.         document.getElementById("videosurf_enhanced-context-menu-separator-2").className = "hidden";
  626.         enabled_option.className = "hidden";
  627.         summaries_option.className = "hidden";
  628.         related_option.className = "hidden";
  629.     }
  630.  
  631.     if(as.is_generic_video_page) {
  632.         not_supported_option.className = "hidden";
  633.         generic_video_option.setAttribute("checked", VideoSurfEnhancer.getPref("external_site_related_videos"));
  634.         generic_video_option.className = "visible";
  635.     } else {
  636.         generic_video_option.className = "hidden";
  637.     }
  638. },
  639.  
  640. load: function() {
  641.     if(gBrowser && !gBrowser.VideoSurfEnhanced) {
  642.         gBrowser.addEventListener("DOMContentLoaded", VideoSurfEnhancer.go, true);
  643.  
  644.         gBrowser.tabContainer.addEventListener("TabSelect", VideoSurfEnhancer.setIconDisplay, false);
  645.  
  646.         var gExtensionManager = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);
  647.         var current = gExtensionManager.getItemForID("videosurf_enhanced@videosurf.com").version;
  648.  
  649.         VideoSurfEnhancer.log('Current Version: ' + VideoSurfEnhancer.getPref("first_run_version"));
  650.         VideoSurfEnhancer.log('New Version: ' + current);
  651.         
  652.         if(VideoSurfEnhancer.getPref("first_run_version") != current) {            
  653.             VideoSurfEnhancer.log('Updating Preferences');
  654.             //Enabled any new sites that have been added
  655.             VideoSurfEnhancer.updatePreferences(parseFloat(VideoSurfEnhancer.getPref("first_run_version")));
  656.  
  657.             VideoSurfEnhancer.log('Setting Timeout');
  658.             //When FF remembers your previous tabs, this timeout is required to make this work.  Otherwise the tab never opens for some odd reason.  
  659.             setTimeout(function() {
  660.                 gBrowser.selectedTab = gBrowser.addTab("http://www.videosurf.com/videos-at-a-glance-"+current); //post-installation splash page
  661.             }, 1000);
  662.             
  663.             VideoSurfEnhancer.log('Updating Current Version');
  664.             //Update running version to the current one
  665.             VideoSurfEnhancer.setPref("first_run_version", current);            
  666.         }
  667.                 
  668.         //Load, convert, and cache regular expressions
  669.         var regularExpressionJSON = JSON.parse(VideoSurfEnhancer.getUrlContents("chrome://videosurf_enhanced/content/siteRegularExpressions.js"));
  670.         for(var siteID in regularExpressionJSON) {        
  671.             for(var regularExpressionIndex in regularExpressionJSON[siteID]['expressions']) {
  672.                 regularExpressionJSON[siteID]['expressions'][regularExpressionIndex]['regexp'] = new RegExp(
  673.                     regularExpressionJSON[siteID]['expressions'][regularExpressionIndex]['regexp'].substr(1, regularExpressionJSON[siteID]['expressions'][regularExpressionIndex]['regexp'].length -2)
  674.                 );
  675.             }
  676.         }
  677.         VS_VID_REGS = regularExpressionJSON;
  678.                 
  679.         //Load, convert, and cache images
  680.         var imageFiles = {
  681.             'arrow-down'           : 'chrome://videosurf_enhanced/content/images/related-images/arrow-down.png',
  682.             'arrow-left'           : 'chrome://videosurf_enhanced/content/images/related-images/arrow-left.png',
  683.             'arrow-right'          : 'chrome://videosurf_enhanced/content/images/related-images/arrow-right.png',
  684.             'arrow-up'             : 'chrome://videosurf_enhanced/content/images/related-images/arrow-up.png',
  685.             'container-background' : 'chrome://videosurf_enhanced/content/images/related-images/container-background.png',
  686.             'container-header'     : 'chrome://videosurf_enhanced/content/images/related-images/container-header.png',
  687.             'tab-closed'           : 'chrome://videosurf_enhanced/content/images/related-images/tab-closed.png',
  688.             'tab-loading-feedback' : 'chrome://videosurf_enhanced/content/images/related-images/tab-loading-feedback.gif',    
  689.             'tab-loading'          : 'chrome://videosurf_enhanced/content/images/related-images/tab-loading.png',
  690.             'tab-open'             : 'chrome://videosurf_enhanced/content/images/related-images/tab-open.png',
  691.         };
  692.         for(var imageID in imageFiles) {    
  693.             VS_LOCAL_IMAGES[imageID] = VideoSurfEnhancer.convertImgToDataUrl(imageFiles[imageID]);
  694.         }
  695.         
  696.         gBrowser.VideoSurfEnhanced = true; //make sure we only do this once, unnecessary?
  697.     }
  698. }, //load
  699.  
  700. updatePreferences: function(previousVersion) {
  701.     //Do not do anything if the extension have not been installed
  702.     VideoSurfEnhancer.log('Previous Version: ' + previousVersion);        
  703.     if(!previousVersion) {
  704.         return;
  705.     }
  706.  
  707.     //Check to see if user have changes summary settings
  708.     var isDefaultSummaries = VideoSurfEnhancer.getPrefManager().prefHasUserValue('search_sites_summaries_enabled');
  709.     VideoSurfEnhancer.log(isDefaultSummaries);
  710.     
  711.     //Check to see if user has changed related settings
  712.     var isDefaultRelated   = VideoSurfEnhancer.getPrefManager().prefHasUserValue('search_sites_related_enabled');
  713.     VideoSurfEnhancer.log(isDefaultRelated);
  714.  
  715.     //New sites added in their corasponding versions
  716.     var preferenceJSON = [
  717.         {
  718.             version : .66,
  719.             sites   : [
  720.                 {
  721.                     id      : 'riot',
  722.                     summary : true,
  723.                     related : true
  724.                 }
  725.             ]
  726.         },
  727.         {
  728.             version : .67,
  729.             sites   : [
  730.                 {
  731.                     id      : 'digg',
  732.                     summary : true,
  733.                     related : false
  734.                 },
  735.                 {
  736.                     id      : 'reddit',
  737.                     summary : true,
  738.                     related : false
  739.                 }
  740.             ]
  741.         },
  742.         {
  743.             version : .68,
  744.             sites   : [
  745.             ]
  746.         }        
  747.     ];
  748.  
  749.     for(newVersion in preferenceJSON) {
  750.         var currentVersion = preferenceJSON[newVersion];
  751.  
  752.         VideoSurfEnhancer.log(previousVersion);
  753.         VideoSurfEnhancer.log(currentVersion.version);
  754.  
  755.         if(currentVersion.version > previousVersion) {
  756.             for(var newSite in currentVersion.sites) {
  757.                 var currentSite = currentVersion.sites[newSite];
  758.                 
  759.                 if(isDefaultSummaries && currentSite.summary) {
  760.                     VideoSurfEnhancer.setPref("search_sites_summaries_enabled", VideoSurfEnhancer.toggleListPresence(VideoSurfEnhancer.getPref('search_sites_summaries_enabled'), currentSite.id));                    
  761.                 }
  762.  
  763.                 if(isDefaultRelated && currentSite.related) {
  764.                     VideoSurfEnhancer.setPref("search_sites_related_enabled", VideoSurfEnhancer.toggleListPresence(VideoSurfEnhancer.getPref('search_sites_related_enabled'), currentSite.id));                    
  765.                 }
  766.             }
  767.         }
  768.     }    
  769. }, //updatePreferences
  770.  
  771. unload: function() {
  772.     window.removeEventListener('load', VideoSurfEnhancer.load, false);
  773.     window.removeEventListener('unload', VideoSurfEnhancer.unload, false);
  774.     gBrowser.removeEventListener("DOMContentLoaded", VideoSurfEnhancer.go, false);
  775.     gBrowser.tabContainer.removeEventListener("TabSelect", VideoSurfEnhancer.setIconDisplay, false);
  776. }, //unload
  777.  
  778.  
  779. log: function(value) {
  780.     return;
  781.     
  782.     var ConsSrv = Components.classes['@mozilla.org/consoleservice;1'].getService(Components.interfaces.nsIConsoleService);    
  783.     ConsSrv.logStringMessage(value);    
  784. } //log
  785.  
  786. } //VideoSurfEnhancer
  787.  
  788. window.addEventListener('load', VideoSurfEnhancer.load, false);
  789. window.addEventListener('unload', VideoSurfEnhancer.unload, false);
  790.