Author: fred
Date: 2007-04-23 22:41:07 +0000 (Mon, 23 Apr 2007)
New Revision: 12908

Added:
   trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java
   trunk/freenet/src/freenet/clients/http/bookmark/
   trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java
   trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java
   trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java
   trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java
   trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java
   trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java
   trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/bookmark-new.png
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/delete.png
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit-delete.png
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit.png
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/folder-new.png
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-down.png
   trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-up.png
Removed:
   trunk/freenet/src/freenet/clients/http/Bookmark.java
   trunk/freenet/src/freenet/clients/http/BookmarkManager.java
Modified:
   trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
   trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
   trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css
   trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
   
trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css
   trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css
   trunk/freenet/src/freenet/node/NodeClientCore.java
Log:
Bookmarks are now organized by categories, new bookmark editor

Deleted: trunk/freenet/src/freenet/clients/http/Bookmark.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Bookmark.java        2007-04-23 
22:28:38 UTC (rev 12907)
+++ trunk/freenet/src/freenet/clients/http/Bookmark.java        2007-04-23 
22:41:07 UTC (rev 12908)
@@ -1,143 +0,0 @@
-/* This code is part of Freenet. It is distributed under the GNU General
- * Public License, version 2 (or at your option any later version). See
- * http://www.gnu.org/ for further details of the GPL. */
-package freenet.clients.http;
-
-import freenet.keys.FreenetURI;
-import freenet.keys.USK;
-import freenet.node.NodeClientCore;
-import freenet.node.useralerts.UserAlert;
-import freenet.node.useralerts.UserAlertManager;
-import freenet.support.HTMLNode;
-
-import java.net.MalformedURLException;
-
-public class Bookmark {
-       
-       private FreenetURI key;
-       private String desc;
-       private boolean updated;
-       private final BookmarkUpdatedUserAlert alert;
-       private UserAlertManager alerts;
-
-       private class BookmarkUpdatedUserAlert implements UserAlert {
-
-               public boolean userCanDismiss() {
-                       return true;
-               }
-
-               public String getTitle() {
-                       return "Bookmark updated: "+desc;
-               }
-
-               public String getText() {
-                       return "The bookmarked site "+desc+" has been updated 
to edition "+key.getSuggestedEdition();
-               }
-
-               public HTMLNode getHTMLText() {
-                       HTMLNode n = new HTMLNode("div");
-                       n.addChild("#", "The bookmarked site ");
-                       n.addChild("a", "href", 
'/'+key.toString()).addChild("#", desc);
-                       n.addChild("#", " has been updated to edition 
"+key.getSuggestedEdition()+".");
-                       return n;
-               }
-
-               public short getPriorityClass() {
-                       return UserAlert.MINOR;
-               }
-
-               public boolean isValid() {
-                       synchronized(Bookmark.this) {
-                               return updated;
-                       }
-               }
-
-               public void isValid(boolean validity) {
-                       if(validity) return;
-                       disableBookmark();
-               }
-
-               public String dismissButtonText() {
-                       return "Delete notification";
-               }
-
-               public boolean shouldUnregisterOnDismiss() {
-                       return true;
-               }
-
-               public void onDismiss() {
-                       disableBookmark();
-               }
-               
-       }
-       
-       private synchronized void disableBookmark() {
-               updated = false;
-               alerts.unregister(alert);
-       }
-       
-       private synchronized void enableBookmark() {
-               if(updated) return;
-               updated = true;
-               alerts.register(alert);
-       }
-
-       Bookmark(String k, String d, UserAlertManager uam) throws 
MalformedURLException {
-               this.key = new FreenetURI(k);
-               this.desc = d;
-               alert = new BookmarkUpdatedUserAlert();
-               this.alerts = uam;
-       }
-
-       Bookmark(String from, UserAlertManager uam) throws 
MalformedURLException {
-               int eqpos = from.indexOf("=");
-
-               if (eqpos < 0) {
-                       this.key = new FreenetURI(from);
-                       this.desc = from;
-               } else {
-                       this.key = new FreenetURI(from.substring(0, eqpos));
-                       this.desc = from.substring(eqpos + 1);
-               }
-               alert = new BookmarkUpdatedUserAlert();
-               this.alerts = uam;
-       }
-
-       public String getKey() {
-               return key.toString();
-       }
-       
-       public synchronized FreenetURI getURI() {
-               return key;
-       }
-       
-       public synchronized void setKey(FreenetURI uri) {
-               key = uri;
-       }
-
-       public synchronized String getKeyType() {
-               return key.getKeyType();
-       }
-
-       public String getDesc() {
-               if (desc.equals("")) {
-                       return "Unnamed Bookmark";
-               } else {
-                       return desc;
-               }
-       }
-
-       public String toString() {
-               return this.key.toString() + '=' + this.desc;
-       }
-
-       public synchronized void setEdition(long ed, NodeClientCore node) {
-               if(key.getSuggestedEdition() >= ed) return;
-               key = key.setSuggestedEdition(ed);
-               enableBookmark();
-       }
-
-       public USK getUSK() throws MalformedURLException {
-               return USK.create(key);
-       }
-}
\ No newline at end of file

Added: trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java           
                (rev 0)
+++ trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java   
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,272 @@
+package freenet.clients.http;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import freenet.node.Node;
+
+import freenet.clients.http.bookmark.Bookmark;
+import freenet.clients.http.bookmark.BookmarkItem;
+import freenet.clients.http.bookmark.BookmarkItems;
+import freenet.clients.http.bookmark.BookmarkCategory;
+import freenet.clients.http.bookmark.BookmarkCategories;
+import freenet.clients.http.bookmark.BookmarkManager;
+
+import freenet.node.useralerts.UserAlertManager;
+import freenet.keys.FreenetURI;
+import freenet.node.NodeClientCore;
+import freenet.client.HighLevelSimpleClient;
+import freenet.support.HTMLEncoder;
+import freenet.support.HTMLNode;
+import freenet.support.api.HTTPRequest;
+
+public class BookmarkEditorToadlet extends Toadlet {
+
+       private static final int MAX_ACTION_LENGTH = 20;
+       private static final int MAX_KEY_LENGTH = QueueToadlet.MAX_KEY_LENGTH;
+       private static final int MAX_NAME_LENGTH = 500;
+       private static final int MAX_BOOKMARK_PATH_LENGTH = 10 * 
MAX_NAME_LENGTH;
+
+       private final Node node;
+       private final NodeClientCore core;
+       private final BookmarkManager bookmarkManager;
+
+       
+       BookmarkEditorToadlet(HighLevelSimpleClient client, Node node)
+       {
+               super(client);
+               this.node = node;
+               this.core = node.clientCore;
+               this.bookmarkManager = core.bookmarkManager;            
+       }
+       
+       private void addCategoryToList(BookmarkCategory cat, String path, 
HTMLNode list)
+       {
+               BookmarkItems items = cat.getItems();
+               
+               for(int i = 0; i < items.size(); i++) {
+
+                       String itemPath = path + items.get(i).getName();
+                       HTMLNode li = new HTMLNode("li", "class","item" , 
items.get(i).getName());
+
+                       HTMLNode actions = new HTMLNode("span", "class", 
"actions");
+                       actions.addChild("a", "href", "?action=edit&bookmark=" 
+ itemPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] 
{"/static/icon/edit.png", "edit", "Edit"});
+                       
+                       actions.addChild("a", "href", "?action=del&bookmark=" + 
itemPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] 
{"/static/icon/delete.png", "delete", "Delete"});
+                       
+                       if(i != 0)
+                               actions.addChild("a", "href", 
"?action=up&bookmark=" + itemPath).addChild("img", new String[] {"src", "alt", 
"title"}, new String[] {"/static/icon/go-up.png", "up", "Go up"});
+                       
+                       if(i != items.size()-1)
+                               actions.addChild("a", "href", 
"?action=down&bookmark=" + itemPath).addChild("img", new String[] {"src", 
"alt", "title"}, new String[] {"/static/icon/go-down.png", "down", "Go down"});
+                       
+                       li.addChild(actions);
+                       list.addChild(li);
+               }
+
+               BookmarkCategories cats = cat.getSubCategories();
+               for(int i = 0; i < cats.size(); i++) {
+
+                       String catPath = path + cats.get(i).getName() + "/";
+                       
+                       HTMLNode subCat = list.addChild("li", "class", "cat", 
cats.get(i).getName());
+
+                       HTMLNode actions = new HTMLNode("span", "class", 
"actions");
+                       
+                       actions.addChild("a", "href", "?action=edit&bookmark=" 
+ catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] 
{"/static/icon/edit.png", "edit", "Edit"});
+                       
+                       actions.addChild("a", "href", "?action=del&bookmark=" + 
catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] 
{"/static/icon/delete.png", "delete", "Delete"});
+                       
+                       actions.addChild("a", "href", 
"?action=addItem&bookmark=" + catPath).addChild("img", new String[] {"src", 
"alt", "title"}, new String[] {"/static/icon/bookmark-new.png", "add bookmark", 
"Add bookmark"});
+                       
+                       actions.addChild("a", "href", 
"?action=addCat&bookmark=" + catPath).addChild("img", new String[] {"src", 
"alt", "title"}, new String[] {"/static/icon/folder-new.png", "add category", 
"Add category"});
+                       
+                       if(i != 0)
+                               actions.addChild("a", "href", 
"?action=up&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", 
"title"}, new String[] {"/static/icon/go-up.png", "up", "Go up"});
+                       
+                       if(i != cats.size() -1)
+                               actions.addChild("a", "href", 
"?action=down&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", 
"title"}, new String[] {"/static/icon/go-down.png", "down", "Go down"});
+                       
+                       subCat.addChild(actions);
+                       addCategoryToList(cats.get(i), catPath, 
list.addChild("li").addChild("ul"));
+               }
+       }
+
+       public HTMLNode getBookmarksList()
+       {
+               HTMLNode bookmarks = new HTMLNode("ul", "id", "bookmarks");
+               
+               HTMLNode root = bookmarks.addChild("li", "class", "cat,root", 
"/");
+               HTMLNode actions = new HTMLNode("span", "class", "actions");
+               actions.addChild("a", "href", 
"?action=addItem&bookmark=/").addChild("img", new String[] {"src", "alt", 
"title"}, new String[] {"/static/icon/bookmark-new.png", "add bookmark", "Add 
bookmark"});
+               actions.addChild("a", "href", 
"?action=addCat&bookmark=/").addChild("img", new String[] {"src", "alt", 
"title"}, new String[] {"/static/icon/folder-new.png", "add category", "Add 
category"});
+               root.addChild(actions);
+               
+               addCategoryToList(bookmarkManager.getMainCategory(), "/", 
root.addChild("li").addChild("ul"));
+               
+               return bookmarks;
+       }
+       
+       public void handleGet(URI uri, HTTPRequest req, ToadletContext ctx) 
+                       throws ToadletContextClosedException, IOException 
+       {
+               
+               HTMLNode pageNode = ctx.getPageMaker().getPageNode("Bookmark 
Editor", ctx);
+               HTMLNode content = ctx.getPageMaker().getContentNode(pageNode);
+               
+               if (req.getParam("action").length() > 0 && 
req.getParam("bookmark").length() > 0) {
+                       String action = req.getParam("action");
+                       String bookmarkPath = req.getParam("bookmark");
+                       Bookmark bookmark;
+                       
+                       if (bookmarkPath.endsWith("/"))
+                               bookmark = 
bookmarkManager.getCategoryByPath(bookmarkPath);
+                       else
+                               bookmark = 
bookmarkManager.getItemByPath(bookmarkPath);
+                               
+                       if(bookmark == null) {
+                               HTMLNode errorBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-error", "Error"));
+                               errorBox.addChild("#", "Bookmark \""+ 
bookmarkPath + "\" does not exists.");
+                       } else {
+                       
+                       if(action.equals("del")){
+                               
+                               HTMLNode infoBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-query", "Delete " + 
(bookmark instanceof BookmarkItem ? "bookmark" : "category")));
+                               
+                               String query = "Are you sure you wish to delete 
" + bookmarkPath;
+                               if(bookmark instanceof BookmarkCategory)
+                                       query+= " and all its children";
+                               query+= " ?";
+                               infoBox.addChild("p").addChild("#", query);
+                               
+                               HTMLNode confirmForm = 
ctx.addFormChild(infoBox.addChild("p"), "", "confirmDeleteForm");
+                               confirmForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "bookmark", bookmarkPath});
+                               confirmForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "submit", "cancel", "Cancel" });
+                               confirmForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "submit", "confirmdelete", "Delete" 
});
+                               
+                               
+                       } else if (action.equals("edit") || 
action.equals("addItem") || action.equals("addCat")) {
+                               
+                               String header;
+                               if(action.equals("edit"))
+                                       header = "Edit "+(bookmark instanceof 
BookmarkItem ? "bookmark" : "category");
+                               else if(action.equals("addItem"))
+                                       header = "Add a new bookmark";
+                               else
+                                       header = "Add a new category";
+                               
+                               HTMLNode actionBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-query", header));
+                               
+                               HTMLNode form = ctx.addFormChild(actionBox, "", 
"editBookmarkForm");
+                               
+                               form.addChild("label", "for", "name", "Name : 
");
+                               form.addChild("input", new String[]{"type", 
"id", "name", "size", "value"}, new String []{"text", "name", "name", "20", 
action.equals("edit")?bookmark.getName():""});
+                               
+                               form.addChild("br");
+                               if ((action.equals("edit") && bookmark 
instanceof BookmarkItem) || action.equals("addItem")) {
+                                       String key = (action.equals("edit") ? 
((BookmarkItem) bookmark).getKey() : "");
+                                       form.addChild("label", "for", "key", 
"Key : ");
+                                       form.addChild("input", new 
String[]{"type", "id", "name", "size", "value"}, new String []{"text", "key", 
"key", "50", key});
+                               }
+                               
+                               form.addChild("input", new String[] {"type", 
"name", "value"}, new String[] {"hidden", "bookmark",bookmarkPath});
+                               
+                               form.addChild("input", new String[] {"type", 
"name", "value"}, new String[] {"hidden", "action",req.getParam("action")});
+                               
+                               form.addChild("br");
+                               form.addChild("input", new String[]{"type", 
"value"}, new String[]{"submit", "Save"});
+                       } else if (action.equals("up") || 
action.equals("down")) {
+                               if(action.equals("up"))
+                                       
bookmarkManager.moveBookmarkUp(bookmarkPath, true);
+                               else
+                                       
bookmarkManager.moveBookmarkDown(bookmarkPath, true);
+                       }
+                       }
+                       
+               }
+               
+               HTMLNode bookmarksBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-normal", "My 
Bookmarks"));
+               bookmarksBox.addChild(getBookmarksList());
+
+               this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
+       }
+
+       
+       public void handlePost(URI uri, HTTPRequest req, ToadletContext ctx) 
+               throws ToadletContextClosedException, IOException 
+       {
+               HTMLNode pageNode = ctx.getPageMaker().getPageNode("Bookmark 
Editor", ctx);
+               HTMLNode content = ctx.getPageMaker().getContentNode(pageNode);
+               
+               String passwd = req.getPartAsString("formPassword", 32);
+               boolean noPassword = (passwd == null) || 
!passwd.equals(core.formPassword);
+               if(noPassword) 
+                       return;
+               
+               
+               String bookmarkPath = req.getPartAsString("bookmark", 
MAX_BOOKMARK_PATH_LENGTH);
+               try {
+                       
+                       Bookmark bookmark;
+                       if(bookmarkPath.endsWith("/"))
+                               bookmark = 
bookmarkManager.getCategoryByPath(bookmarkPath);
+                       else
+                               bookmark = 
bookmarkManager.getItemByPath(bookmarkPath);
+                       
+                       String action = req.getPartAsString("action", 
MAX_ACTION_LENGTH);
+                       
+                       if (req.isPartSet("confirmdelete")) {
+                               bookmarkManager.removeBookmark(bookmarkPath, 
true);
+                               HTMLNode successBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-success", "Delete 
succeeded"));
+                               successBox.addChild("p", "The bookmark has been 
deleted successfully");
+                               
+                       } else if (action.equals("edit") || 
action.equals("addItem") || action.equals("addCat")) {
+                               
+                               String name = "unnamed";
+                               if (req.getPartAsString("name", 
MAX_NAME_LENGTH).length() > 0)
+                                       name = req.getPartAsString("name", 
MAX_NAME_LENGTH);
+                               
+                               if(action.equals("edit")) {
+                                       
bookmarkManager.renameBookmark(bookmarkPath, name);
+                                       if(bookmark instanceof BookmarkItem)
+                                               ((BookmarkItem) 
bookmark).setKey(new FreenetURI(req.getPartAsString("key", MAX_KEY_LENGTH)));
+                                       
+                                       HTMLNode successBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-success", 
"Modifications saved"));
+                                       successBox.addChild("p", "The changes 
has been saved successfully");
+                                               
+                               } else if (action.equals("addItem") || 
action.equals("addCat")) {
+                                       
+                                       Bookmark newBookmark;
+                                       if(action.equals("addItem")) {
+                                               FreenetURI key = new 
FreenetURI(req.getPartAsString("key", MAX_KEY_LENGTH));
+                                               newBookmark = new 
BookmarkItem(key, name, core.alerts);
+                                       } else
+                                               newBookmark = new 
BookmarkCategory(name);
+                                       
+                                       
bookmarkManager.addBookmark(bookmarkPath, newBookmark, true);
+                                       
+                                       HTMLNode successBox =  
content.addChild(ctx.getPageMaker().getInfobox("infobox-success", "New bookmark 
added"));
+                                       successBox.addChild("p", "The new 
bookmark has been added successfully");
+                                       
+                               }
+                               
+                       }
+
+               } catch (NullPointerException npo) {
+                       HTMLNode errorBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-error", "Error"));
+                       errorBox.addChild("#", "Bookmark \""+ bookmarkPath + 
"\" does not exists.");
+               } catch (MalformedURLException mue) {
+                       HTMLNode errorBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-error", "Invalid key"));
+                       errorBox.addChild("#", "Invalid Freenet Key");
+               }
+               HTMLNode bookmarksBox = 
content.addChild(ctx.getPageMaker().getInfobox("infobox-normal", "My 
Bookmarks"));
+               bookmarksBox.addChild(getBookmarksList());
+               
+               this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
+       }
+       
+       public String supportedMethods()
+       {
+               return "GET, POST";
+       }
+}

Deleted: trunk/freenet/src/freenet/clients/http/BookmarkManager.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/BookmarkManager.java 2007-04-23 
22:28:38 UTC (rev 12907)
+++ trunk/freenet/src/freenet/clients/http/BookmarkManager.java 2007-04-23 
22:41:07 UTC (rev 12908)
@@ -1,181 +0,0 @@
-/* This code is part of Freenet. It is distributed under the GNU General
- * Public License, version 2 (or at your option any later version). See
- * http://www.gnu.org/ for further details of the GPL. */
-package freenet.clients.http;
-
-import java.net.MalformedURLException;
-import java.util.Enumeration;
-import java.util.Vector;
-
-import freenet.client.async.USKCallback;
-import freenet.config.InvalidConfigValueException;
-import freenet.config.SubConfig;
-import freenet.keys.FreenetURI;
-import freenet.keys.USK;
-import freenet.node.NodeClientCore;
-import freenet.support.api.StringArrCallback;
-
-public class BookmarkManager {
-       private static final String[] DEFAULT_TESTNET_BOOKMARKS = {
-               "USK at 
60I8H8HinpgZSOuTSD66AVlIFAy-xsppFr0YCzCar7c,NzdivUGCGOdlgngOGRbbKDNfSCnjI0FXjHLzJM4xkJ4,AQABAAE/index/4/=INDEX.7-freesite"
-       };
-       private static final String[] DEFAULT_DARKNET_BOOKMARKS = {
-               "USK at 
c55vMxUl-T-lD3nv0iOaXF~G1hnY6pOMRbzZSwACMmY,yd8~uwUmGm164-ipStoiBOJVjkbbYXJMlD~H5ftPxIA,AQABAAE/Indicia/55/=Indicia
 (Lots of freesites - web sites hosted on freenet)",
-               "USK at 
7H66rhYmxIFgMyw5Dl11JazXGHPhp7dSN7WMa1pbtEo,jQHUQUPTkeRcjmjgrc7t5cDRdDkK3uKkrSzuw5CO9uk,AQACAAE/ENTRY.POINT/19/=Entry
 Point (Lots of freesites - web sites hosted on freenet)",
-               "USK at 
PFeLTa1si2Ml5sDeUy7eDhPso6TPdmw-2gWfQ4Jg02w,3ocfrqgUMVWA2PeorZx40TW0c-FiIOL-TWKQHoDbVdE,AQABAAE/Index/42/=Darknet
 Index (Older freesite index)"
-       };
-       private Vector bookmarks;
-       private final NodeClientCore node;
-       private USKUpdatedCallback uskcb;
-       private boolean started;
-       
-       public class BookmarkCallback implements StringArrCallback {
-               public String[] get() {
-                       synchronized(BookmarkManager.this) {
-                               String[] values = new String[bookmarks.size()];
-                               for(int i=0;i<bookmarks.size();i++)
-                                       values[i] = bookmarks.get(i).toString();
-                               return values;
-                       }
-               }
-               
-               public void set(String[] newvals) throws 
InvalidConfigValueException {
-                       bookmarks.clear();
-                       for (int i = 0; i < newvals.length; i++) {
-                               try {
-                                       bookmarks.add(new Bookmark(newvals[i], 
node.alerts));
-                               } catch (MalformedURLException mue) {
-                                       throw new 
InvalidConfigValueException(mue.getMessage());
-                               }
-                       }
-               }
-       }
-       
-       private class USKUpdatedCallback implements USKCallback {
-               public void onFoundEdition(long edition, USK key) {
-                       
-                       for (Enumeration e = bookmarks.elements(); 
e.hasMoreElements(); ) {
-                               Bookmark b = (Bookmark) e.nextElement();
-                               
-                               if (!b.getKeyType().equals("USK")) continue;
-                               
-                               try {
-                                       FreenetURI furi = new 
FreenetURI(b.getKey());
-                                       USK usk = USK.create(furi);
-                                       
-                                       if (usk.equals(key, false)) {
-                                               
b.setEdition(key.suggestedEdition, node);
-                                               break;
-                                       }
-                               } catch (MalformedURLException mue) {
-                               }
-                       }
-                       node.storeConfig();
-               }
-       }
-       
-       public BookmarkManager(NodeClientCore n, SubConfig sc) {
-               this.bookmarks = new Vector();
-               this.node = n;
-               this.uskcb = new USKUpdatedCallback();
-               sc.register("bookmarks", n.isTestnetEnabled() ? 
DEFAULT_TESTNET_BOOKMARKS : DEFAULT_DARKNET_BOOKMARKS, 0, true, false, 
"BookmarkManager.list", "BookmarkManager.listLong", makeCB());
-               
-               String[] initialbookmarks = sc.getStringArr("bookmarks");
-               for (int i = 0; i < initialbookmarks.length; i++) {
-                       try {
-                               addBookmark(new Bookmark(initialbookmarks[i], 
n.alerts), false);
-                       } catch (MalformedURLException mue) {
-                               // just ignore that one
-                       }
-               }
-               synchronized(this) {
-                       started = true;
-               }
-       }
-       
-       public BookmarkCallback makeCB() {
-               return new BookmarkCallback();
-       }
-       
-       public Enumeration getBookmarks() {
-               return this.bookmarks.elements();
-       }
-       
-       public FreenetURI[] getBookmarkURIs() {
-               Bookmark[] b = (Bookmark[]) bookmarks.toArray(new 
Bookmark[bookmarks.size()]);
-               FreenetURI[] uris = new FreenetURI[b.length];
-               for(int i=0;i<uris.length;i++) {
-                       uris[i] = b[i].getURI();
-               }
-               return uris;
-       }
-       
-       public void clear() {
-               for (Enumeration e = this.bookmarks.elements(); 
e.hasMoreElements(); ) {
-                       Bookmark i = (Bookmark)e.nextElement();
-                       
-                       if (!i.getKeyType().equals("USK")) continue;
-                       
-                       try {
-                               USK u = i.getUSK();
-                               this.node.uskManager.unsubscribe(u, this.uskcb, 
true);
-                       } catch (MalformedURLException mue) {
-                               
-                       }
-               }
-               this.bookmarks.clear();
-       }
-       
-       public void addBookmark(Bookmark b, boolean store) {
-               this.bookmarks.add(b);
-               if (b.getKeyType().equals("USK")) {
-                       try {
-                               USK u = b.getUSK();
-                               this.node.uskManager.subscribe(u, this.uskcb, 
true, this);
-                       } catch (MalformedURLException mue) {
-                               
-                       }
-               }
-               if(store && started) node.storeConfig();
-       }
-       
-       public void removeBookmark(Bookmark b, boolean store) {
-               if (b.getKeyType().equals("USK")) {
-                       try {
-                               USK u = b.getUSK();
-                               this.node.uskManager.unsubscribe(u, this.uskcb, 
true);
-                       } catch (MalformedURLException mue) {
-                       
-                       }
-               }
-               this.bookmarks.remove(b);
-               if(store && started) node.storeConfig();
-       }
-       
-       public void moveBookmarkDown (Bookmark b, boolean store) {              
-               int i = this.bookmarks.indexOf(b);
-               if (i == -1) return;
-               
-               Bookmark bk = (Bookmark)this.bookmarks.get(i);
-               this.bookmarks.remove(i);
-               this.bookmarks.add((i+1)%(this.bookmarks.size()+1), bk);
-               
-               if(store && started) node.storeConfig();
-       }
-
-       public void moveBookmarkUp (Bookmark b, boolean store) {
-               int i = this.bookmarks.indexOf(b);
-               if (i == -1) return;
-               
-               Bookmark bk = (Bookmark)this.bookmarks.get(i);
-               this.bookmarks.remove(i);
-               if (--i < 0) i = this.bookmarks.size();
-               this.bookmarks.add(i, bk);
-               
-               if(store && started) node.storeConfig();
-       }
-       
-       public int getSize() {
-               return this.bookmarks.size();
-       }
-}

Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2007-04-23 
22:28:38 UTC (rev 12907)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2007-04-23 
22:41:07 UTC (rev 12908)
@@ -609,6 +609,9 @@

                        LocalFileInsertToadlet localFileInsertToadlet = new 
LocalFileInsertToadlet(core, client);
                        server.register(localFileInsertToadlet, "/files/", 
true, false);
+                       
+                       BookmarkEditorToadlet bookmarkEditorToadlet = new 
BookmarkEditorToadlet(client, node);
+                       server.register(bookmarkEditorToadlet, 
"/bookmarkEditor/", true, false);

                        BrowserTestToadlet browsertTestToadlet = new 
BrowserTestToadlet(client, core);
                        server.register(browsertTestToadlet, "/test/", true, 
false);

Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2007-04-23 
22:28:38 UTC (rev 12907)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2007-04-23 
22:41:07 UTC (rev 12908)
@@ -20,6 +20,11 @@
 import freenet.client.InsertBlock;
 import freenet.client.InserterException;
 import freenet.clients.http.filter.GenericReadFilterCallback;
+import freenet.clients.http.bookmark.BookmarkItem;
+import freenet.clients.http.bookmark.BookmarkItems;
+import freenet.clients.http.bookmark.BookmarkCategory;
+import freenet.clients.http.bookmark.BookmarkCategories;
+import freenet.clients.http.bookmark.BookmarkManager;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
 import freenet.node.NodeClientCore;
@@ -32,9 +37,12 @@
 import freenet.support.api.Bucket;
 import freenet.support.api.HTTPRequest;

+
 import freenet.frost.message.*;


+
+
 public class WelcomeToadlet extends Toadlet {
        private final static int MODE_ADD = 1;
        private final static int MODE_EDIT = 2;
@@ -43,13 +51,13 @@
        private static final int MAX_NAME_LENGTH = 1024 * 1024;
        final NodeClientCore core;
        final Node node;
-       final BookmarkManager bookmarks;
+       final BookmarkManager bookmarkManager;

        WelcomeToadlet(HighLevelSimpleClient client, Node node) {
                super(client);
                this.node = node;
                this.core = node.clientCore;
-               this.bookmarks = core.bookmarkManager;
+               this.bookmarkManager = core.bookmarkManager;
                try {
                        manageBookmarksURI = new 
URI("/welcome/?managebookmarks");
                } catch (URISyntaxException e) {
@@ -66,6 +74,22 @@

        URI manageBookmarksURI;

+       
+       private void addCategoryToList(BookmarkCategory cat, HTMLNode list)
+       {
+               BookmarkItems items = cat.getItems();
+               for(int i = 0; i < items.size(); i++) {
+                       HTMLNode li = list.addChild("li", "class","item");
+                       li.addChild("a", "href", "/" + items.get(i).getKey(), 
items.get(i).getName());
+               }
+
+               BookmarkCategories cats = cat.getSubCategories();
+               for (int i = 0; i < cats.size(); i++) {                 
+                       HTMLNode subCat = list.addChild("li", "class", "cat", 
cats.get(i).getName());
+                       addCategoryToList(cats.get(i), 
list.addChild("li").addChild("ul"));
+               }
+       }
+       
        public void handlePost(URI uri, HTTPRequest request, ToadletContext 
ctx) throws ToadletContextClosedException, IOException {

                if(!ctx.isAllowedFullAccess()) {
@@ -147,58 +171,6 @@

                        
ctx.getPageMaker().getContentNode(infobox).addChild("#", "Runtime database 
statistics have been written to the wrapper logfile");
                        this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
-               }else if (request.isPartSet("addbookmark")) {
-                       if(noPassword) {
-                               redirectToRoot(ctx);
-                               return;
-                       }
-                       String key = request.getPartAsString("key", 
MAX_KEY_LENGTH);
-                       String name = request.getPartAsString("name", 
MAX_NAME_LENGTH);
-                       try {
-                               bookmarks.addBookmark(new Bookmark(key, name, 
core.alerts), true);
-                       } catch (MalformedURLException mue) {
-                               this.sendBookmarkEditPage(ctx, MODE_ADD, null, 
key, name, "Given key does not appear to be a valid Freenet key.");
-                               return;
-                       }
-                       
-                       this.handleGet(manageBookmarksURI, new 
HTTPRequestImpl(manageBookmarksURI), ctx);
-               } else if (request.isPartSet("managebookmarks")) {
-                       if(noPassword) {
-                               redirectToRoot(ctx);
-                               return;
-                       }
-                       Enumeration e = bookmarks.getBookmarks();
-                       while (e.hasMoreElements()) {
-                               Bookmark b = (Bookmark)e.nextElement();
-                       
-                               if (request.isPartSet("delete_"+b.hashCode())) {
-                                       bookmarks.removeBookmark(b, true);
-                                       break;
-                               } else if 
(request.isPartSet("movedown_"+b.hashCode())) {
-                                       bookmarks.moveBookmarkDown(b, true);
-                                       break;
-                               } else if 
(request.isPartSet("moveup_"+b.hashCode())) {
-                                       bookmarks.moveBookmarkUp(b, true);
-                                       break;
-                               } else if 
(request.isPartSet("edit_"+b.hashCode())) {
-                                       this.sendBookmarkEditPage(ctx, b);
-                                       return;
-                               } else if 
(request.isPartSet("update_"+b.hashCode())) {
-                                       // removing it and adding means that 
any USK subscriptions are updated properly
-                                       String key = 
request.getPartAsString("key", MAX_KEY_LENGTH);
-                                       String name = 
request.getPartAsString("name", MAX_NAME_LENGTH);
-                                       try {
-                                               Bookmark newbkmk = new 
Bookmark(key, name, core.alerts);
-                                               bookmarks.removeBookmark(b, 
false);
-                                               bookmarks.addBookmark(newbkmk, 
true);
-                                       } catch (MalformedURLException mue) {
-                                               this.sendBookmarkEditPage(ctx, 
MODE_EDIT, b, key, name, "Given key does not appear to be a valid freenet 
key.");
-                                               return;
-                                       }
-                                       this.handleGet(manageBookmarksURI, new 
HTTPRequestImpl(manageBookmarksURI), ctx);
-                               }
-                       }
-                       this.handleGet(manageBookmarksURI, new 
HTTPRequestImpl(manageBookmarksURI), ctx);
                }else if(request.isPartSet("disable")){
                        if(noPassword) {
                                redirectToRoot(ctx);
@@ -477,19 +449,7 @@
                                writeReply(ctx, 200, "text/html; 
charset=utf-8", "OK", pageNode.generate());
                                Logger.normal(this, "Node is restarting");
                                return;
-                       }else if (request.getParam("newbookmark").length() > 0) 
{
-                               HTMLNode pageNode = 
ctx.getPageMaker().getPageNode("Add a Bookmark", ctx);
-                               HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
-                               HTMLNode infobox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("Confirm Bookmark 
Addition"));
-                               HTMLNode addForm = 
ctx.addFormChild(ctx.getPageMaker().getContentNode(infobox), "/", 
"bookmarkAddForm");
-                               addForm.addChild("#", "Please confirm that you 
want to add the key " + request.getParam("newbookmark") + " to your bookmarks 
and enter the description that you would prefer:");
-                               addForm.addChild("br");
-                               addForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "key", 
request.getParam("newbookmark") });
-                               addForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "text", "name", 
request.getParam("desc") });
-                               addForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "submit", "addbookmark", "Add 
bookmark" });
-                               this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
-                               return;
-                       } else if 
(request.getParam(GenericReadFilterCallback.magicHTTPEscapeString).length() > 
0) {
+                       }else if 
(request.getParam(GenericReadFilterCallback.magicHTTPEscapeString).length() > 
0) {
                                HTMLNode pageNode = 
ctx.getPageMaker().getPageNode("Link to external resources", ctx);
                                HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
                                HTMLNode warnbox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-warning", "External 
link"));
@@ -503,38 +463,7 @@
                                externalLinkForm.addChild("input", new String[] 
{ "type", "name", "value" }, new String[] { "submit", "Go", "Go to the 
specified link" });
                                this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
                                return;
-                       } else if (request.isParameterSet("managebookmarks")) {
-                               HTMLNode pageNode = 
ctx.getPageMaker().getPageNode("Bookmark Manager", ctx);
-                               HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
-                               HTMLNode infobox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-normal", "My 
Bookmarks"));
-                               HTMLNode infoboxContent = 
ctx.getPageMaker().getContentNode(infobox);
-
-                               Enumeration e = bookmarks.getBookmarks();
-                               boolean moveButtonsEnabled = 
(bookmarks.getSize() > 1); // activate move{up|down} buttons
-
-                               if (!e.hasMoreElements()) {
-                                       infoboxContent.addChild("#", "You 
currently do not have any bookmarks defined.");
-                               } else {
-                                       HTMLNode manageForm = 
ctx.addFormChild(infoboxContent, ".", "manageBookmarksForm");
-                                       HTMLNode bookmarkList = 
manageForm.addChild("ul", "id", "bookmarks");
-                                       while (e.hasMoreElements()) {
-                                               Bookmark b = 
(Bookmark)e.nextElement();
-
-                                               HTMLNode bookmark = 
bookmarkList.addChild("li", "style", "clear: right;"); /* TODO */
-                                               bookmark.addChild("input", new 
String[] { "type", "name", "value", "style" }, new String[] { "submit", 
"delete_" + b.hashCode(), "Delete", "float: right;" });
-                                               bookmark.addChild("input", new 
String[] { "type", "name", "value", "style" }, new String[] { "submit", "edit_" 
+ b.hashCode(), "Edit", "float: right;" });
-                                               if (moveButtonsEnabled) {
-                                                       
bookmark.addChild("input", new String[] { "type", "name", "value", "style" }, 
new String[] { "submit", "movedown_" + b.hashCode(), "Down", "float: right;" });
-                                                       
bookmark.addChild("input", new String[] { "type", "name", "value", "style" }, 
new String[] { "submit", "moveup_" + b.hashCode(), "Up", "float: right;" });
-                                               }
-                                               bookmark.addChild("a", "href", 
'/' + b.getKey(), b.getDesc());
-                                       }
-                                       manageForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", 
"managebookmarks", "yes" });
-                               }
-                               
contentNode.addChild(createBookmarkEditForm(ctx, MODE_ADD, null, "", ""));
-                               this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
-                               return;
-                       }else if (request.isParameterSet("exit")) {
+                       } else if (request.isParameterSet("exit")) {
                                HTMLNode pageNode = 
ctx.getPageMaker().getPageNode("Node Shutdown", ctx);
                                HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
                                HTMLNode infobox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-query", "Node 
Shutdown"));
@@ -598,23 +527,14 @@
                bookmarkBoxHeader.addChild("#", "My Bookmarks");
                if(ctx.isAllowedFullAccess()){
                        bookmarkBoxHeader.addChild("#", " [");
-                       bookmarkBoxHeader.addChild("span", "id", 
"bookmarkedit").addChild("a", new String[] { "href", "class" }, new String[] { 
"?managebookmarks", "interfacelink" }, (bookmarks.getSize() == 0) ? "Add" : 
"Edit");
+                       bookmarkBoxHeader.addChild("span", "id", 
"bookmarkedit").addChild("a", new String[] { "href", "class" }, new String[] { 
"/bookmarkEditor/", "interfacelink" },"Edit");
                        bookmarkBoxHeader.addChild("#", "]");
                }

                HTMLNode bookmarkBoxContent = bookmarkBox.addChild("div", 
"class", "infobox-content");
+               HTMLNode bookmarksList = bookmarkBoxContent.addChild("ul", 
"id", "bookmarks");
+               addCategoryToList(bookmarkManager.getMainCategory(), 
bookmarksList);

-               Enumeration e = bookmarks.getBookmarks();
-               if (!e.hasMoreElements()) {
-                       bookmarkBoxContent.addChild("#", "You currently do not 
have any bookmarks defined.");
-               } else {
-                       HTMLNode bookmarkList = 
bookmarkBoxContent.addChild("ul", "id", "bookmarks");
-                       while (e.hasMoreElements()) {
-                               Bookmark b = (Bookmark)e.nextElement();
-                               bookmarkList.addChild("li").addChild("a", 
"href", '/' + b.getKey(), b.getDesc());
-                       }
-               }
-
                // Version info and Quit Form
                HTMLNode versionBox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-information", 
"Version Information & Node Control"));
                HTMLNode versionContent = 
ctx.getPageMaker().getContentNode(versionBox);
@@ -651,45 +571,6 @@
                this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
        }

-       private void sendBookmarkEditPage(ToadletContext ctx, Bookmark b) 
throws ToadletContextClosedException, IOException {
-               this.sendBookmarkEditPage(ctx, MODE_EDIT, b, b.getKey(), 
b.getDesc(), null);
-       }
-       
-       private void sendBookmarkEditPage(ToadletContext ctx, int mode, 
Bookmark b, String origKey, String origDesc, String message) throws 
ToadletContextClosedException, IOException {
-               HTMLNode pageNode = ctx.getPageMaker().getPageNode((mode == 
MODE_ADD) ? "Add a Bookmark" : "Edit a Bookmark", ctx);
-               HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
-               
-               if (message != null) {  // only used for error messages so 
far...
-                       HTMLNode errorBox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-error", "An Error 
Occured"));
-                       
ctx.getPageMaker().getContentNode(errorBox).addChild("#", message);
-               }
-               
-               contentNode.addChild(createBookmarkEditForm(ctx, mode, b, 
origKey, origDesc));
-               
-               this.writeReply(ctx, 200, "text/html", "OK", 
pageNode.generate());
-       }
-       
-       private HTMLNode createBookmarkEditForm(ToadletContext ctx, int mode, 
Bookmark b, String origKey, String origDesc) {
-               PageMaker pageMaker = ctx.getPageMaker();
-               HTMLNode infobox = pageMaker.getInfobox("infobox-normal 
bookmark-edit", (mode == MODE_ADD) ? "New Bookmark" : "Update Bookmark");
-               HTMLNode content = pageMaker.getContentNode(infobox);
-               HTMLNode editForm = ctx.addFormChild(content, ".", mode == 
MODE_ADD ? "addBookmarkForm" : "editBookmarkForm");
-               editForm.addChild("#", "Key: ");
-               editForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "text", "key", origKey });
-               editForm.addChild("br");
-               editForm.addChild("#", "Description: ");
-               editForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "text", "name", origDesc });
-               editForm.addChild("br");
-               if (mode == MODE_ADD) {
-                       editForm.addChild("input", new String[] { "type", 
"name", "value", "class" }, new String[] { "submit", "addbookmark", "Add 
bookmark", "confirm" });
-               } else {
-                       editForm.addChild("input", new String[] { "type", 
"name", "value", "class" }, new String[] { "submit", "update_" + b.hashCode(), 
"Update bookmark", "confirm" });
-                        editForm.addChild("input", new String[] { "type", 
"value", "class" }, new String[] { "submit", "Cancel", "cancel" });
-               }
-               editForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "managebookmarks", "yes" });
-               return infobox;
-       }
-       
        public String supportedMethods() {
                return "GET, POST";
        }

Copied: trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java (from rev 
12707, trunk/freenet/src/freenet/clients/http/Bookmark.java)
===================================================================
--- trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java               
                (rev 0)
+++ trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java       
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,35 @@
+package freenet.clients.http.bookmark;
+
+public abstract class Bookmark
+{
+       protected boolean privateBookmark;
+       protected String name;
+       protected String desc;
+       
+       public boolean isPrivate()
+       {
+               return privateBookmark;
+       }
+
+       public abstract void setPrivate(boolean bool);
+               
+       public String getName()
+       {
+               return name;
+       }
+
+       protected void setName(String s)
+       {
+               name = s;
+       }
+
+       public String getDesc()
+       {
+               return desc;
+       }
+
+       public void setDesc(String s)
+       {
+               desc = s;
+       }
+}

Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java     
                        (rev 0)
+++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java     
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,43 @@
+
+package freenet.clients.http.bookmark;
+
+import java.util.Vector;
+import java.util.Iterator;
+
+
+public final class BookmarkCategories implements Iterable
+{
+
+       Vector categories;
+
+       public BookmarkCategories()
+       {
+               categories = new Vector();
+       }
+
+       public BookmarkCategory get(int i)
+       {
+               return (BookmarkCategory) categories.get(i);
+       }
+
+       public void add(BookmarkCategory bc)
+       {
+               categories.add(bc);
+       }
+
+       protected void extend(BookmarkCategories bc)
+       {
+               for(int i = 0; i < bc.size(); i++)
+                       add(bc.get(i));
+       }
+       
+       public int size()
+       {
+               return categories.size();
+       }
+       
+       public Iterator iterator()
+       {
+               return categories.iterator();
+       }
+}

Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java       
                        (rev 0)
+++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java       
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,155 @@
+package freenet.clients.http.bookmark;
+
+import java.util.Vector;
+import java.util.Iterator;
+
+import freenet.support.StringArray;
+
+
+public class BookmarkCategory extends Bookmark implements Iterable
+{
+
+       private final Vector bookmarks;
+       
+       public BookmarkCategory(String name)
+       {
+               bookmarks = new Vector();
+               setName(name);  
+       }
+       
+       public BookmarkCategory(String name, String desc)
+       {
+               bookmarks = new Vector();
+               setName(name);
+               setDesc(desc);
+       }       
+       
+       protected Bookmark addBookmark(Bookmark b)
+       {
+               bookmarks.add(b);
+               return b;       
+       }
+
+       protected void removeBookmark(Bookmark b)
+       {
+               bookmarks.remove(b);
+       }
+
+       public Bookmark get(int i)
+       {
+               return (Bookmark) bookmarks.get(i);
+       }
+       
+       protected void moveBookmarkUp(Bookmark b)
+       {
+               int index = bookmarks.indexOf(b);
+               if(index == -1)
+                       return;
+                       
+               Bookmark bk = get(index);
+               bookmarks.remove(index);
+               bookmarks.add((--index < 0) ? 0 : index , bk);
+       }
+       
+       protected void moveBookmarkDown(Bookmark b)
+       {
+               int index = bookmarks.indexOf(b);
+               if(index == -1)
+                       return;
+               
+               Bookmark bk = get(index);
+               bookmarks.remove(index);
+               bookmarks.add((++index > size()) ? size() : index, bk);
+       }
+       
+       public int size()
+       {
+               return bookmarks.size();
+       }
+       
+       public BookmarkItems getItems()
+       {
+               BookmarkItems items = new BookmarkItems();
+               for(int i = 0; i < size();  i++) {
+                       if(get(i) instanceof BookmarkItem)
+                               items.add((BookmarkItem) get(i));
+               }
+
+               return items;
+       }
+       
+       public BookmarkItems getAllItems()
+       {
+               BookmarkItems items = getItems();
+               BookmarkCategories subCategories = getSubCategories();
+               
+               for(int i = 0; i < subCategories.size(); i++) {
+                       items.extend(subCategories.get(i).getAllItems());
+               }
+               return items;
+       }
+
+       
+       public BookmarkCategories getSubCategories()
+       {
+               BookmarkCategories categories = new BookmarkCategories();
+               for(int i = 0; i < size();  i++) {
+                       if(get(i) instanceof BookmarkCategory)
+                               categories.add((BookmarkCategory) get(i));
+               }
+               
+               return categories;
+       }
+       
+       public BookmarkCategories getAllSubCategories()
+       {
+               BookmarkCategories categories = getSubCategories();
+               BookmarkCategories subCategories = getSubCategories();
+               
+               for(int i = 0; i < subCategories.size(); i++) {
+                       
categories.extend(subCategories.get(i).getAllSubCategories());
+               }
+
+               return categories;
+       }
+       
+
+       public String[] toStrings()
+       {
+               return StringArray.toArray(toStrings("").toArray());
+       }
+       
+       // Iternal use only
+       private Vector toStrings(String prefix)
+       {
+               Vector strings = new Vector();
+               BookmarkItems items = getItems();
+               BookmarkCategories subCategories = getSubCategories();
+               prefix += this.name + "/";
+                       
+               for(int i = 0; i < items.size(); i++)
+                       strings.add(prefix + items.get(i).toString());
+               
+               for(int i = 0; i < subCategories.size(); i++)
+                       strings.addAll(subCategories.get(i).toStrings(prefix));
+
+               return strings;
+               
+       }
+       
+       public void setPrivate(boolean bool)
+       {
+               privateBookmark = bool;
+               
+               BookmarkCategories subCategories = getSubCategories();
+               for(int i = 0; i < size(); i++)
+                       subCategories.get(i).setPrivate(bool);
+       }
+       
+       public Iterator iterator()
+       {
+               return bookmarks.iterator();
+       }
+       
+}
+

Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java           
                (rev 0)
+++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java   
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,143 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.clients.http.bookmark;
+
+import freenet.keys.FreenetURI;
+import freenet.keys.USK;
+import freenet.node.NodeClientCore;
+import freenet.node.useralerts.UserAlert;
+import freenet.node.useralerts.UserAlertManager;
+import freenet.support.HTMLNode;
+
+import java.net.MalformedURLException;
+
+public class BookmarkItem extends Bookmark{
+       
+       private FreenetURI key;
+       private boolean updated;
+       private final BookmarkUpdatedUserAlert alert;
+       private UserAlertManager alerts;
+       
+       
+       public BookmarkItem(FreenetURI k, String n, UserAlertManager uam) 
throws MalformedURLException {
+               this.key = k;
+               this.name = n;
+               this.alerts = uam;
+               alert = new BookmarkUpdatedUserAlert();
+       }
+
+       public BookmarkItem(FreenetURI k, String n, String d,  UserAlertManager 
uam) throws MalformedURLException {
+       
+               this.key = k;
+               this.name = n;
+               this.desc = d;
+               this.alerts = uam;
+               alert = new BookmarkUpdatedUserAlert();
+       }
+       
+       private class BookmarkUpdatedUserAlert implements UserAlert {
+
+               public boolean userCanDismiss() {
+                       return true;
+               }
+
+               public String getTitle() {
+                       return "Bookmark updated: "+ name;
+               }
+
+               public String getText() {
+                       return "The bookmarked site "+ name +" has been updated 
to edition "+key.getSuggestedEdition();
+               }
+
+               public HTMLNode getHTMLText() {
+                       HTMLNode n = new HTMLNode("div");
+                       n.addChild("#", "The bookmarked site ");
+                       n.addChild("a", "href", 
'/'+key.toString()).addChild("#", name);
+                       n.addChild("#", " has been updated to edition 
"+key.getSuggestedEdition()+".");
+                       return n;
+               }
+
+               public short getPriorityClass() {
+                       return UserAlert.MINOR;
+               }
+
+               public boolean isValid() {
+                       synchronized(BookmarkItem.this) {
+                               return updated;
+                       }
+               }
+
+               public void isValid(boolean validity) {
+                       if(validity) return;
+                       disableBookmark();
+               }
+
+               public String dismissButtonText() {
+                       return "Delete notification";
+               }
+
+               public boolean shouldUnregisterOnDismiss() {
+                       return true;
+               }
+
+               public void onDismiss() {
+                       disableBookmark();
+               }
+               
+       }
+       
+       private synchronized void disableBookmark() {
+               updated = false;
+               alerts.unregister(alert);
+       }
+       
+       private synchronized void enableBookmark() {
+               if(updated) return;
+               updated = true;
+               alerts.register(alert);
+       }
+       
+       public String getKey() {
+               return key.toString();
+       }
+       
+       public synchronized FreenetURI getURI() {
+               return key;
+       }
+       
+       public synchronized void setKey(FreenetURI uri) {
+               key = uri;
+       }
+
+       public synchronized String getKeyType() {
+               return key.getKeyType();
+       }
+
+       public String getName() {
+               if (name.equals("")) {
+                       return "Unnamed Bookmark";
+               } else {
+                       return name;
+               }
+       }
+       
+       public void setPrivate(boolean bool)
+       {
+               privateBookmark = bool;
+       }
+       
+       public String toString() {
+               return this.name + "=" + this.key.toString();
+       }
+
+       public synchronized void setEdition(long ed, NodeClientCore node) {
+               if(key.getSuggestedEdition() >= ed) return;
+               key = key.setSuggestedEdition(ed);
+               enableBookmark();
+       }
+
+       public USK getUSK() throws MalformedURLException {
+               return USK.create(key);
+       }
+}

Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java          
                (rev 0)
+++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java  
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,43 @@
+package freenet.clients.http.bookmark;
+
+import java.util.Vector;
+import java.util.Iterator;
+
+
+public class BookmarkItems implements Iterable
+{
+
+       Vector items;
+       
+
+       public BookmarkItems()
+       {
+               items = new Vector();
+       }
+
+       public BookmarkItem get(int i)
+       {
+               return (BookmarkItem) items.get(i);
+       }
+
+       public void add(BookmarkItem bi)
+       {
+               items.add(bi);
+       }
+
+       protected void extend(BookmarkItems bi)
+       {
+               for(int i = 0; i < bi.size(); i++)
+                       add(bi.get(i));
+       }
+       
+       public int size()
+       {
+               return items.size();
+       }
+       
+       public Iterator iterator()
+       {
+               return (items).iterator();
+       }
+}

Copied: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java 
(from rev 12707, trunk/freenet/src/freenet/clients/http/BookmarkManager.java)
===================================================================
--- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java        
                        (rev 0)
+++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java        
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,338 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+
+package freenet.clients.http.bookmark;
+
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import freenet.client.async.USKCallback;
+import freenet.config.InvalidConfigValueException;
+import freenet.config.SubConfig;
+import freenet.keys.FreenetURI;
+import freenet.keys.USK;
+import freenet.node.NodeClientCore;
+import freenet.support.api.StringArrCallback;
+
+
+public class BookmarkManager {
+
+       private final NodeClientCore node;
+       private USKUpdatedCallback uskcb;
+       private boolean started;
+       private BookmarkCategory mainCategory;
+       private HashMap bookmarks;
+       
+       public BookmarkManager(NodeClientCore n, SubConfig sc)
+       {
+
+               bookmarks = new HashMap();
+               mainCategory = new BookmarkCategory("/");
+               bookmarks.put("/", mainCategory);
+
+               this.uskcb = new USKUpdatedCallback();
+               this.node = n;
+                               
+               try {
+                       
+                       BookmarkCategory defaultRoot = new 
BookmarkCategory("/");
+                       
+                       BookmarkCategory indexes = (BookmarkCategory) 
defaultRoot.addBookmark(new BookmarkCategory("Indicies"));
+                       indexes.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
7H66rhYmxIFgMyw5Dl11JazXGHPhp7dSN7WMa1pbtEo,jQHUQUPTkeRcjmjgrc7t5cDRdDkK3uKkrSzuw5CO9uk,AQACAAE/ENTRY.POINT/20/full/page1.html"),"Entry
 point", node.alerts));
+                       indexes.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
BPZppy07RyID~NGihHgs4AAw3fUXxgtKIrwRu5rtpWE,k5yjkAFJC93JkydKl6vpY0Zy9D8ec1ymv2XP4Tx5Io0,AQABAAE/FreeHoo/6/"),"Free
 Hoo", node.alerts));
+       
+                       BookmarkCategory flog = (BookmarkCategory) 
defaultRoot.addBookmark(new BookmarkCategory("Freenet devel's flog"));
+                       flog.addBookmark(new BookmarkItem(new FreenetURI("USK 
at 
J585KtAJ7UN2~4i17hf7C9XbufMnticJeUDYLcB0dvo,lxZhX2snsExxemocIlI~ZJRFVdVLBLIFZhqV3yswR9U,AQABAAE/toad/10/"),"Toad",
 node.alerts));
+                       flog.addBookmark(new BookmarkItem(new FreenetURI("USK 
at 
hM9XRwjXIzU8xTSBXNZvTn2KuvTSRFnVn4EER9FQnpM,gsth24O7ud4gL4NwNuYJDUqfaWASOG2zxZY~ChtgPxc,AQACAAE/Flog/2/"),
 "Nextgen$", node.alerts));
+                       
+                       BookmarkCategory apps = (BookmarkCategory) 
defaultRoot.addBookmark(new BookmarkCategory("Software"));
+                       apps.addBookmark(new BookmarkItem(new FreenetURI("USK 
at 
XeMBryjuEaxqazEuxwnn~G7wCUOXFOZlVWbscdCOUFs,209eycYVidlZvhgL5V2a3INFxrofxzQctEZvyJaFL7I,AQABAAE/frost/2/"),"Frost",
 node.alerts));
+                               
+                       sc.register("bookmarks",defaultRoot.toStrings() , 0, 
true, false, "List of bookmarks", "A list of bookmarked freesites", makeCB());
+       
+                       makeCB().set((sc.getStringArr("bookmarks").length == 0 
? defaultRoot.toStrings() : sc.getStringArr("bookmarks")));
+                       
+               
+               } catch (MalformedURLException mue) {
+                       // just ignore that one
+               } catch (InvalidConfigValueException icve){
+                       //TODO
+                       icve.printStackTrace();
+               }
+               
+               synchronized(this) {
+                       started = true;
+               }
+       }
+       
+       public class BookmarkCallback implements StringArrCallback 
+       {
+               public String[] get() 
+               {
+
+                       synchronized(BookmarkManager.this) {
+
+                               return mainCategory.toStrings();
+                               
+                       }
+               }
+
+               public void set(String[] newVals) throws 
InvalidConfigValueException 
+               {
+                       clear();
+                       Pattern pattern = 
Pattern.compile("/(.*/)([^/]*)=([A-Z]{3}@.*).*");
+
+                       FreenetURI key;
+                       for (int i = 0; i < newVals.length; i++) {
+                               try {
+                                       Matcher matcher = 
pattern.matcher(newVals[i]);
+                                       if(matcher.matches() && 
matcher.groupCount() == 3) {
+
+                                               makeParents(matcher.group(1));
+                                               key  = new 
FreenetURI(matcher.group(3));
+                                               
addBookmark(matcher.group(1),new BookmarkItem(key, matcher.group(2), 
node.alerts), false);
+                                       
+                                       }else
+                                               throw new 
InvalidConfigValueException("Malformed Bookmark");    
+                                       
+                               } catch (MalformedURLException mue) {
+                                       throw new 
InvalidConfigValueException(mue.getMessage());
+                               }
+                       }
+               }
+       }
+       
+       private class USKUpdatedCallback implements USKCallback {
+               public void onFoundEdition(long edition, USK key) {
+                       BookmarkItems items = mainCategory.getAllItems();
+                       for (int i = 0; i < items.size(); i++) {
+                               
+                               
+                               if (!items.get(i).getKeyType().equals("USK")) 
+                                       continue;
+                               
+                               try {
+                                       FreenetURI furi = new 
FreenetURI(items.get(i).getKey());
+                                       USK usk = USK.create(furi);
+                                       
+                                       if (usk.equals(key, false)) {
+                                               
items.get(i).setEdition(key.suggestedEdition, node);
+                                               break;
+                                       }
+                               } catch (MalformedURLException mue) {
+                               }
+                       }
+                       node.storeConfig();
+               }
+       }
+
+       public BookmarkCallback makeCB() {
+               return new BookmarkCallback();
+       }
+
+       public BookmarkCategory getMainCategory()
+       {
+               return mainCategory;
+       }
+
+       public String parentPath(String path)
+       {
+               if(path.equals("/"))
+                       return "/";
+
+               return path.substring(0, path.substring(0,path.length() 
-1).lastIndexOf("/")) + "/";
+       }
+
+       public Bookmark getBookmarkByPath(String path)
+       {
+               return (Bookmark) bookmarks.get(path);
+       }
+
+       public BookmarkCategory getCategoryByPath(String path)
+       {
+               if(getBookmarkByPath(path) instanceof BookmarkCategory)
+                       return (BookmarkCategory) getBookmarkByPath(path);
+
+               return null;
+       }
+
+       public BookmarkItem getItemByPath(String path)
+       {
+               if(getBookmarkByPath(path) instanceof BookmarkItem)
+                       return (BookmarkItem) getBookmarkByPath(path);
+
+               return null;
+       }
+
+       public void addBookmark(String parentPath, Bookmark b,  boolean store) 
throws NullPointerException
+       {
+               BookmarkCategory parent = getCategoryByPath(parentPath);
+               if(parent == null)
+                        throw new NullPointerException();
+               else {
+                       parent.addBookmark(b);
+                       bookmarks.put(parentPath + b.getName() + ((b instanceof 
BookmarkCategory) ? "/" : ""), b);
+               }       
+                       
+               if(store)
+                       node.storeConfig();
+       }
+       
+       // TODO
+       public void renameBookmark(String path, String newName)
+       {
+               Bookmark bookmark = getBookmarkByPath(path);
+               bookmark.setName(newName);
+               if(bookmark instanceof BookmarkCategory) {
+                       try {
+                               makeCB().set(makeCB().get());
+                               
+                       } catch (InvalidConfigValueException icve) {    }
+               }
+       
+       }
+
+       public void removeBookmark(String path, boolean store)
+       {
+               Bookmark bookmark = getBookmarkByPath(path);
+               if(bookmark == null)
+                       return;
+               
+               if(bookmark instanceof BookmarkCategory) {
+                       BookmarkCategory cat = (BookmarkCategory) bookmark;
+                       for(int i = 0; i < cat.size(); i++) {
+                               removeBookmark(path + cat.get(i).getName() + 
((cat.get(i) instanceof BookmarkCategory) ? "/" : ""), false);
+                       }
+               } else {
+                       if(((BookmarkItem) 
bookmark).getKeyType().equals("USK")) {
+                               try {
+                                       USK u = ((BookmarkItem) 
bookmark).getUSK();
+                                       this.node.uskManager.subscribe(u, 
this.uskcb, true, this);
+                               } catch (MalformedURLException mue) { }
+                       }
+               }
+
+               
getCategoryByPath(parentPath(path)).removeBookmark(getBookmarkByPath(path));
+               bookmarks.remove(path);
+               
+               if(store)
+                       node.storeConfig();
+
+       }
+
+       public void moveBookmarkUp(String path, boolean store)
+       {
+               BookmarkCategory parent = getCategoryByPath(parentPath(path));
+               parent.moveBookmarkUp(getBookmarkByPath(path));
+               
+               if(store)
+                       node.storeConfig();
+       }
+               
+       public void moveBookmarkDown(String path, boolean store)
+       {
+               BookmarkCategory parent = getCategoryByPath(parentPath(path));
+               parent.moveBookmarkDown(getBookmarkByPath(path));
+               
+               if(store)
+                       node.storeConfig();
+       }
+
+       private BookmarkCategory makeParents(String path)
+       {
+               if(bookmarks.containsKey(path))
+                       return getCategoryByPath(path);
+               else {
+                       
+                       int index =  path.substring(0, 
path.length()-1).lastIndexOf("/");
+                       String name = path.substring(index +1, path.length() 
-1);
+
+                       BookmarkCategory cat = new BookmarkCategory(name);
+                       makeParents(parentPath(path));
+                       addBookmark(parentPath(path), cat, false);
+       
+                       return cat;
+               }       
+       }
+       
+       public void clear()
+       {
+
+               removeBookmark("/", false);
+               bookmarks.clear();
+
+               mainCategory = new BookmarkCategory("/");
+               bookmarks.put("/", mainCategory);
+
+       }
+       
+       public FreenetURI[] getBookmarkURIs() 
+       {
+               BookmarkItems items = mainCategory.getAllItems();
+               FreenetURI[] uris = new FreenetURI[items.size()];
+               for(int i = 0; i < items.size(); i++) {
+                       uris[i] = items.get(i).getURI();
+               }
+               
+               return uris;
+       }
+       
+       
+       
+/*
+       public void addBookmark(Bookmark b, boolean store) {
+               this.bookmarks.add(b);
+               if (b.getKeyType().equals("USK")) {
+                       try {
+                               USK u = b.getUSK();
+                               this.node.uskManager.subscribe(u, this.uskcb, 
true, this);
+                       } catch (MalformedURLException mue) {
+                               
+                       }
+               }
+               if(store && started) node.storeConfig();
+       }
+       
+       public void removeBookmark(Bookmark b, boolean store) {
+               if (b.getKeyType().equals("USK")) {
+                       try {
+                               USK u = b.getUSK();
+                               this.node.uskManager.unsubscribe(u, this.uskcb, 
true);
+                       } catch (MalformedURLException mue) {
+                       
+                       }
+               }
+               this.bookmarks.remove(b);
+               if(store && started) node.storeConfig();
+       }
+       
+       public void moveBookmarkDown (Bookmark b, boolean store) {              
+               int i = this.bookmarks.indexOf(b);
+               if (i == -1) return;
+               
+               Bookmark bk = (Bookmark)this.bookmarks.get(i);
+               this.bookmarks.remove(i);
+               this.bookmarks.add((i+1)%(this.bookmarks.size()+1), bk);
+               
+               if(store && started) node.storeConfig();
+       }
+
+       public void moveBookmarkUp (Bookmark b, boolean store) {
+               int i = this.bookmarks.indexOf(b);
+               if (i == -1) return;
+               
+               Bookmark bk = (Bookmark)this.bookmarks.get(i);
+               this.bookmarks.remove(i);
+               if (--i < 0) i = this.bookmarks.size();
+               this.bookmarks.add(i, bk);
+               
+               if(store && started) node.storeConfig();
+       }
+       
+       public int getSize() {
+               return this.bookmarks.size();
+       }*/
+}

Added: trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css             
                (rev 0)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css     
2007-04-23 22:41:07 UTC (rev 12908)
@@ -0,0 +1,19 @@
+ul#bookmarks ul {
+       padding-left: 20px;
+}
+
+ul#bookmarks li {
+       list-style-type: none;
+       margin-top: 1px;
+       margin-bottom: 1px;
+}
+
+ul#bookmarks li.cat {
+       font-weight: bold;
+       margin-top: 7px;
+}
+
+ul#bookmarks span.actions img {
+       border: 0;
+       margin-left: 3px;
+}
\ No newline at end of file

Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/bookmark-new.png
===================================================================
(Binary files differ)


Property changes on: 
trunk/freenet/src/freenet/clients/http/staticfiles/icon/bookmark-new.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/delete.png
===================================================================
(Binary files differ)


Property changes on: 
trunk/freenet/src/freenet/clients/http/staticfiles/icon/delete.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit-delete.png
===================================================================
(Binary files differ)


Property changes on: 
trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit-delete.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit.png
===================================================================
(Binary files differ)


Property changes on: 
trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/folder-new.png
===================================================================
(Binary files differ)


Property changes on: 
trunk/freenet/src/freenet/clients/http/staticfiles/icon/folder-new.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-down.png
===================================================================
(Binary files differ)


Property changes on: 
trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-down.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-up.png
===================================================================
(Binary files differ)


Property changes on: 
trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: 
trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css   
2007-04-23 22:28:38 UTC (rev 12907)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css   
2007-04-23 22:41:07 UTC (rev 12908)
@@ -1,3 +1,6 @@
+/* Bookmarks & bookmark editor */
+ at import url(/static/bookmark.css);
+
 body {
        font-family: tahoma;
        font-size: 11px;

Modified: 
trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css   
2007-04-23 22:28:38 UTC (rev 12907)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css   
2007-04-23 22:41:07 UTC (rev 12908)
@@ -1,3 +1,6 @@
+/* Bookmarks & bookmark editor */
+ at import url(/static/bookmark.css);
+
 /* overall settings */

 p, span, div, td, th, li, h1, h2, h3, h4, h5 {
@@ -582,3 +585,6 @@
 td.n2ntm-send-failed {
        background-color: #ffb7b7;
 }
+
+
+

Modified: 
trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css
===================================================================
--- 
trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css 
    2007-04-23 22:28:38 UTC (rev 12907)
+++ 
trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css 
    2007-04-23 22:41:07 UTC (rev 12908)
@@ -1,3 +1,5 @@
+/* Bookmarks & bookmark editor */
+ at import url(/static/bookmark.css);

 /* [edward at rnahost.com] */


Modified: 
trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css     
2007-04-23 22:28:38 UTC (rev 12907)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css     
2007-04-23 22:41:07 UTC (rev 12908)
@@ -1,3 +1,6 @@
+/* Bookmarks & bookmark editor */
+ at import url(/static/bookmark.css);
+
 /* overall settings */

 p, span, div, td, th, li, h1, h2, h3, h4, h5 {

Modified: trunk/freenet/src/freenet/node/NodeClientCore.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeClientCore.java  2007-04-23 22:28:38 UTC 
(rev 12907)
+++ trunk/freenet/src/freenet/node/NodeClientCore.java  2007-04-23 22:41:07 UTC 
(rev 12908)
@@ -13,7 +13,7 @@
 import freenet.client.async.SimpleHealingQueue;
 import freenet.client.async.USKManager;
 import freenet.client.events.SimpleEventProducer;
-import freenet.clients.http.BookmarkManager;
+import freenet.clients.http.bookmark.BookmarkManager;
 import freenet.clients.http.FProxyToadlet;
 import freenet.clients.http.SimpleToadletServer;
 import freenet.clients.http.filter.FilterCallback;


Reply via email to