home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / mozil06.zip / bin / chrome / messenger.jar / content / messenger / subscribe.js < prev    next >
Text File  |  2001-02-14  |  12KB  |  465 lines

  1. var gSubscribeTree = null;
  2. var okCallback = null;
  3. var gChangeTable = {};
  4. var gServerURI = null;
  5. var gSubscribableServer = null;
  6. var RDF = null;
  7. var gSubscribeDS = null;
  8. var gStatusBar = null;
  9. var gNameField = null;
  10. var gFolderDelimiter = ".";
  11. var gStatusFeedback = new nsMsgStatusFeedback;
  12.  
  13. // used for caching the tree children (in typedown)
  14. var lastTreeChildrenValue = null;
  15. var lastTreeChildren = null;
  16.  
  17.  
  18. function SetUpRDF()
  19. {
  20.     if (!RDF) {
  21.             RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService();
  22.             RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
  23.     }
  24.         
  25.     if (!gSubscribeDS) {
  26.         gSubscribeDS = RDF.GetDataSource("rdf:subscribe");
  27.     }
  28. }
  29.  
  30. function Stop()
  31. {
  32.     dump("xxx todo implement stop.\n");
  33. }
  34.  
  35. var Bundle = srGetStrBundle("chrome://messenger/locale/subscribe.properties");
  36.  
  37. function SetServerTypeSpecificTextValues()
  38. {
  39.     if (!gServerURI) return;
  40.  
  41.     var serverType = GetMsgFolderFromUri(gServerURI).server.type;
  42.     //dump("serverType="+serverType+"\n");
  43.     
  44.     /* set the server specific ui elements */
  45.     var element = document.getElementById("foldertextlabel");
  46.     var stringName = "foldertextfor-" + serverType;
  47.     var stringval = Bundle.GetStringFromName(stringName);
  48.     element.setAttribute('value',stringval);
  49.  
  50.     stringName = "foldersheaderfor-" + serverType;
  51.     stringval = Bundle.GetStringFromName(stringName);
  52.     element = document.getElementById("foldersheaderlabel");
  53.     element.setAttribute('value',stringval);
  54.  
  55.     // xxx todo, fix this hack
  56.     // qi the server to get a nsISubscribable server
  57.     // and ask it for the delimiter
  58.     if (serverType == "nntp") {
  59.         gFolderDelimiter = ".";
  60.     }
  61.     else {
  62.         gFolderDelimiter = "/";
  63.     }
  64. }
  65.  
  66. function onServerClick(event)
  67. {
  68.     var item = event.target;
  69.     gServerURI = item.id;
  70.     //dump("gServerURI="+gServerURI+"\n");
  71.  
  72.     SetServerTypeSpecificTextValues();
  73.     SetUpTree(false);
  74. }
  75.  
  76. function SetUpServerMenu()
  77. {
  78.     //dump("SetUpServerMenu()\n");
  79.  
  80.     var serverMenu = document.getElementById("serverMenu");
  81.     var menuitems = serverMenu.getElementsByAttribute("id", gServerURI);
  82.  
  83.     try {
  84.         //dump("gServerURI="+gServerURI+"\n");
  85.         //dump("menuitems="+menuitems+"\n");
  86.         //dump("menuitems[0]="+menuitems[0]+"\n");
  87.         //dump("serverMenu="+serverMenu+"\n");
  88.         serverMenu.selectedItem = menuitems[0];
  89.     }
  90.     catch (ex) {
  91.         dump("failed to set the selected server: " + ex + "\n");
  92.     }
  93.  
  94.     SetServerTypeSpecificTextValues();
  95. }
  96.  
  97. var MySubscribeListener = {
  98.     OnStopPopulating: function() {
  99.         // only re-root the tree, if it is null.
  100.         // otherwise, we are in here because we are populating
  101.         // a part of the tree
  102.  
  103.         var refValue = gSubscribeTree.getAttribute('ref');
  104.         //dump("ref = " + refValue + refValue.length + "\n");
  105.         if (refValue == "null") {
  106.             dump("root subscribe tree at: "+ gServerURI +"\n");
  107.             gSubscribeTree.setAttribute('ref',gServerURI);
  108.         }
  109.  
  110.         gStatusFeedback.ShowProgress(100);
  111.         gStatusFeedback.ShowStatusString(Bundle.GetStringFromName("doneString"));
  112.         gStatusBar.setAttribute("mode","normal");
  113.     }
  114. };
  115.  
  116. function SetUpTree(forceToServer)
  117. {
  118.     //dump("SetUpTree()\n");
  119.     
  120.     // forget the cached tree children
  121.     lastTreeChildrenValue = null;
  122.     lastTreeChildren = null;
  123.  
  124.     SetUpRDF();
  125.     
  126.     gStatusBar = document.getElementById('statusbar-icon');
  127.     gSubscribeTree.setAttribute('ref',null);
  128.  
  129.     if (!gServerURI) return;
  130.  
  131.     var folder = GetMsgFolderFromUri(gServerURI);
  132.     var server = folder.server;
  133.  
  134.     try {
  135.         gSubscribableServer = server.QueryInterface(Components.interfaces.nsISubscribableServer);
  136.  
  137.         gSubscribableServer.subscribeListener = MySubscribeListener;
  138.  
  139.         gStatusFeedback.ShowProgress(0);
  140.         gStatusFeedback.ShowStatusString(Bundle.GetStringFromName("pleaseWaitString"));
  141.         gStatusBar.setAttribute("mode","undetermined");
  142.  
  143.         gSubscribableServer.populateSubscribeDatasource(msgWindow, forceToServer);
  144.     }
  145.     catch (ex) {
  146.         dump("failed to populate subscribe ds: " + ex + "\n");
  147.     }
  148. }
  149.  
  150.  
  151. function SubscribeOnLoad()
  152. {
  153.     //dump("SubscribeOnLoad()\n");
  154.     
  155.     gSubscribeTree = document.getElementById('subscribetree');
  156.     gNameField = document.getElementById('namefield');
  157.  
  158.     msgWindow = Components.classes[msgWindowContractID].createInstance(Components.interfaces.nsIMsgWindow);
  159.     msgWindow.statusFeedback = gStatusFeedback;
  160.     msgWindow.SetDOMWindow(window);
  161.  
  162.     doSetOKCancel(subscribeOK,subscribeCancel);
  163.  
  164.     // look in arguments[0] for parameters
  165.     if (window.arguments && window.arguments[0]) {
  166.         if ( window.arguments[0].title ) {
  167.             top.window.title = window.arguments[0].title;
  168.         }
  169.         
  170.         if ( window.arguments[0].okCallback ) {
  171.             top.okCallback = window.arguments[0].okCallback;
  172.         }
  173.     }
  174.     
  175.     gServerURI = null;
  176.     if (window.arguments[0].preselectedURI) {
  177.         var uri = window.arguments[0].preselectedURI;
  178.         //dump("subscribe: got a uri," + uri + "\n");
  179.         var folder = GetMsgFolderFromUri(uri);
  180.         //dump("folder="+folder+"\n");
  181.         //dump("folder.server="+folder.server+"\n");
  182.         try {
  183.             gSubscribableServer = folder.server.QueryInterface(Components.interfaces.nsISubscribableServer);
  184.             gServerURI = folder.server.serverURI;
  185.         }
  186.         catch (ex) {
  187.             dump("not a subscribable server\n");
  188.             gSubscribableServer = null;
  189.             gServerURI = null;
  190.         }
  191.     }
  192.  
  193.     if (!gServerURI) {
  194.         //dump("subscribe: no uri\n");
  195.         dump("xxx todo:  use the default news server.  right now, I'm just using the first server\n");
  196.         var serverMenu = document.getElementById("serverMenu");
  197.         var menuitems = serverMenu.getElementsByTagName("menuitem");
  198.         
  199.         if (menuitems.length > 1) {
  200.             gServerURI = menuitems[1].id;
  201.         }
  202.         else {
  203.             dump("xxx todo none of your servers are subscribable\n");
  204.             dump("xxx todo fix this by disabling subscribe if no subscribable server or, add a CREATE SERVER button, like in 4.x\n");
  205.             return;
  206.         }
  207.     }
  208.  
  209.     SetUpServerMenu();
  210.     SetUpTree(false);
  211.  
  212.   
  213.   gNameField.focus();
  214. }
  215.  
  216. function subscribeOK()
  217. {
  218.     //dump("in subscribeOK()\n")
  219.     if (top.okCallback) {
  220.         top.okCallback(top.gServerURI,top.gChangeTable);
  221.     }
  222.     if (gSubscribableServer) {
  223.         gSubscribableServer.subscribeCleanup();
  224.     }
  225.     return true;
  226. }
  227.  
  228. function subscribeCancel()
  229. {
  230.     //dump("in subscribeCancel()\n");
  231.     Stop();
  232.     if (gSubscribableServer) {
  233.         gSubscribableServer.subscribeCleanup();
  234.     }
  235.     return true;
  236. }
  237.  
  238. function SetState(uri,name,state,stateStr)
  239. {
  240.     //dump("SetState(" + uri +"," + name + "," + state + "," + stateStr + ")\n");
  241.     if (!uri || !stateStr) return;
  242.  
  243.     try {
  244.         // xxx should we move this code into nsSubscribableServer.cpp?
  245.         var src = RDF.GetResource(uri, true);
  246.         var prop = RDF.GetResource("http://home.netscape.com/NC-rdf#Subscribed", true);
  247.         var oldLiteral = gSubscribeDS.GetTarget(src, prop, true);
  248.         //dump("oldLiteral="+oldLiteral+"\n");
  249.  
  250.         oldValue = oldLiteral.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  251.         //dump("oldLiteral.Value="+oldValue+"\n");
  252.         if (oldValue != stateStr) {
  253.             var newLiteral = RDF.GetLiteral(stateStr);
  254.             gSubscribeDS.Change(src, prop, oldLiteral, newLiteral);
  255.             StateChanged(name,state);
  256.         }
  257.     }
  258.     catch (ex) {
  259.         dump("failed: " + ex + "\n");
  260.     }
  261. }
  262.  
  263. function StateChanged(name,state)
  264. {
  265.     //dump("StateChanged(" + name + "," + state + ")\n");
  266.     //dump("start val=" +gChangeTable[name] + "\n");
  267.  
  268.     if (gChangeTable[name] == undefined) {
  269.         //dump(name+" not in table yet\n");
  270.         gChangeTable[name] = state;
  271.     }
  272.     else {
  273.         var oldValue = gChangeTable[name];
  274.         //dump(name+" already in table\n");
  275.         if (oldValue != state) {
  276.             gChangeTable[name] = undefined;
  277.         }
  278.     }
  279.  
  280.     //dump("end val=" +gChangeTable[name] + "\n");
  281. }
  282.  
  283. function SetSubscribeState(state)
  284. {
  285.   //dump("SetSubscribedState()\n");
  286.  
  287.   var stateStr;
  288.   if (state) {
  289.       stateStr = 'true';
  290.   }
  291.   else {
  292.     stateStr = 'false';
  293.   }
  294.  
  295.   try {
  296.     //dump("subscribe button clicked\n");
  297.     
  298.     var groupList = gSubscribeTree.selectedItems;
  299.     for (i=0;i<groupList.length;i++) {
  300.         group = groupList[i];
  301.         uri = group.getAttribute('id');
  302.         //dump(uri + "\n");
  303.         name = group.getAttribute('name');
  304.         //dump(name + "\n");
  305.         SetState(uri,name,state,stateStr);
  306.     }
  307.   }
  308.   catch (ex) {
  309.     dump("SetSubscribedState failed:  " + ex + "\n");
  310.   }
  311. }
  312.  
  313. function ReverseStateFromNode(node)
  314. {
  315.     var stateStr;
  316.     var state;
  317.  
  318.     if (node.getAttribute('Subscribed') == "true") {
  319.         stateStr = "false";
  320.         state = false;
  321.     }
  322.     else {
  323.         stateStr = "true";
  324.         state = true;
  325.     }
  326.     
  327.     var uri = node.getAttribute('id');
  328.     var    name = node.getAttribute('name');
  329.     SetState(uri, name, state, stateStr);
  330. }
  331.  
  332. function ReverseState(uri)
  333. {
  334.     //dump("ReverseState("+uri+")\n");
  335. }
  336.  
  337. function SubscribeOnClick(event)
  338. {
  339.   var t = event.originalTarget;
  340.  
  341.     if (event.detail == 2) {
  342.         ReverseStateFromNode(t.parentNode.parentNode);
  343.     }
  344.     else {
  345.          if (t.getAttribute('twisty') == 'true') {
  346.             var treeitem = t.parentNode.parentNode.parentNode;
  347.             var open = treeitem.getAttribute('open');
  348.             if(open == "true") {
  349.                 var uri = treeitem.getAttribute("id");    
  350.                 
  351.                 dump("do twisty for " + uri + "\n");
  352.  
  353.                 gStatusFeedback.ShowProgress(0);
  354.                 gStatusFeedback.ShowStatusString(Bundle.GetStringFromName("pleaseWaitString"));
  355.                 gStatusBar.setAttribute("mode","undetermined");
  356.  
  357.                 gSubscribableServer.populateSubscribeDatasourceWithUri(msgWindow, true /* force to server */, uri);
  358.             }
  359.         }
  360.         else {
  361.             var name = t.parentNode.parentNode.getAttribute('name');
  362.             if (name && (name.length > 0)) {
  363.                 gNameField.setAttribute('value',name);
  364.             }
  365.         }
  366.     }
  367. }
  368.  
  369. function RefreshList()
  370. {
  371.     // force it to talk to the server
  372.     SetUpTree(true);
  373. }
  374.  
  375. function trackGroupInTree()
  376. {
  377.   var portion = gNameField.value;
  378.   selectNodeByName( portion );  
  379. }
  380.  
  381.  
  382. function selectNodeByName( aMatchString )
  383. {
  384.   var lastDot = aMatchString.lastIndexOf(gFolderDelimiter);
  385.   var nodeValue = lastDot != -1 ? aMatchString.substring(0, lastDot) : aMatchString;
  386.   
  387.   var chain = aMatchString.split(gFolderDelimiter);
  388.   var node;
  389.   if( chain.length == 1 ) {
  390.     if (lastTreeChildrenValue != "") {
  391.         node = getTreechildren(gSubscribeTree);
  392.         if( !node ) return;
  393.         lastTreeChildrenValue = "";
  394.         lastTreeChildren = node;
  395.         //dump("cache miss!\n");
  396.     }
  397.     else {
  398.         node = lastTreeChildren;
  399.         //dump("cache hit!\n");
  400.     }
  401.   }
  402.   else {
  403.     // if we can, use the cached tree children
  404.     if (nodeValue != lastTreeChildrenValue) {
  405.         node = gSubscribeTree.getElementsByAttribute("name",nodeValue)[0];
  406.  
  407.         // expand the node, if we need to
  408.         if( node.getAttribute("container") == "true" && 
  409.             node.getAttribute("open") != "true" ) {
  410.               node.setAttribute("open","true");
  411.         }
  412.         node = getTreechildren(node);
  413.         //dump("*** node = " + node.localName + "\n");
  414.  
  415.         lastTreeChildren = node;
  416.         lastTreeChildrenValue = nodeValue;
  417.         //dump("cache miss!\n");
  418.     }
  419.     else {
  420.         //dump("cache hit!\n");
  421.         node = lastTreeChildren;
  422.     }
  423.   }
  424.   
  425.   // find the match, using a binary search.
  426.   var totalItems = node.childNodes.length;
  427.   if (totalItems == 0) return;
  428.   var lastLow = 0;
  429.   var lastHigh = totalItems;
  430.   while (true) {
  431.       var i = Math.floor((lastHigh + lastLow) / 2);
  432.     //dump(i+","+lastLow+","+lastHigh+"\n");
  433.     var currItem = node.childNodes[i];
  434.     var currValue = (currItem.getAttribute("name")).substring(0,aMatchString.length);
  435.     //dump(currValue+" vs "+aMatchString+"\n");
  436.     if (currValue > aMatchString) {
  437.         if (lastHigh == i) return;
  438.         lastHigh = i;
  439.     }
  440.     else if (currValue < aMatchString) {
  441.         if (lastLow == i) return;
  442.         lastLow = i;
  443.     }
  444.     else {
  445.       gSubscribeTree.selectItem( currItem );
  446.       gSubscribeTree.ensureElementIsVisible( currItem );
  447.       return;
  448.     }
  449.   }
  450. }
  451.  
  452. function getTreechildren( aTreeNode )
  453. {
  454.   if( aTreeNode.childNodes ) 
  455.     {
  456.       for( var i = 0; i < aTreeNode.childNodes.length; i++ )
  457.       {
  458.         if( aTreeNode.childNodes[i].localName.toLowerCase() == "treechildren" )
  459.           return aTreeNode.childNodes[i];
  460.       }
  461.       return aTreeNode;
  462.     }
  463.   return null;
  464. }
  465.