diff --git a/mozilla/suite/common/bookmarks/bm-panel.xul b/mozilla/suite/common/bookmarks/bm-panel.xul new file mode 100644 index 00000000000..c6106181380 --- /dev/null +++ b/mozilla/suite/common/bookmarks/bm-panel.xul @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + Name + + + + URL + + + + + + + + + diff --git a/mozilla/suite/common/bookmarks/bm-props.xul b/mozilla/suite/common/bookmarks/bm-props.xul new file mode 100644 index 00000000000..fa98c9fa0be --- /dev/null +++ b/mozilla/suite/common/bookmarks/bm-props.xul @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ Name: + + +
+ Location: + + +
+ Shortcut: + + +
+ Description: + + +
+
+
+ + + +
+
+
diff --git a/mozilla/suite/common/bookmarks/bookmarks.css b/mozilla/suite/common/bookmarks/bookmarks.css new file mode 100644 index 00000000000..ae8c2f9174d --- /dev/null +++ b/mozilla/suite/common/bookmarks/bookmarks.css @@ -0,0 +1,126 @@ +window { + display: block; + background-color: #FFFFFF; +} + +menubar { + display: none; +} + +tree { + display: table; + background-color: #FFFFFF; + border: none; + border-spacing: 0px; + width: 100%; +} + +treecol { + display: table-column; + width: 200px; +} + +treeitem { + display: table-row; +} + +treehead { + display: table-header-group; +} + +treebody { + display: table-row-group; +} + +treecell { + display: table-cell; + font-family: Verdana, Sans-Serif; + font-size: 8pt; +} + +treecell[selectedcell] { + background-color: yellow; + } + +treecell[sortActive="true"][sortDirection="ascending"] { + background-color: green; + } + +treecell[sortActive="true"][sortDirection="descending"] { + background-color: red; + } + +treecol[sortActive="true"] { + background-color: lightgreen; +} + +treehead treeitem treecell { + background-color: #c0c0c0; + border: outset 1px; + border-color: white #707070 #707070 white; + padding-left: 4px; +} + +treecell[selectedcell] { + background-color: yellow; +} + +treeitem[container="true"][open="true"][loading="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/loading.gif") ! important ; +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-folder-closed.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-folder-open.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"][id="NC:PersonalToolbarFolder"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/personal-folder-closed.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"][id="NC:PersonalToolbarFolder"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/personal-folder-open.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#BookmarkSeparator"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-item.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#IEFavorite"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/IEFavorite.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Bookmark"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-item.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#FileSystemObject"][container="true"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-open.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#FileSystemObject"][container="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-closed.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#FileSystemObject"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/article.gif"); +} + +treeitem[container="true"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-open.gif"); +} + +treeitem[container="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-closed.gif"); +} + +treeitem > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/document.gif"); +} + +titledbutton#bookmarks { + list-style-image:url("resource:/res/rdf/bookmark-item.gif"); +} diff --git a/mozilla/suite/common/bookmarks/bookmarks.js b/mozilla/suite/common/bookmarks/bookmarks.js new file mode 100644 index 00000000000..ab13daf76e8 --- /dev/null +++ b/mozilla/suite/common/bookmarks/bookmarks.js @@ -0,0 +1,131 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + + Script for the bookmarks properties window + +*/ + +function BookmarksNewWindow() +{ + // XXX This needs to be "window.open()", I think... + var toolkitCore = XPAppCoresManager.Find("toolkitCore"); + if (!toolkitCore) { + toolkitCore = new ToolkitCore(); + if (toolkitCore) { + toolkitCore.Init("toolkitCore"); + } + } + if (toolkitCore) { + toolkitCore.ShowWindow("resource://res/rdf/bookmarks.xul",window); + } +} + +function BookmarkProperties() +{ + var tree = document.getElementById('bookmarksTree'); + var select_list = tree.getElementsByAttribute("selected", "true"); + + if (select_list.length >= 1) { + dump("Bookmark Properties: Have selection\n"); + var propsCore = XPAppCoresManager.Find(select_list[0].id); + if (!propsCore) { + dump("Bookmark Properties: no existing appcore\n"); + var propsCore = new DOMPropsCore(); + if (propsCore) { + dump("Bookmark Properties: initing new appcore\n"); + propsCore.Init(select_list[0].id); + } else { + dump("Bookmark Properties: failed to create new appcore\n"); + } + } + if (propsCore) { + dump("Bookmark Properties: opening new window\n"); + propsCore.showProperties("resource://res/rdf/bm-props.xul", + window, select_list[0]); + return true; + } + } else { + dump("nothing selected!\n"); + } + return false; +} + +function OpenURL(event,node) +{ + if (node.getAttribute('container') == "true") { + return false; + } + url = node.getAttribute('id'); + + // Ignore "NC:" urls. + if (url.substring(0, 3) == "NC:") { + return false; + } + + /*window.open(url,'bookmarks');*/ + var toolkitCore = XPAppCoresManager.Find("ToolkitCore"); + if (!toolkitCore) { + toolkitCore = new ToolkitCore(); + if (toolkitCore) { + toolkitCore.Init("ToolkitCore"); + } + } + if (toolkitCore) { + toolkitCore.ShowWindow(url,window); + } + + dump("OpenURL(" + url + ")\n"); + + return true; +} + +function doSort(sortColName) +{ + var node = document.getElementById(sortColName); + // determine column resource to sort on + var sortResource = node.getAttribute('resource'); + if (!node) return(false); + + var sortDirection="ascending"; + var isSortActive = node.getAttribute('sortActive'); + if (isSortActive == "true") { + var currentDirection = node.getAttribute('sortDirection'); + if (currentDirection == "ascending") + sortDirection = "descending"; + else if (currentDirection == "descending") + sortDirection = "natural"; + else + sortDirection = "ascending"; + } + + // get RDF Core service + var rdfCore = XPAppCoresManager.Find("RDFCore"); + if (!rdfCore) { + rdfCore = new RDFCore(); + if (!rdfCore) { + return(false); + } + rdfCore.Init("RDFCore"); +// XPAppCoresManager.Add(rdfCore); + } + // sort!!! + rdfCore.doSort(node, sortResource, sortDirection); + return(false); +} diff --git a/mozilla/xpfe/components/bookmarks/Makefile.in b/mozilla/xpfe/components/bookmarks/Makefile.in new file mode 100644 index 00000000000..0ec06f4e571 --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/Makefile.in @@ -0,0 +1,29 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = public src resources + +include $(topsrcdir)/config/config.mk + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/xpfe/components/bookmarks/makefile.win b/mozilla/xpfe/components/bookmarks/makefile.win new file mode 100644 index 00000000000..32cfaf4a2cd --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/makefile.win @@ -0,0 +1,22 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\.. + +DIRS=public src resources + +include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/xpfe/components/bookmarks/public/MANIFEST_IDL b/mozilla/xpfe/components/bookmarks/public/MANIFEST_IDL new file mode 100644 index 00000000000..fb9667a177b --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/public/MANIFEST_IDL @@ -0,0 +1 @@ +nsIBookmarksService.idl diff --git a/mozilla/xpfe/components/bookmarks/public/Makefile.in b/mozilla/xpfe/components/bookmarks/public/Makefile.in new file mode 100644 index 00000000000..12ca9d44764 --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/public/Makefile.in @@ -0,0 +1,32 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE=bookmarks + +XPIDLSRCS = nsIBookmarksService.idl \ + $(NULL) + +EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/xpfe/components/bookmarks/public/makefile.win b/mozilla/xpfe/components/bookmarks/public/makefile.win new file mode 100644 index 00000000000..538a778d095 --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/public/makefile.win @@ -0,0 +1,27 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\.. + +MODULE=bookmarks + +XPIDLSRCS = \ + .\nsIBookmarksService.idl \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + diff --git a/mozilla/xpfe/components/bookmarks/public/nsIBookmarksService.idl b/mozilla/xpfe/components/bookmarks/public/nsIBookmarksService.idl new file mode 100644 index 00000000000..bb7df3f99c1 --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/public/nsIBookmarksService.idl @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + + The Browser Bookmarks service + +*/ + +#include "nsISupports.idl" + +[scriptable, uuid(a82e9300-e4af-11d2-8fdf-0008c70adc7b)] +interface nsIBookmarksService : nsISupports +{ + void AddBookmark(in string aURI, in wstring aTitle); + string FindShortcut(in wstring aName); +}; + +%{C++ + +// {E638D760-8687-11d2-B530-000000000000} +#define NS_BOOKMARKS_SERVICE_CID \ +{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } + +#define NS_BOOKMARKS_SERVICE_PROGID \ + "component://netscape/browser/bookmarks" + +#define NS_BOOKMARKS_DATASOURCE_PROGID \ + "component://netscape/rdf/datasource?name=bookmarks" + +%} diff --git a/mozilla/xpfe/components/bookmarks/resources/MANIFEST b/mozilla/xpfe/components/bookmarks/resources/MANIFEST new file mode 100644 index 00000000000..65dfb051e2b --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/MANIFEST @@ -0,0 +1,10 @@ +bm-panel.xul +bm-props.xul +bookmark-folder-closed.gif +bookmark-folder-open.gif +bookmark-item.gif +bookmarks.css +bookmarks.html +bookmarks.js +bookmarks.xul + diff --git a/mozilla/xpfe/components/bookmarks/resources/Makefile.in b/mozilla/xpfe/components/bookmarks/resources/Makefile.in new file mode 100644 index 00000000000..ba5ea0eeddc --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/Makefile.in @@ -0,0 +1,42 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/rules.mk + +FILES = \ + bm-panel.xul \ + bm-props.xul \ + bookmark-folder-closed.gif \ + bookmark-folder-open.gif \ + bookmark-item.gif \ + bookmarks.css \ + bookmarks.html \ + bookmarks.js \ + bookmarks.xul \ + $(NULL) + +FILES := $(addprefix $(srcdir)/, $(FILES)) + +install:: + $(INSTALL) $(FILES) $(DIST)/bin/res/rdf diff --git a/mozilla/xpfe/components/bookmarks/resources/bm-panel.xul b/mozilla/xpfe/components/bookmarks/resources/bm-panel.xul new file mode 100644 index 00000000000..c6106181380 --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/bm-panel.xul @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + Name + + + + URL + + + + + + + + + diff --git a/mozilla/xpfe/components/bookmarks/resources/bm-props.xul b/mozilla/xpfe/components/bookmarks/resources/bm-props.xul new file mode 100644 index 00000000000..fa98c9fa0be --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/bm-props.xul @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ Name: + + +
+ Location: + + +
+ Shortcut: + + +
+ Description: + + +
+
+
+ + + +
+
+
diff --git a/mozilla/xpfe/components/bookmarks/resources/bookmark-folder-closed.gif b/mozilla/xpfe/components/bookmarks/resources/bookmark-folder-closed.gif new file mode 100644 index 00000000000..d8f072037f3 Binary files /dev/null and b/mozilla/xpfe/components/bookmarks/resources/bookmark-folder-closed.gif differ diff --git a/mozilla/xpfe/components/bookmarks/resources/bookmark-folder-open.gif b/mozilla/xpfe/components/bookmarks/resources/bookmark-folder-open.gif new file mode 100644 index 00000000000..12e67a19417 Binary files /dev/null and b/mozilla/xpfe/components/bookmarks/resources/bookmark-folder-open.gif differ diff --git a/mozilla/xpfe/components/bookmarks/resources/bookmark-item.gif b/mozilla/xpfe/components/bookmarks/resources/bookmark-item.gif new file mode 100644 index 00000000000..02d55f528ed Binary files /dev/null and b/mozilla/xpfe/components/bookmarks/resources/bookmark-item.gif differ diff --git a/mozilla/xpfe/components/bookmarks/resources/bookmarks.css b/mozilla/xpfe/components/bookmarks/resources/bookmarks.css new file mode 100644 index 00000000000..ae8c2f9174d --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/bookmarks.css @@ -0,0 +1,126 @@ +window { + display: block; + background-color: #FFFFFF; +} + +menubar { + display: none; +} + +tree { + display: table; + background-color: #FFFFFF; + border: none; + border-spacing: 0px; + width: 100%; +} + +treecol { + display: table-column; + width: 200px; +} + +treeitem { + display: table-row; +} + +treehead { + display: table-header-group; +} + +treebody { + display: table-row-group; +} + +treecell { + display: table-cell; + font-family: Verdana, Sans-Serif; + font-size: 8pt; +} + +treecell[selectedcell] { + background-color: yellow; + } + +treecell[sortActive="true"][sortDirection="ascending"] { + background-color: green; + } + +treecell[sortActive="true"][sortDirection="descending"] { + background-color: red; + } + +treecol[sortActive="true"] { + background-color: lightgreen; +} + +treehead treeitem treecell { + background-color: #c0c0c0; + border: outset 1px; + border-color: white #707070 #707070 white; + padding-left: 4px; +} + +treecell[selectedcell] { + background-color: yellow; +} + +treeitem[container="true"][open="true"][loading="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/loading.gif") ! important ; +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-folder-closed.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-folder-open.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"][id="NC:PersonalToolbarFolder"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/personal-folder-closed.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Folder"][id="NC:PersonalToolbarFolder"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/personal-folder-open.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#BookmarkSeparator"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-item.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#IEFavorite"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/IEFavorite.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#Bookmark"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/bookmark-item.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#FileSystemObject"][container="true"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-open.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#FileSystemObject"][container="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-closed.gif"); +} + +treeitem[type="http://home.netscape.com/NC-rdf#FileSystemObject"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/article.gif"); +} + +treeitem[container="true"][open="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-open.gif"); +} + +treeitem[container="true"] > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/folder-closed.gif"); +} + +treeitem > treecell > titledbutton { + list-style-image: url("resource:/res/rdf/document.gif"); +} + +titledbutton#bookmarks { + list-style-image:url("resource:/res/rdf/bookmark-item.gif"); +} diff --git a/mozilla/xpfe/components/bookmarks/resources/bookmarks.html b/mozilla/xpfe/components/bookmarks/resources/bookmarks.html new file mode 100644 index 00000000000..aaccc1d7d5b --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/bookmarks.html @@ -0,0 +1,151 @@ + + +Bookmarks for temp +

Bookmarks for temp

+ +

+

Sample FTP URLs

+

+

FTP: Netscape +
FTP: XPNav +

+

Sample SmartFind queries

+

+

Find: Bookmark Names containing 'Netscape' +
Find: Bookmark Names starting with 'A' +
Find: Bookmark Names ending with '.com' +
Find: Bookmark Names containing 'Mac' +
Find: Bookmark URLs containing 'mac' +

+

Personal Toolbar Folder

+

+

Mozilla.org +
Tinderbox +
Bonsai +
Bugzilla +

Channels

+

+

Autos +
Business +
Computing and Internet +
Education +
Entertainment +
Games +
Health +
Kids and Family +
Lifestyles +
Local +
Netscape +
News +
Personal Finance +
Real Estate +
Shopping +
Sports +
Travel +

+

+


+

Search

+

+

Alta Vista +
Excite +
GoTo.com +
Infoseek +
LookSmart +
Lycos +
Netscape Search +

+

Business and Finance

+

+

Career Center +
CBS.MarketWatch +
Datek Online +
dbusiness.com +
Gartner Group, Inc. +
NextCard Internet Visa +
Personal Finance +
Small Business Source +
Virtual Office by Netopia +

+

Computers and Internet

+

+

@vantage +
Computing Channel +
Netscape Channel +
ONSALE Computer Auctions +
Open Studio +
Professional Connections +
SmartUpdate +
Toshiba +

+

Directories

+

+

GTE SuperPages +
Member Directory +
Netcenter Yellow Pages +
People +
Thomas Register +
Web Directory +
YellowPages AtHand +

+

Entertainment and Lifestyle

+

+

Entertainment Channel +
Games +
Health +
Kids and Family +
Lifestyle Channel +
theglobe.com community +
TV Guide +
Women.com +

+

News and Sports

+

+

ABCNEWS.com +
Business Journal +
CBS SportsLine +
In-Box Direct +
News Channel +
Sports Channel +

+

Shopping and Classifieds

+

+

Amazon.com +
Audio Book Club +
DealDeal.com Auctions +
FreeRide +
FTD Flowers +
Music Boulevard +
netMarket +
Real Estate +
Rent.Net +
Software Depot +

+

Travel and Leisure

+

+

Leisure Planet +
Local +
Renaissance Cruises +
Travelocity +

+

Macintosh Resources

+

+

Mac OS Rumors +
MacSurfer +
Macintouch +
MacWEEK +
O'Grady's Mac PowerPage +

+

AAA URLs with no redirection

+

+

Netscape +
Yahoo +
AOL +

+


+

Personal Bookmarks

+

+

+

diff --git a/mozilla/xpfe/components/bookmarks/resources/bookmarks.js b/mozilla/xpfe/components/bookmarks/resources/bookmarks.js new file mode 100644 index 00000000000..ab13daf76e8 --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/bookmarks.js @@ -0,0 +1,131 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + + Script for the bookmarks properties window + +*/ + +function BookmarksNewWindow() +{ + // XXX This needs to be "window.open()", I think... + var toolkitCore = XPAppCoresManager.Find("toolkitCore"); + if (!toolkitCore) { + toolkitCore = new ToolkitCore(); + if (toolkitCore) { + toolkitCore.Init("toolkitCore"); + } + } + if (toolkitCore) { + toolkitCore.ShowWindow("resource://res/rdf/bookmarks.xul",window); + } +} + +function BookmarkProperties() +{ + var tree = document.getElementById('bookmarksTree'); + var select_list = tree.getElementsByAttribute("selected", "true"); + + if (select_list.length >= 1) { + dump("Bookmark Properties: Have selection\n"); + var propsCore = XPAppCoresManager.Find(select_list[0].id); + if (!propsCore) { + dump("Bookmark Properties: no existing appcore\n"); + var propsCore = new DOMPropsCore(); + if (propsCore) { + dump("Bookmark Properties: initing new appcore\n"); + propsCore.Init(select_list[0].id); + } else { + dump("Bookmark Properties: failed to create new appcore\n"); + } + } + if (propsCore) { + dump("Bookmark Properties: opening new window\n"); + propsCore.showProperties("resource://res/rdf/bm-props.xul", + window, select_list[0]); + return true; + } + } else { + dump("nothing selected!\n"); + } + return false; +} + +function OpenURL(event,node) +{ + if (node.getAttribute('container') == "true") { + return false; + } + url = node.getAttribute('id'); + + // Ignore "NC:" urls. + if (url.substring(0, 3) == "NC:") { + return false; + } + + /*window.open(url,'bookmarks');*/ + var toolkitCore = XPAppCoresManager.Find("ToolkitCore"); + if (!toolkitCore) { + toolkitCore = new ToolkitCore(); + if (toolkitCore) { + toolkitCore.Init("ToolkitCore"); + } + } + if (toolkitCore) { + toolkitCore.ShowWindow(url,window); + } + + dump("OpenURL(" + url + ")\n"); + + return true; +} + +function doSort(sortColName) +{ + var node = document.getElementById(sortColName); + // determine column resource to sort on + var sortResource = node.getAttribute('resource'); + if (!node) return(false); + + var sortDirection="ascending"; + var isSortActive = node.getAttribute('sortActive'); + if (isSortActive == "true") { + var currentDirection = node.getAttribute('sortDirection'); + if (currentDirection == "ascending") + sortDirection = "descending"; + else if (currentDirection == "descending") + sortDirection = "natural"; + else + sortDirection = "ascending"; + } + + // get RDF Core service + var rdfCore = XPAppCoresManager.Find("RDFCore"); + if (!rdfCore) { + rdfCore = new RDFCore(); + if (!rdfCore) { + return(false); + } + rdfCore.Init("RDFCore"); +// XPAppCoresManager.Add(rdfCore); + } + // sort!!! + rdfCore.doSort(node, sortResource, sortDirection); + return(false); +} diff --git a/mozilla/xpfe/components/bookmarks/resources/bookmarks.xul b/mozilla/xpfe/components/bookmarks/resources/bookmarks.xul new file mode 100644 index 00000000000..bd3aa1143a7 --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/bookmarks.xul @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &tree.header.name.label; + + + + &tree.header.url.label; + + + + &tree.header.shortcut.label; + + + + + + + + diff --git a/mozilla/xpfe/components/bookmarks/resources/makefile.win b/mozilla/xpfe/components/bookmarks/resources/makefile.win new file mode 100644 index 00000000000..e72ecbeed6b --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/resources/makefile.win @@ -0,0 +1,39 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\.. + +FILES=\ + bm-panel.xul \ + bm-props.xul \ + bookmark-folder-closed.gif \ + bookmark-folder-open.gif \ + bookmark-item.gif \ + bookmarks.css \ + bookmarks.html \ + bookmarks.js \ + bookmarks.xul \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +install:: $(FILES:/=\) + !@$(MAKE_INSTALL) $** $(DIST)\bin\res\rdf + +clobber:: $(FILES:/=\) + !$(RM) $(DIST)\bin\res\samples\$** + diff --git a/mozilla/xpfe/components/bookmarks/src/Makefile.in b/mozilla/xpfe/components/bookmarks/src/Makefile.in new file mode 100644 index 00000000000..751d1d8cb3f --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/src/Makefile.in @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE=bookmarks +LIBRARY_NAME=bookmarks +IS_COMPONENT=1 + +CPPSRCS=\ + nsBookmarksService.cpp \ + $(NULL) + +EXTRA_DSO_LDOPTS = \ + $(MKSHLIB_FORCE_ALL) \ + $(SHARED_LIBRARY_LIBS) \ + $(MKSHLIB_UNFORCE_ALL) \ + -L$(DIST)/bin \ + -L$(DIST)/lib \ + -lxpcom \ + $(NSPR_LIBS) \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + + diff --git a/mozilla/xpfe/components/bookmarks/src/makefile.win b/mozilla/xpfe/components/bookmarks/src/makefile.win new file mode 100644 index 00000000000..4771ec8e65c --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/src/makefile.win @@ -0,0 +1,49 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\.. +MODULE=bookmarks + +CPPSRCS= \ + nsBookmarksService.obj \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\nsBookmarksService.obj \ + $(NULL) + +MAKE_OBJ_TYPE=DLL +DLLNAME = bookmarks +DLL=.\$(OBJDIR)\$(DLLNAME).dll + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +# These are the libraries we need to link with to create the DLL +LLIBS= \ + $(DIST)\lib\xpcom.lib \ + $(DIST)\lib\plc3.lib \ + $(LIBNSPR) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +install:: $(DLL) + $(MAKE_INSTALL) $(DLL) $(DIST)\bin\components + diff --git a/mozilla/xpfe/components/bookmarks/src/nsBookmarksService.cpp b/mozilla/xpfe/components/bookmarks/src/nsBookmarksService.cpp new file mode 100644 index 00000000000..ea0252f97bf --- /dev/null +++ b/mozilla/xpfe/components/bookmarks/src/nsBookmarksService.cpp @@ -0,0 +1,1618 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; c-file-style: "stroustrup" -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + + The global bookmarks service. + + */ + +#include "nsCOMPtr.h" +#include "nsFileSpec.h" +#include "nsFileStream.h" +#include "nsIBookmarksService.h" +#include "nsIComponentManager.h" +#include "nsIGenericFactory.h" +#include "nsIRDFContainer.h" +#include "nsIRDFContainerUtils.h" +#include "nsIRDFDataSource.h" +#include "nsIRDFNode.h" +#include "nsIRDFService.h" +#include "nsIServiceManager.h" +#include "nsRDFCID.h" +#include "nsSpecialSystemDirectory.h" +#include "nsString.h" +#include "nsVoidArray.h" +#include "nsXPIDLString.h" +#include "prio.h" +#include "prlog.h" +#include "rdf.h" +#include "xp_core.h" + +//////////////////////////////////////////////////////////////////////// + +static NS_DEFINE_CID(kBookmarksServiceCID, NS_BOOKMARKS_SERVICE_CID); +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); +static NS_DEFINE_CID(kGenericFactoryCID, NS_GENERICFACTORY_CID); +static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); +static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); +static NS_DEFINE_CID(kRDFContainerCID, NS_RDFCONTAINER_CID); +static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +static const char kURINC_BookmarksRoot[] = "NC:BookmarksRoot"; // XXX? +static const char kURINC_IEFavoritesRoot[] = "NC:IEFavoritesRoot"; // XXX? +static const char kURINC_PersonalToolbarFolder[] = "NC:PersonalToolbarFolder"; // XXX? + +static const char kPersonalToolbarFolder[] = "Personal Toolbar Folder"; + + +//////////////////////////////////////////////////////////////////////// + +PRInt32 gRefCnt; +nsIRDFService* gRDF; +nsIRDFContainerUtils* gRDFC; +nsIRDFResource* kNC_Bookmark; +nsIRDFResource* kNC_BookmarkSeparator; +nsIRDFResource* kNC_BookmarkAddDate; +nsIRDFResource* kNC_BookmarksRoot; +nsIRDFResource* kNC_Description; +nsIRDFResource* kNC_Folder; +nsIRDFResource* kNC_IEFavorite; +nsIRDFResource* kNC_IEFavoritesRoot; +nsIRDFResource* kNC_Name; +nsIRDFResource* kNC_PersonalToolbarFolder; +nsIRDFResource* kNC_ShortcutURL; +nsIRDFResource* kNC_URL; +nsIRDFResource* kRDF_type; +nsIRDFResource* kWEB_LastModifiedDate; +nsIRDFResource* kWEB_LastVisitDate; + +static nsresult +bm_AddRefGlobals() +{ + if (gRefCnt++ == 0) { + nsresult rv; + rv = nsServiceManager::GetService(kRDFServiceCID, + nsIRDFService::GetIID(), + (nsISupports**) &gRDF); + + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); + if (NS_FAILED(rv)) return rv; + + + rv = nsServiceManager::GetService(kRDFContainerUtilsCID, + nsIRDFContainerUtils::GetIID(), + (nsISupports**) &gRDFC); + + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF container utils"); + if (NS_FAILED(rv)) return rv; + + gRDF->GetResource(NC_NAMESPACE_URI "Bookmark", &kNC_Bookmark); + gRDF->GetResource(NC_NAMESPACE_URI "BookmarkSeparator", &kNC_BookmarkSeparator); + gRDF->GetResource(NC_NAMESPACE_URI "BookmarkAddDate", &kNC_BookmarkAddDate); + gRDF->GetResource(NC_NAMESPACE_URI "BookmarksRoot", &kNC_BookmarksRoot); + gRDF->GetResource(NC_NAMESPACE_URI "Description", &kNC_Description); + gRDF->GetResource(NC_NAMESPACE_URI "Folder", &kNC_Folder); + gRDF->GetResource(NC_NAMESPACE_URI "IEFavorite", &kNC_IEFavorite); + gRDF->GetResource(NC_NAMESPACE_URI "IEFavoritesRoot", &kNC_IEFavoritesRoot); + gRDF->GetResource(NC_NAMESPACE_URI "Name", &kNC_Name); + gRDF->GetResource(NC_NAMESPACE_URI "PersonalToolbarFolder", &kNC_PersonalToolbarFolder); + gRDF->GetResource(NC_NAMESPACE_URI "ShortcutURL", &kNC_ShortcutURL); + gRDF->GetResource(NC_NAMESPACE_URI "URL", &kNC_URL); + gRDF->GetResource(RDF_NAMESPACE_URI "type", &kRDF_type); + gRDF->GetResource(WEB_NAMESPACE_URI "LastModifiedDate", &kWEB_LastModifiedDate); + gRDF->GetResource(WEB_NAMESPACE_URI "LastVisitDate", &kWEB_LastVisitDate); + } + return NS_OK; +} + + +static void +bm_ReleaseGlobals() +{ + if (--gRefCnt == 0) + { + if (gRDF) + nsServiceManager::ReleaseService(kRDFServiceCID, gRDF); + + if (gRDFC) + nsServiceManager::ReleaseService(kRDFContainerUtilsCID, gRDFC); + + NS_IF_RELEASE(kNC_Bookmark); + NS_IF_RELEASE(kNC_BookmarkSeparator); + NS_IF_RELEASE(kNC_BookmarkAddDate); + NS_IF_RELEASE(kNC_BookmarksRoot); + NS_IF_RELEASE(kNC_Description); + NS_IF_RELEASE(kNC_Folder); + NS_IF_RELEASE(kNC_IEFavorite); + NS_IF_RELEASE(kNC_IEFavoritesRoot); + NS_IF_RELEASE(kNC_Name); + NS_IF_RELEASE(kNC_PersonalToolbarFolder); + NS_IF_RELEASE(kNC_ShortcutURL); + NS_IF_RELEASE(kNC_URL); + NS_IF_RELEASE(kRDF_type); + NS_IF_RELEASE(kWEB_LastModifiedDate); + NS_IF_RELEASE(kWEB_LastVisitDate); + } +} + + +//////////////////////////////////////////////////////////////////////// + +/** + * The bookmark parser knows how to read bookmarks.html and convert it + * into an RDF graph. + */ +class BookmarkParser { +private: + nsInputFileStream *mStream; + nsIRDFDataSource *mDataSource; + const char *mIEFavoritesRoot; + PRBool mFoundIEFavoritesRoot; + +protected: + nsresult AssertTime(nsIRDFResource* aSource, + nsIRDFResource* aLabel, + PRInt32 aTime); + + nsresult CreateAnonymousResource(nsCOMPtr* aResult); + + nsresult ParseBookmark(const nsString& aLine, nsIRDFResource* aContainer, nsIRDFResource *nodeType); + nsresult ParseBookmarkHeader(const nsString& aLine, nsIRDFResource* aContainer, nsIRDFResource *nodeType); + nsresult ParseBookmarkSeparator(const nsString& aLine, nsIRDFResource* aContainer); + nsresult ParseHeaderBegin(const nsString& aLine, nsIRDFResource* aContainer); + nsresult ParseHeaderEnd(const nsString& aLine); + nsresult ParseAttribute(const nsString& aLine, + const char* aAttribute, + PRInt32 aAttributeLen, + nsString& aResult); + +public: + BookmarkParser(); + ~BookmarkParser(); + + nsresult Init(nsInputFileStream *aStream, nsIRDFDataSource *aDataSource); + nsresult Parse(nsIRDFResource* aContainer, nsIRDFResource *nodeType); + + nsresult AddBookmark(nsIRDFResource* aContainer, + const char* aURL, + const PRUnichar* aOptionalTitle, + PRInt32 aAddDate, + PRInt32 aLastVisitDate, + PRInt32 aLastModifiedDate, + const char* aShortcutURL, + nsIRDFResource* aNodeType); + + nsresult SetIEFavoritesRoot(const char *IEFavoritesRootURL) + { + mIEFavoritesRoot = IEFavoritesRootURL; + return(NS_OK); + } + nsresult ParserFoundIEFavoritesRoot(PRBool *foundIEFavoritesRoot) + { + *foundIEFavoritesRoot = mFoundIEFavoritesRoot; + return(NS_OK); + } +}; + + +BookmarkParser::BookmarkParser() +{ + bm_AddRefGlobals(); +} + +nsresult +BookmarkParser::Init(nsInputFileStream *aStream, nsIRDFDataSource *aDataSource) +{ + mStream = aStream; + mDataSource = aDataSource; + mIEFavoritesRoot = nsnull; + mFoundIEFavoritesRoot = PR_FALSE; + return(NS_OK); +} + +BookmarkParser::~BookmarkParser() +{ + bm_ReleaseGlobals(); +} + +static const char kHREFEquals[] = "HREF=\""; +static const char kCloseAnchor[] = ""; + +static const char kOpenHeading[] = "= 0) { + rv = ParseBookmark(line, aContainer, nodeType); + } + else if ((offset = line.Find(kOpenHeading)) >= 0 && + nsString::IsDigit(line.CharAt(offset + 2))) { + // XXX Ignore

so that bookmarks root _is_

+ if (line.CharAt(offset + 2) != PRUnichar('1')) + rv = ParseBookmarkHeader(line, aContainer, nodeType); + } + else if ((offset = line.Find(kSeparator)) >= 0) { + rv = ParseBookmarkSeparator(line, aContainer); + } + else if ((offset = line.Find(kCloseUL)) >= 0 || + (offset = line.Find(kCloseMenu)) >= 0 || + (offset = line.Find(kCloseDL)) >= 0) { + return ParseHeaderEnd(line); + } + else if ((offset = line.Find(kOpenUL)) >= 0 || + (offset = line.Find(kOpenMenu)) >= 0 || + (offset = line.Find(kOpenDL)) >= 0) { + rv = ParseHeaderBegin(line, aContainer); + } + else { + // XXX Discard the line. We should be treating this as the + // description. + } + } + return rv; +} + + +nsresult +BookmarkParser::CreateAnonymousResource(nsCOMPtr* aResult) +{ + static PRInt32 gNext = 0; + if (! gNext) { + LL_L2I(gNext, PR_Now()); + } + nsAutoString uri(kURINC_BookmarksRoot); + uri.Append("$"); + uri.Append(gNext, 16); + + return gRDF->GetUnicodeResource(uri.GetUnicode(), getter_AddRefs(*aResult)); +} + +nsresult +BookmarkParser::ParseBookmark(const nsString& aLine, nsIRDFResource* aContainer, nsIRDFResource *nodeType) +{ + NS_PRECONDITION(aContainer != nsnull, "null ptr"); + if (! aContainer) + return NS_ERROR_NULL_POINTER; + + PRInt32 start = aLine.Find(kHREFEquals); + NS_ASSERTION(start >= 0, "no 'HREF=\"' string: how'd we get here?"); + if (start < 0) + return NS_ERROR_UNEXPECTED; + + // 1. Crop out the URL + + // Skip past the first double-quote + start += (sizeof(kHREFEquals) - 1); + + // ...and find the next so we can chop the URL. + PRInt32 end = aLine.Find(PRUnichar('"'), start); + NS_ASSERTION(end >= 0, "unterminated string"); + if (end < 0) + return NS_ERROR_UNEXPECTED; + + nsAutoString url; + aLine.Mid(url, start, end - start); + + { + // Now do properly replace %22's (this is what 4.5 did, anyway...) + static const char kEscape22[] = "%22"; + PRInt32 offset; + while ((offset = url.Find(kEscape22)) >= 0) { + url.SetCharAt(' ',offset); + url.Cut(offset + 1, sizeof(kEscape22) - 2); + } + } + + // XXX At this point, the URL may be relative. 4.5 called into + // netlib to make an absolute URL, and there was some magic + // "relative_URL" parameter that got sent down as well. We punt on + // that stuff. + + // 2. Parse the name + + start = aLine.Find(PRUnichar('>'), end + 1); // 'end' still points to the end of the URL + NS_ASSERTION(start >= 0, "open anchor tag not terminated"); + if (start < 0) + return NS_ERROR_UNEXPECTED; + + nsAutoString name; + aLine.Right(name, aLine.Length() - (start + 1)); + + end = name.Find(kCloseAnchor); + NS_ASSERTION(end >= 0, "anchor tag not terminated"); + if (end < 0) + return NS_ERROR_UNEXPECTED; + + name.Truncate(end); + + // 3. Parse the target + nsAutoString target; + + start = aLine.Find(kTargetEquals); + if (start >= 0) { + start += (sizeof(kTargetEquals) - 1); + end = aLine.Find(PRUnichar('"'), start); + aLine.Mid(target, start, end - start); + } + + + // 4. Parse the addition date + PRInt32 addDate = 0; + + { + nsAutoString s; + ParseAttribute(aLine, kAddDateEquals, sizeof(kAddDateEquals) - 1, s); + if (s.Length() > 0) { + PRInt32 err; + addDate = s.ToInteger(&err); // ignored. + } + } + + // 5. Parse the last visit date + + PRInt32 lastVisitDate = 0; + + { + nsAutoString s; + ParseAttribute(aLine, kLastVisitEquals, sizeof(kLastVisitEquals) - 1, s); + if (s.Length() > 0) { + PRInt32 err; + lastVisitDate = s.ToInteger(&err); // ignored. + } + } + + // 6. Parse the last modified date + + PRInt32 lastModifiedDate; + + { + nsAutoString s; + ParseAttribute(aLine, kLastModifiedEquals, sizeof(kLastModifiedEquals) - 1, s); + if (s.Length() > 0) { + PRInt32 err; + lastModifiedDate = s.ToInteger(&err); // ignored. + } + } + + // 7. Parse the shortcut URL + + nsAutoString shortcut; + ParseAttribute(aLine, kShortcutURLEquals, sizeof(kShortcutURLEquals) -1, shortcut); + + + // Dunno. 4.5 did it, so will we. + if (!lastModifiedDate) + lastModifiedDate = lastVisitDate; + + // XXX There was some other cruft here to deal with aliases, but + // since I have no clue what those are, I'll punt. + + char *cURL = url.ToNewCString(); + if (cURL) + { + char *cShortcutURL = shortcut.ToNewCString(); + if (! cShortcutURL) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv = AddBookmark(aContainer, + cURL, + name.GetUnicode(), + addDate, + lastVisitDate, + lastModifiedDate, + cShortcutURL, + nodeType); + + delete [] cURL; + if (cShortcutURL) delete [] cShortcutURL; + } + return(NS_OK); +} + + + + // Now create the bookmark +nsresult +BookmarkParser::AddBookmark(nsIRDFResource* aContainer, + const char* aURL, + const PRUnichar* aOptionalTitle, + PRInt32 aAddDate, + PRInt32 aLastVisitDate, + PRInt32 aLastModifiedDate, + const char* aShortcutURL, + nsIRDFResource* aNodeType) +{ + nsresult rv; + nsCOMPtr bookmark; + + if (NS_FAILED(rv = gRDF->GetResource(aURL, getter_AddRefs(bookmark) ))) + { + NS_ERROR("unable to get bookmark resource"); + return rv; + } + + PRBool result = PR_FALSE; + if (nsnull != mIEFavoritesRoot) + { + if (!PL_strcmp(aURL, mIEFavoritesRoot)) + { + mFoundIEFavoritesRoot = PR_TRUE; + } + } + + nsCOMPtr container; + rv = nsComponentManager::CreateInstance(kRDFContainerCID, + nsnull, + nsIRDFContainer::GetIID(), + getter_AddRefs(container)); + if (NS_FAILED(rv)) return rv; + + rv = container->AppendElement(bookmark); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add bookmark to container"); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Assert(bookmark, kRDF_type, aNodeType, PR_TRUE); + if (rv != NS_RDF_ASSERTION_ACCEPTED) + { + NS_ERROR("unable to add bookmark to data source"); + return rv; + } + + if ((nsnull != aOptionalTitle) && (*aOptionalTitle != PRUnichar('\0'))) + { + nsCOMPtr literal; + if (NS_FAILED(rv = gRDF->GetLiteral(aOptionalTitle, getter_AddRefs(literal)))) + { + NS_ERROR("unable to create literal for bookmark name"); + return rv; + } + + rv = mDataSource->Assert(bookmark, kNC_Name, literal, PR_TRUE); + if (rv != NS_RDF_ASSERTION_ACCEPTED) + { + NS_ERROR("unable to set bookmark name"); + return rv; + } + } + + AssertTime(bookmark, kNC_BookmarkAddDate, aAddDate); + AssertTime(bookmark, kWEB_LastVisitDate, aLastVisitDate); + AssertTime(bookmark, kWEB_LastModifiedDate, aLastModifiedDate); + + if ((nsnull != aShortcutURL) && (*aShortcutURL != '\0')) + { + nsCOMPtr shortcutLiteral; + if (NS_FAILED(rv = gRDF->GetLiteral(nsAutoString(aShortcutURL).GetUnicode(), + getter_AddRefs(shortcutLiteral)))) + { + NS_ERROR("unable to get literal for bookmark shortcut URL"); + return(rv); + } + if (rv != NS_RDF_NO_VALUE) + { + rv = mDataSource->Assert(bookmark, + kNC_ShortcutURL, + shortcutLiteral, + PR_TRUE); + + if (rv != NS_RDF_ASSERTION_ACCEPTED) + { + NS_ERROR("unable to set bookmark shortcut URL"); + return(rv); + } + } + } + + return(NS_OK); +} + + + +nsresult +BookmarkParser::ParseBookmarkHeader(const nsString& aLine, nsIRDFResource* aContainer, nsIRDFResource *nodeType) +{ + // Snip out the header + PRInt32 start = aLine.Find(kOpenHeading); + NS_ASSERTION(start >= 0, "couldn't find ''), start); // skip to the end of the '' tag + + if (start < 0) { + NS_WARNING("couldn't find end of header tag"); + return NS_OK; + } + + nsAutoString name; + aLine.Right(name, aLine.Length() - (start + 1)); + + PRInt32 end = name.Find(kCloseHeading); + if (end < 0) + NS_WARNING("No '= 0) + name.Truncate(end); + + // Find the add date + PRInt32 addDate = 0; + + nsAutoString s; + ParseAttribute(aLine, kAddDateEquals, sizeof(kAddDateEquals) - 1, s); + if (s.Length() > 0) { + PRInt32 err; + addDate = s.ToInteger(&err); // ignored + } + + nsAutoString id; + ParseAttribute(aLine, kIDEquals, sizeof(kIDEquals) - 1, id); + + // Make the necessary assertions + nsresult rv; + nsCOMPtr folder; + if (id.Length() > 0) { + // Use the ID attribute, if one is set. + rv = gRDF->GetUnicodeResource(id.GetUnicode(), getter_AddRefs(folder)); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create resource for folder"); + if (NS_FAILED(rv)) return rv; + } + else if (name.Equals(kPersonalToolbarFolder)) { // XXX I18n!!! + folder = dont_QueryInterface( kNC_PersonalToolbarFolder ); + } + else { + // We've never seen this folder before. Assign it an anonymous ID + rv = CreateAnonymousResource(&folder); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create anonymous resource for folder"); + if (NS_FAILED(rv)) return rv; + } + + nsCOMPtr literal; + rv = gRDF->GetLiteral(name.GetUnicode(), getter_AddRefs(literal)); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create literal for folder name"); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Assert(folder, kNC_Name, literal, PR_TRUE); + if (rv != NS_RDF_ASSERTION_ACCEPTED) { + NS_ERROR("unable to set folder name"); + return rv; + } + + nsCOMPtr container; + rv = nsComponentManager::CreateInstance(kRDFContainerCID, + nsnull, + nsIRDFContainer::GetIID(), + getter_AddRefs(container)); + if (NS_FAILED(rv)) return rv; + + rv = container->AppendElement(folder); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add bookmark to container"); + if (NS_FAILED(rv)) return rv; + + rv = gRDFC->MakeSeq(mDataSource, folder, nsnull); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to make new folder as sequence"); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Assert(folder, kRDF_type, kNC_Folder, PR_TRUE); + if (rv != NS_RDF_ASSERTION_ACCEPTED) { + NS_ERROR("unable to mark new folder as folder"); + return rv; + } + + if (NS_FAILED(rv = AssertTime(folder, kNC_BookmarkAddDate, addDate))) { + NS_ERROR("unable to mark add date"); + return rv; + } + + // And now recursively parse the rest of the file... + + if (NS_FAILED(rv = Parse(folder, nodeType))) { + NS_ERROR("recursive parse of bookmarks file failed"); + return rv; + } + + return NS_OK; +} + + +nsresult +BookmarkParser::ParseBookmarkSeparator(const nsString& aLine, nsIRDFResource* aContainer) +{ + nsresult rv; + nsCOMPtr separator; + + if (NS_SUCCEEDED(rv = CreateAnonymousResource(&separator))) + { + nsAutoString defaultSeparatorName("-----"); + nsCOMPtr nameLiteral; + if (NS_SUCCEEDED(rv = gRDF->GetLiteral(defaultSeparatorName.GetUnicode(), getter_AddRefs(nameLiteral)))) + { + if (NS_SUCCEEDED(rv = mDataSource->Assert(separator, kNC_Name, nameLiteral, PR_TRUE))) + { + } + } + if (NS_SUCCEEDED(rv = mDataSource->Assert(separator, kRDF_type, kNC_BookmarkSeparator, PR_TRUE))) + { + nsCOMPtr container; + rv = nsComponentManager::CreateInstance(kRDFContainerCID, + nsnull, + nsIRDFContainer::GetIID(), + getter_AddRefs(container)); + if (NS_SUCCEEDED(rv)) + { + rv = container->AppendElement(separator); + } + } + } + return(rv); +} + + + +nsresult +BookmarkParser::ParseHeaderBegin(const nsString& aLine, nsIRDFResource* aContainer) +{ + return NS_OK; +} + + + +nsresult +BookmarkParser::ParseHeaderEnd(const nsString& aLine) +{ + return NS_OK; +} + + +nsresult +BookmarkParser::ParseAttribute(const nsString& aLine, + const char* aAttributeName, + PRInt32 aAttributeLen, + nsString& aResult) +{ + aResult.Truncate(); + + PRInt32 start = aLine.Find(aAttributeName); + if (start < 0) + return NS_OK; + + start += aAttributeLen; + PRInt32 end = aLine.Find(PRUnichar('"'), start); + aLine.Mid(aResult, start, end - start); + + return NS_OK; +} + +nsresult +BookmarkParser::AssertTime(nsIRDFResource* aSource, + nsIRDFResource* aLabel, + PRInt32 aTime) +{ + // XXX TO DO: Convert to a date literal + + nsAutoString time; + time.Append(aTime, 10); + + nsresult rv; + nsIRDFLiteral* literal; + if (NS_FAILED(rv = gRDF->GetLiteral(time.GetUnicode(), &literal))) { + NS_ERROR("unable to get literal for time"); + return rv; + } + + rv = mDataSource->Assert(aSource, aLabel, literal, PR_TRUE); + NS_ASSERTION(rv == NS_RDF_ASSERTION_ACCEPTED, "unable to assert time"); + + NS_RELEASE(literal); + return rv; +} + +//////////////////////////////////////////////////////////////////////// +// BookmarkDataSourceImpl + +class nsBookmarksService : public nsIBookmarksService, + public nsIRDFDataSource +{ +protected: + nsIRDFDataSource* mInner; + + nsresult ReadBookmarks(); + nsresult WriteBookmarks(nsIRDFDataSource *ds, nsIRDFResource *root); + nsresult WriteBookmarksContainer(nsIRDFDataSource *ds, nsOutputFileStream strm, nsIRDFResource *container, PRInt32 level); + nsresult WriteBookmarkProperties(nsIRDFDataSource *ds, nsOutputFileStream strm, nsIRDFResource *node, + nsIRDFResource *property, const char *htmlAttrib, PRBool isFirst); + PRBool CanAccept(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget); + + nsBookmarksService(); + virtual ~nsBookmarksService(); + nsresult Init(); + + friend NS_IMETHODIMP + NS_NewBookmarksService(nsISupports* aOuter, REFNSIID aIID, void** aResult); + +public: + // nsISupports + NS_DECL_ISUPPORTS + + // nsIRDFBookmarkDataSource + NS_IMETHOD AddBookmark(const char *aURI, const PRUnichar *aOptionalTitle); + NS_IMETHOD FindShortcut(const PRUnichar *aUserInput, char **aShortcutURL); + + // nsIRDFDataSource + NS_IMETHOD Init(const char* uri) { + return mInner->Init(uri); + } + + NS_IMETHOD GetURI(char* *uri) { + return mInner->GetURI(uri); + } + + NS_IMETHOD GetSource(nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + nsIRDFResource** source) { + return mInner->GetSource(property, target, tv, source); + } + + NS_IMETHOD GetSources(nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + nsISimpleEnumerator** sources) { + return mInner->GetSources(property, target, tv, sources); + } + + NS_IMETHOD GetTarget(nsIRDFResource* source, + nsIRDFResource* property, + PRBool tv, + nsIRDFNode** target); + + NS_IMETHOD GetTargets(nsIRDFResource* source, + nsIRDFResource* property, + PRBool tv, + nsISimpleEnumerator** targets) { + return mInner->GetTargets(source, property, tv, targets); + } + + NS_IMETHOD Assert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + PRBool aTruthValue); + + NS_IMETHOD Unassert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget); + + NS_IMETHOD HasAssertion(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + PRBool* hasAssertion) { + return mInner->HasAssertion(source, property, target, tv, hasAssertion); + } + + NS_IMETHOD AddObserver(nsIRDFObserver* n) { + return mInner->AddObserver(n); + } + + NS_IMETHOD RemoveObserver(nsIRDFObserver* n) { + return mInner->RemoveObserver(n); + } + + NS_IMETHOD ArcLabelsIn(nsIRDFNode* node, + nsISimpleEnumerator** labels) { + return mInner->ArcLabelsIn(node, labels); + } + + NS_IMETHOD ArcLabelsOut(nsIRDFResource* source, + nsISimpleEnumerator** labels) { + return mInner->ArcLabelsOut(source, labels); + } + + NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) { + return mInner->GetAllResources(aResult); + } + + NS_IMETHOD Flush(); + + NS_IMETHOD GetAllCommands(nsIRDFResource* source, + nsIEnumerator/**/** commands); + + NS_IMETHOD IsCommandEnabled(nsISupportsArray/**/* aSources, + nsIRDFResource* aCommand, + nsISupportsArray/**/* aArguments, + PRBool* aResult); + + NS_IMETHOD DoCommand(nsISupportsArray/**/* aSources, + nsIRDFResource* aCommand, + nsISupportsArray/**/* aArguments); + +}; + + +//////////////////////////////////////////////////////////////////////// + +nsBookmarksService::nsBookmarksService() +{ + NS_INIT_REFCNT(); +} + +nsBookmarksService::~nsBookmarksService() +{ + Flush(); + NS_RELEASE(mInner); + bm_ReleaseGlobals(); +} + + +nsresult +nsBookmarksService::Init() +{ + nsresult rv; + rv = bm_AddRefGlobals(); + if (NS_FAILED(rv)) return rv; + + rv = nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID, + nsnull, + nsIRDFDataSource::GetIID(), + (void**) &mInner); + if (NS_FAILED(rv)) return rv; + + rv = mInner->Init("rdf:bookmarks"); + if (NS_FAILED(rv)) return rv; + + rv = ReadBookmarks(); + if (NS_FAILED(rv)) return rv; + + // register this as a named data source with the RDF service + rv = gRDF->RegisterDataSource(this, PR_FALSE); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + + +NS_IMETHODIMP +NS_NewBookmarksService(nsISupports* aOuter, REFNSIID aIID, void** aResult) +{ + NS_PRECONDITION(aResult != nsnull, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aOuter == nsnull, "no aggregation"); + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + nsresult rv = NS_OK; + + nsBookmarksService* result = new nsBookmarksService(); + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + rv = result->Init(); + if (NS_SUCCEEDED(rv)) + rv = result->QueryInterface(aIID, aResult); + + if (NS_FAILED(rv)) { + delete result; + *aResult = nsnull; + return rv; + } + + return rv; +} + + +//////////////////////////////////////////////////////////////////////// + +NS_IMPL_ADDREF(nsBookmarksService); +NS_IMPL_RELEASE(nsBookmarksService); + +NS_IMETHODIMP +nsBookmarksService::QueryInterface(REFNSIID aIID, void **aResult) +{ + NS_PRECONDITION(aResult != nsnull, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (aIID.Equals(nsIBookmarksService::GetIID()) || + aIID.Equals(kISupportsIID)) + { + *aResult = NS_STATIC_CAST(nsIBookmarksService*, this); + } + else if (aIID.Equals(nsIRDFDataSource::GetIID())) { + *aResult = NS_STATIC_CAST(nsIRDFDataSource*, this); + } + else { + *aResult = nsnull; + return NS_NOINTERFACE; + } + + NS_ADDREF(this); + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// nsIBookmarksService + + +NS_IMETHODIMP +nsBookmarksService::AddBookmark(const char *aURI, const PRUnichar *aOptionalTitle) +{ + // XXX for the moment, just add it as a child of BookmarksRoot + BookmarkParser parser; + parser.Init(nsnull, NS_STATIC_CAST(nsIRDFDataSource *, this)); + nsresult rv = parser.AddBookmark(kNC_BookmarksRoot, aURI, aOptionalTitle, + 0L, 0L, 0L, nsnull, kNC_Bookmark); + if (NS_SUCCEEDED(rv)) + { + Flush(); + } + return(rv); +} + +NS_IMETHODIMP +nsBookmarksService::FindShortcut(const PRUnichar *aUserInput, char **aShortcutURL) +{ + NS_PRECONDITION(aUserInput != nsnull, "null ptr"); + if (! aUserInput) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aShortcutURL != nsnull, "null ptr"); + if (! aShortcutURL) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + nsCOMPtr literalTarget; + rv = gRDF->GetLiteral(aUserInput, getter_AddRefs(literalTarget)); + if (NS_FAILED(rv)) return rv; + + if (rv != NS_RDF_NO_VALUE) + { + nsCOMPtr source; + rv = GetSource(kNC_ShortcutURL, literalTarget, + PR_TRUE, getter_AddRefs(source)); + + if (NS_FAILED(rv)) return rv; + + if (rv != NS_RDF_NO_VALUE) + { + rv = source->GetValue(aShortcutURL); + if (NS_FAILED(rv)) return rv; + + return NS_OK; + } + } + + *aShortcutURL = nsnull; + return NS_RDF_NO_VALUE; +} + + + +//////////////////////////////////////////////////////////////////////// +// nsIRDFDataSource + + +NS_IMETHODIMP +nsBookmarksService::GetTarget(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + PRBool aTruthValue, + nsIRDFNode** aTarget) +{ + nsresult rv; + + // If they want the URL... + if (aTruthValue && aProperty == kNC_URL) { + // ...and it is in fact a bookmark... + PRBool hasAssertion; + if (NS_SUCCEEDED(mInner->HasAssertion(aSource, kRDF_type, kNC_Bookmark, PR_TRUE, &hasAssertion)) + && hasAssertion) { + + nsXPIDLCString uri; + if (NS_FAILED(rv = aSource->GetValue( getter_Copies(uri) ))) { + NS_ERROR("unable to get source's URI"); + return rv; + } + + nsAutoString ncURI(uri); + if (ncURI.Find("NC:") == 0) + { + return(NS_RDF_NO_VALUE); + } + + nsIRDFLiteral* literal; + if (NS_FAILED(rv = gRDF->GetLiteral(nsAutoString(uri).GetUnicode(), &literal))) { + NS_ERROR("unable to construct literal for URL"); + return rv; + } + + *aTarget = (nsIRDFNode*)literal; + return NS_OK; + } + } + + return mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget); +} + + +NS_IMETHODIMP +nsBookmarksService::Assert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + PRBool aTruthValue) +{ + if (CanAccept(aSource, aProperty, aTarget)) { + return mInner->Assert(aSource, aProperty, aTarget, aTruthValue); + } + else { + return NS_RDF_ASSERTION_REJECTED; + } +} + + + +NS_IMETHODIMP +nsBookmarksService::Unassert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) +{ + if (CanAccept(aSource, aProperty, aTarget)) { + return mInner->Unassert(aSource, aProperty, aTarget); + } + else { + return NS_RDF_ASSERTION_REJECTED; + } +} + + + +NS_IMETHODIMP +nsBookmarksService::Flush() +{ + return WriteBookmarks(mInner, kNC_BookmarksRoot); +} + + +NS_IMETHODIMP +nsBookmarksService::GetAllCommands(nsIRDFResource* source, + nsIEnumerator/**/** commands) +{ + NS_NOTYETIMPLEMENTED("write me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsBookmarksService::IsCommandEnabled(nsISupportsArray/**/* aSources, + nsIRDFResource* aCommand, + nsISupportsArray/**/* aArguments, + PRBool* aResult) +{ + NS_NOTYETIMPLEMENTED("write me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsBookmarksService::DoCommand(nsISupportsArray* aSources, + nsIRDFResource* aCommand, + nsISupportsArray* aArguments) +{ + NS_NOTYETIMPLEMENTED("write me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + + + +//////////////////////////////////////////////////////////////////////// +// Implementation methods + + +nsresult +nsBookmarksService::ReadBookmarks() +{ + nsresult rv; + + rv = gRDFC->MakeSeq(mInner, kNC_BookmarksRoot, nsnull); + NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to make NC:BookmarksRoot a sequence"); + if (NS_FAILED(rv)) return rv; + + nsSpecialSystemDirectory bookmarksFile(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); + + // XXX we should get this from prefs. + bookmarksFile += "res"; + bookmarksFile += "rdf"; + bookmarksFile += "bookmarks.html"; + + PRBool foundIERoot = PR_FALSE; +#ifdef XP_WIN + nsCOMPtr ieFolder; + const char *ieFavoritesURL; +#endif + { // <-- scope the stream to get the open/close automatically. + nsInputFileStream strm(bookmarksFile); + + if (! strm.is_open()) + { + NS_ERROR("unable to open file"); + return NS_ERROR_FAILURE; + } + + BookmarkParser parser; + parser.Init(&strm, NS_STATIC_CAST(nsIRDFDataSource *, this)); + +#ifdef XP_MAC + parser.SetIEFavoritesRoot(kURINC_IEFavoritesRoot); +#endif + +#ifdef XP_WIN + nsSpecialSystemDirectory ieFavoritesFile(nsSpecialSystemDirectory::Win_Favorites); + nsFileURL ieFavoritesURLSpec(ieFavoritesFile); + ieFavoritesURL = ieFavoritesURLSpec.GetAsString(); + parser.SetIEFavoritesRoot(ieFavoritesURL); +#endif + + parser.Parse(kNC_BookmarksRoot, kNC_Bookmark); + + parser.ParserFoundIEFavoritesRoot(&foundIERoot); + } // <-- scope the stream to get the open/close automatically. + + // look for and import any IE Favorites + nsAutoString ieTitle("Imported IE Favorites"); // XXX localization? + +#ifdef XP_MAC + nsSpecialSystemDirectory ieFavoritesFile(nsSpecialSystemDirectory::Mac_PreferencesDirectory); + ieFavoritesFile += "Explorer"; + ieFavoritesFile += "Favorites.html"; + + nsInputFileStream ieStream(ieFavoritesFile); + if (ieStream.is_open()) + { + if (NS_SUCCEEDED(rv = gRDFC->MakeSeq(mInner, kNC_IEFavoritesRoot, nsnull))) + { + BookmarkParser parser; + parser.Init(&ieStream, this); + parser.Parse(kNC_IEFavoritesRoot, kNC_IEFavorite); + + nsCOMPtr ieTitleLiteral; + if (NS_SUCCEEDED(rv = gRDF->GetLiteral(ieTitle.GetUnicode(), getter_AddRefs(ieTitleLiteral)))) + { + rv = mInner->Assert(kNC_IEFavoritesRoot, kNC_Name, ieTitleLiteral, PR_TRUE); + } + + // if the IE Favorites root isn't somewhere in bookmarks.html, add it + if (!foundIERoot) + { + nsCOMPtr bookmarksRoot; + rv = nsComponentManager::CreateInstance(kRDFContainerCID, + nsnull, + nsIRDFContainer::GetIID(), + getter_AddRefs(container)); + if (NS_SUCCEEDED(rv)) + { + rv = bookmarksRoot->AppendElement(kNC_IEFavoritesRoot); + } + } + } + } +#endif + +#ifdef XP_WIN + if (NS_SUCCEEDED(rv = gRDF->GetResource(ieFavoritesURL, getter_AddRefs(ieFolder)))) + { + nsCOMPtr ieTitleLiteral; + if (NS_SUCCEEDED(rv = gRDF->GetLiteral(ieTitle.GetUnicode(), getter_AddRefs(ieTitleLiteral)))) + { + rv = mInner->Assert(ieFolder, kNC_Name, ieTitleLiteral, PR_TRUE); + } + + // if the IE Favorites root isn't somewhere in bookmarks.html, add it + if (!foundIERoot) + { + nsCOMPtr container; + rv = nsComponentManager::CreateInstance(kRDFContainerCID, + nsnull, + nsIRDFContainer::GetIID(), + getter_AddRefs(container)); + if (NS_SUCCEEDED(rv)) + { + rv = container->AppendElement(ieFolder); + } + } + } +#endif + + return NS_OK; +} + + +nsresult +nsBookmarksService::WriteBookmarks(nsIRDFDataSource *ds, nsIRDFResource *root) +{ + nsSpecialSystemDirectory bookmarksFile(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); + + // XXX we should get this from prefs. + bookmarksFile += "res"; + bookmarksFile += "rdf"; + bookmarksFile += "bookmarks.html"; + + nsresult rv = NS_ERROR_FAILURE; + nsOutputFileStream strm(bookmarksFile); + if (strm.is_open()) + { + strm << "\n"; + strm << "\n"; + strm << "Bookmarks\n"; + strm << "

Bookmarks

\n\n"; + + rv = WriteBookmarksContainer(ds, strm, root, 0); + } + return(rv); +} + + +nsresult +nsBookmarksService::WriteBookmarksContainer(nsIRDFDataSource *ds, nsOutputFileStream strm, nsIRDFResource *parent, PRInt32 level) +{ + nsresult rv = NS_OK; + + nsAutoString indentationString(""); + for (PRInt32 loop=0; loop container; + rv = nsComponentManager::CreateInstance(kRDFContainerCID, + nsnull, + nsIRDFContainer::GetIID(), + getter_AddRefs(container)); + if (NS_SUCCEEDED(rv)) + { + strm << indentation; + strm << "

\n"; + + nsCOMPtr children; + if (NS_SUCCEEDED(rv = container->GetElements(getter_AddRefs(children)))) + { + PRBool more = PR_TRUE; + while (more == PR_TRUE) + { + if (NS_FAILED(rv = children->HasMoreElements(&more))) break; + if (more != PR_TRUE) break; + + nsCOMPtr iSupports; + if (NS_FAILED(rv = children->GetNext(getter_AddRefs(iSupports)))) break; + + nsCOMPtr child = do_QueryInterface(iSupports); + if (!child) break; + + PRBool isIERoot = PR_FALSE, isContainer = PR_FALSE; + if (NS_SUCCEEDED(child->EqualsResource(kNC_IEFavoritesRoot, &isIERoot))) + { + if (isIERoot == PR_FALSE) + { + if (NS_SUCCEEDED(rv = gRDFC->IsContainer(ds, child, &isContainer))) + { + } + } + } + + nsCOMPtr nameNode; + nsAutoString nameString(""); + char *name = nsnull; + if (NS_SUCCEEDED(rv = ds->GetTarget(child, kNC_Name, PR_TRUE, getter_AddRefs(nameNode)))) + { + nsCOMPtr nameLiteral = do_QueryInterface(nameNode); + PRUnichar *title = nsnull; + if (NS_SUCCEEDED(rv = nameLiteral->GetValue(&title))) + { + nameString = title; + name = nameString.ToNewCString(); + } + + } + + strm << indentation; + strm << " "; + if (isContainer == PR_TRUE) + { + strm << "

GetValue(getter_Copies(id)); + if (NS_SUCCEEDED(rv) && (id)) { + strm << (const char*) id; + } + strm << "\""; + + strm << ">"; + + // output title + if (name) strm << name; + strm << "

\n"; + rv = WriteBookmarksContainer(ds, strm, child, level+1); + } + else + { + char *url = nsnull; + if (NS_SUCCEEDED(rv = child->GetValue(&url))) + { + if (url) + { + nsAutoString uri(url); + // XXX What's the best way to determine if its a separator? + if (uri.Find(kURINC_BookmarksRoot) == 0) + { + // its a separator + strm << "
\n"; + } + else + { + strm << "
"; + // output title + if (name) strm << name; + strm << "\n"; + } + } + } + } + + if (nsnull != name) + { + delete []name; + name = nsnull; + } + + if (NS_FAILED(rv)) break; + } + + strm << indentation; + strm << "

\n"; + } + } + delete [] indentation; + return(rv); +} + + +nsresult +nsBookmarksService::WriteBookmarkProperties(nsIRDFDataSource *ds, nsOutputFileStream strm, + nsIRDFResource *child, nsIRDFResource *property, const char *htmlAttrib, PRBool isFirst) +{ + nsresult rv; + nsCOMPtr node; + if (NS_SUCCEEDED(rv = ds->GetTarget(child, property, PR_TRUE, getter_AddRefs(node)))) + { + nsCOMPtr literal = do_QueryInterface(node); + if (literal) + { + PRUnichar *literalUni = nsnull; + if (NS_SUCCEEDED(rv = literal->GetValue(&literalUni))) + { + nsAutoString literalString = literalUni; + char *attribute = literalString.ToNewCString(); + if (nsnull != attribute) + { + if (isFirst == PR_FALSE) + { + strm << " "; + } + strm << htmlAttrib; + strm << attribute; + strm << "\""; + delete [] attribute; + attribute = nsnull; + } + } + } + } + return(rv); +} + + +PRBool +nsBookmarksService::CanAccept(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) +{ + // XXX This is really crippled, and needs to be stricter. We want + // to exclude any property that isn't talking about a known + // bookmark. + nsresult rv; + + PRBool isOrdinal; + rv = gRDFC->IsOrdinalProperty(aProperty, &isOrdinal); + if (NS_FAILED(rv)) + return PR_FALSE; + + if (isOrdinal) { + return PR_TRUE; + } + else if ((aProperty != kRDF_type) || + (aProperty != kWEB_LastModifiedDate) || + (aProperty != kWEB_LastVisitDate) || + (aProperty != kNC_Name) || + (aProperty != kNC_BookmarkAddDate)) { + return PR_TRUE; + } + else { + return PR_FALSE; + } +} + +//////////////////////////////////////////////////////////////////////// +// Component Exports + +extern "C" PR_IMPLEMENT(nsresult) +NSGetFactory(nsISupports* aServiceMgr, + const nsCID &aClass, + const char *aClassName, + const char *aProgID, + nsIFactory **aFactory) +{ + NS_PRECONDITION(aFactory != nsnull, "null ptr"); + if (! aFactory) + return NS_ERROR_NULL_POINTER; + + nsIGenericFactory::ConstructorProcPtr constructor; + + if (aClass.Equals(kBookmarksServiceCID)) { + constructor = NS_NewBookmarksService; + } + else { + *aFactory = nsnull; + return NS_NOINTERFACE; // XXX + } + + nsresult rv; + NS_WITH_SERVICE1(nsIComponentManager, compMgr, aServiceMgr, kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr factory; + rv = compMgr->CreateInstance(kGenericFactoryCID, + nsnull, + nsIGenericFactory::GetIID(), + getter_AddRefs(factory)); + + if (NS_FAILED(rv)) return rv; + + rv = factory->SetConstructor(constructor); + if (NS_FAILED(rv)) return rv; + + *aFactory = factory; + NS_ADDREF(*aFactory); + return NS_OK; +} + + + +extern "C" PR_IMPLEMENT(nsresult) +NSRegisterSelf(nsISupports* aServMgr , const char* aPath) +{ + nsresult rv; + + nsCOMPtr servMgr(do_QueryInterface(aServMgr, &rv)); + if (NS_FAILED(rv)) return rv; + + NS_WITH_SERVICE1(nsIComponentManager, compMgr, servMgr, kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = compMgr->RegisterComponent(kBookmarksServiceCID, "Bookmarks", + NS_BOOKMARKS_SERVICE_PROGID, + aPath, PR_TRUE, PR_TRUE); + + rv = compMgr->RegisterComponent(kBookmarksServiceCID, "Bookmarks", + NS_BOOKMARKS_DATASOURCE_PROGID, + aPath, PR_TRUE, PR_TRUE); + + return NS_OK; +} + + + +extern "C" PR_IMPLEMENT(nsresult) +NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) +{ + nsresult rv; + + nsCOMPtr servMgr(do_QueryInterface(aServMgr, &rv)); + if (NS_FAILED(rv)) return rv; + + NS_WITH_SERVICE1(nsIComponentManager, compMgr, servMgr, kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = compMgr->UnregisterComponent(kBookmarksServiceCID, aPath); + + return NS_OK; +} + +