Merge lp://qastaging/~neal-s/do-plugins/firefoxawesomebar into lp://qastaging/do-plugins
- firefoxawesomebar
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp://qastaging/~neal-s/do-plugins/firefoxawesomebar |
Merge into: | lp://qastaging/do-plugins |
Diff against target: | None lines |
To merge this branch: | bzr merge lp://qastaging/~neal-s/do-plugins/firefoxawesomebar |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alex Launi (community) | Needs Fixing | ||
Review via email: mp+5689@code.qastaging.launchpad.net |
This proposal supersedes a proposal from 2009-04-11.
Commit message
Description of the change
Neal Stewart (neal-s) wrote : Posted in a previous version of this proposal | # |
Neal Stewart (neal-s) wrote : Posted in a previous version of this proposal | # |
Code reverted to old version somehow? Will fix in a few hours. Delay review, please.
> Another try!
>
> This version allows you to search through your Firefox Bookmarks from Gnome Do
> directly.
>
> Bookmarks and History are both provided as children of the Firefox
> Application.
Neal Stewart (neal-s) wrote : Posted in a previous version of this proposal | # |
And now it's back to where it was this afternoon.
Alex Launi (alexlauni) wrote : | # |
Usability: Arrowing into the firefox application should have two meta-items, bookmarks and history. You should then arrow into one. Currently if I arrow into firefox i am given 1000s of results just called url. This renders the window manager plugin useless since finding my window becomes impossible. Organizing these into subcategories will make this much more sane.
Fix namespaces, just use Firefox, not Mozilla.Firefox.
Fix some other mono guidelines issues, you've got a few places where your method calls are not seperated from their parameters. ex)
Foo(bar) ;
should be
Foo (bar);
Youve got an extra space between your const delcarations in FABarItemSource.cs, and are missing one between your global variable declarations and your constructor. You've got a few places with extra newlines, keep these to single blank lines.
You should not be calling UpdateItems in ChildrenOfItem that's bad news.
Do prefix Services calls with Do.Platform, it's not needed and is overly verbose.
you've got a while (null != (line = r.ReadLine ())), reverse that.
while ((line = r.ReadLine ()) != null)
Try and avoid one line conditionals, unless it makes the code more readable, use a newline for the predicate. Examples in your code:
in FABarItemSource
if (!String.
this would be better on two lines like
if (!String.
return storedProfilePath;
assign profile before home, do your assignments like this in order of line length. It makes the code prettier.
tempDatabasePath property should be TempDatabasePath
in this property the else if should be on the same line as the ending if bracket, and the else if's starting bracket should be on the same line as the else if.
Your declarations of static vars should all be together at the top.
There are some serious formatting issues in LoadFoldeItems, i'm going to blame monodevelop, but you still need to clean them up. You dont need to call dbcon.Close (), that's the point of the using statements. Can you document why you're using the parameters to GetString and GetInt32? the 0s, 1s, and 2s seem arbitrary. Make them meaningful. LoadPlaceItems () has similar criticisms to LoadFolderItems.
FABarItem's class bracket should be on the line below
organize your variable declarations by length, same for their initializations in the constructor.
- 594. By Neal Stewart <email address hidden>
-
FUNCTION CHANGES -----
Created BrowseBookmarkItem and BrowseHistoryItem.
ChildrenOfItems given for both. Provide what you'd expect.Feeding Main Firefox application those items.
Firefox Awesome Bar item provides those items, as well as Bookmarks, to
the main list.See ChildrenOfItem in FABarItemSource for details.
FORMAT CHANGES -----
Now complying to Mono standards in method calls and parameters.
Instantiated SQlite search results to provide code clarity.
Changed connection string creation from string literal to concatenated
string. - 595. By Neal Stewart <email address hidden>
-
Hopefully fixed the SQL formatting problems with Loggerhead.
..hopefully. - 596. By Neal Stewart <email address hidden>
-
Changed some method names.
- 597. By Neal Stewart <email address hidden>
-
fixins
- 598. By Neal Stewart <email address hidden>
-
Changed Collection searching to LINQ
Some housekeeping.
- 599. By Neal Stewart <email address hidden>
-
Removed Path.Combine(
Path.Combine. .. Now using Linq.
- 600. By Neal Stewart <email address hidden>
-
Changed from Community to Official.
Preview Diff
1 | === modified file 'Firefox/Firefox.mdp' |
2 | --- Firefox/Firefox.mdp 2009-02-28 16:16:48 +0000 |
3 | +++ Firefox/Firefox.mdp 2009-04-11 21:58:01 +0000 |
4 | @@ -18,12 +18,19 @@ |
5 | <File name="src" subtype="Directory" buildaction="Compile" /> |
6 | <File name="src/BookmarkItemSource.cs" subtype="Code" buildaction="Compile" /> |
7 | <File name="Resources/Firefox.addin.xml" subtype="Code" buildaction="EmbedAsResource" /> |
8 | + <File name="src/FABarItemSource.cs" subtype="Code" buildaction="Compile" /> |
9 | + <File name="src/FABarItems.cs" subtype="Code" buildaction="Compile" /> |
10 | </Contents> |
11 | <References> |
12 | <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> |
13 | <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> |
14 | - <ProjectReference type="Gac" localcopy="True" refto="Do.Platform, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null" /> |
15 | - <ProjectReference type="Gac" localcopy="True" refto="Do.Universe, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null" /> |
16 | <ProjectReference type="Gac" localcopy="True" refto="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> |
17 | + <ProjectReference type="Gac" localcopy="True" refto="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> |
18 | + <ProjectReference type="Gac" localcopy="True" refto="Mono.Data.SqliteClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> |
19 | + <ProjectReference type="Gac" localcopy="True" refto="Do.Platform, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null" /> |
20 | + <ProjectReference type="Gac" localcopy="True" refto="Do.Platform.Linux, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null" /> |
21 | + <ProjectReference type="Gac" localcopy="True" refto="Do.Universe, Version=0.9.0.0, Culture=neutral, PublicKeyToken=null" /> |
22 | + <ProjectReference type="Gac" localcopy="True" refto="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> |
23 | + <ProjectReference type="Gac" localcopy="True" refto="Mono.Data.SqliteClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> |
24 | </References> |
25 | -</Project> |
26 | \ No newline at end of file |
27 | +</Project> |
28 | |
29 | === modified file 'Firefox/Makefile.am' |
30 | --- Firefox/Makefile.am 2009-01-09 05:04:13 +0000 |
31 | +++ Firefox/Makefile.am 2009-04-11 21:58:01 +0000 |
32 | @@ -3,7 +3,8 @@ |
33 | ASSEMBLY=Firefox |
34 | |
35 | FILES = \ |
36 | - src/BookmarkItemSource.cs |
37 | + src/FABarItemSource.cs \ |
38 | + src/FABarItems.cs |
39 | |
40 | RESOURCES = \ |
41 | Resources/Firefox.addin.xml |
42 | @@ -12,5 +13,7 @@ |
43 | Mono.Posix \ |
44 | System \ |
45 | System.Core \ |
46 | + System.Data \ |
47 | + Mono.Data.SqliteClient \ |
48 | $(DO_PLATFORM_LIBS) \ |
49 | $(DO_UNIVERSE_LIBS) |
50 | |
51 | === modified file 'Firefox/Resources/Firefox.addin.xml' |
52 | --- Firefox/Resources/Firefox.addin.xml 2009-01-16 23:29:46 +0000 |
53 | +++ Firefox/Resources/Firefox.addin.xml 2009-04-11 21:58:01 +0000 |
54 | @@ -1,11 +1,11 @@ |
55 | <Addin |
56 | id="Firefox" |
57 | namespace="Do" |
58 | - version="2.2" |
59 | + version="3" |
60 | name="Firefox" |
61 | - description="Search Firefox 3 bookmarks." |
62 | - author="David Siegel" |
63 | - category="Official" |
64 | + description="Search Firefox 3 bookmarks, bookmark directories, and history." |
65 | + author="Neal Stewart" |
66 | + category="Community" |
67 | > |
68 | |
69 | <Runtime> |
70 | @@ -17,6 +17,6 @@ |
71 | </Dependencies> |
72 | |
73 | <Extension path="/Do/ItemSource"> |
74 | - <ItemSource type="Mozilla.Firefox.BookmarkItemSource" /> |
75 | + <ItemSource type="Mozilla.Firefox.FABarItemSource" /> |
76 | </Extension> |
77 | </Addin> |
78 | |
79 | === added file 'Firefox/src/FABarItemSource.cs' |
80 | --- Firefox/src/FABarItemSource.cs 1970-01-01 00:00:00 +0000 |
81 | +++ Firefox/src/FABarItemSource.cs 2009-04-12 15:14:14 +0000 |
82 | @@ -0,0 +1,285 @@ |
83 | +// FABarItemSource.cs -- Modification of BookmarkItemSource |
84 | +// |
85 | +// GNOME Do is the legal property of its developers. Please refer to the |
86 | +// COPYRIGHT file distributed with this source distribution. |
87 | +// |
88 | +// This program is free software: you can redistribute it and/or modify |
89 | +// it under the terms of the GNU General Public License as published by |
90 | +// the Free Software Foundation, either version 3 of the License, or |
91 | +// (at your option) any later version. |
92 | +// |
93 | +// This program is distributed in the hope that it will be useful, |
94 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
95 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
96 | +// GNU General Public License for more details. |
97 | +// |
98 | +// You should have received a copy of the GNU General Public License |
99 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. |
100 | +// |
101 | + |
102 | +using System; |
103 | +using System.IO; |
104 | +using System.Data; |
105 | +using System.Linq; |
106 | +using System.Collections.Generic; |
107 | + |
108 | +using Do.Universe; |
109 | +using Do.Universe.Common; |
110 | + |
111 | +using Mono.Data.SqliteClient; |
112 | +using Mono.Unix; |
113 | + |
114 | +namespace Mozilla.Firefox |
115 | +{ |
116 | + public class FABarItemSource : ItemSource |
117 | + { |
118 | + const string BeginProfileName = "Path="; |
119 | + const string BeginDefaultProfile = "Default=1"; |
120 | + |
121 | + |
122 | + List<Item> items; |
123 | + IEnumerable<PlaceItem> places; |
124 | + IEnumerable<FolderItem> folders; |
125 | + public FABarItemSource () |
126 | + { |
127 | + places = Enumerable.Empty<PlaceItem> (); |
128 | + folders = Enumerable.Empty<FolderItem> (); |
129 | + items = new List<Item> (); |
130 | + } |
131 | + |
132 | + public override IEnumerable<Type> SupportedItemTypes { |
133 | + get { |
134 | + yield return typeof (PlaceItem); |
135 | + yield return typeof (FolderItem); |
136 | + yield return typeof (IApplicationItem); |
137 | + } |
138 | + } |
139 | + |
140 | + public override string Name { |
141 | + get { return Catalog.GetString ("Firefox Bookmarks"); } |
142 | + } |
143 | + |
144 | + public override string Description { |
145 | + get { return Catalog.GetString ("Search through your bookmarks."); } |
146 | + } |
147 | + |
148 | + public override string Icon { |
149 | + get { return "firefox-3.0"; } |
150 | + } |
151 | + |
152 | + |
153 | + public override IEnumerable<Item> Items { |
154 | + get { return items; } |
155 | + } |
156 | + |
157 | + public override void UpdateItems () |
158 | + { |
159 | + this.places = LoadPlaceItems (); |
160 | + this.folders = LoadFolderItems (); |
161 | + items.Clear(); |
162 | + // Feed the main itemsource only Bookmark places and directories. |
163 | + foreach (FolderItem folder in folders) items.Add((Item) folder); |
164 | + foreach (PlaceItem place in places) |
165 | + if (place.ParentId != null) items.Add((Item) place); |
166 | + } |
167 | + |
168 | + public override IEnumerable<Item> ChildrenOfItem (Item item) { |
169 | + // If it's the Firefox Application Item, give them everything. |
170 | + if (isFirefox(item)) { |
171 | + UpdateItems(); |
172 | + foreach (Item folder in folders) yield return folder; |
173 | + foreach (Item place in places) yield return place; |
174 | + } |
175 | + |
176 | + // If it's a folder, give them its' children. |
177 | + if (isFolder(item)) { |
178 | + FolderItem parent = (FolderItem) item; |
179 | + foreach (FolderItem folder in folders) { |
180 | + if (parent.Id == folder.ParentId) yield return (Item) folder; |
181 | + } |
182 | + foreach (PlaceItem place in places) { |
183 | + if (parent.Id == place.ParentId) yield return (Item) place; |
184 | + } |
185 | + } |
186 | + } |
187 | + |
188 | + bool isFirefox(Item item) { |
189 | + return item.Equals(Do.Platform.Services.UniverseFactory.MaybeApplicationItemFromCommand("firefox")); |
190 | + } |
191 | + |
192 | + bool isFolder(Item item) { |
193 | + return item is FolderItem; |
194 | + } |
195 | + |
196 | + /// <summary> |
197 | + /// Looks in the firefox profiles file (~/.mozilla/firefox/profiles.ini) |
198 | + /// for the name of the default profile, and returns the path to the |
199 | + /// default profile. |
200 | + /// </summary> |
201 | + /// <returns> |
202 | + /// A <see cref="System.String"/> containing the absolute path to the |
203 | + /// bookmarks.html file of the default firefox profile for the current |
204 | + /// user. |
205 | + /// </returns> |
206 | + static string storedProfilePath; |
207 | + static string ProfilePath { |
208 | + get { |
209 | + string line, profile, path, home; |
210 | + |
211 | + if (!String.IsNullOrEmpty(storedProfilePath)) return storedProfilePath; |
212 | + |
213 | + home = Environment.GetFolderPath (Environment.SpecialFolder.Personal); |
214 | + profile = null; |
215 | + path = Path.Combine (home, ".mozilla/firefox/profiles.ini"); |
216 | + using (StreamReader r = File.OpenText (path)) { |
217 | + while (null != (line = r.ReadLine ())) { |
218 | + if (line.StartsWith (BeginDefaultProfile)) break; |
219 | + if (line.StartsWith (BeginProfileName)) { |
220 | + line = line.Trim (); |
221 | + line = line.Substring (BeginProfileName.Length); |
222 | + profile = line; |
223 | + } |
224 | + } |
225 | + } |
226 | + return storedProfilePath = |
227 | + Path.Combine (Path.Combine (home, ".mozilla/firefox"), profile); |
228 | + } |
229 | + } |
230 | + |
231 | + /// <summary> |
232 | + /// Looks at the file currently saved in the temp folder and sees if it |
233 | + /// needs to be updated. |
234 | + /// </summary> |
235 | + /// <returns> |
236 | + /// The path of the current database file in memory. |
237 | + /// </returns> |
238 | + static string storedTempDatabasePath; |
239 | + static string tempDatabasePath { |
240 | + get { |
241 | + // Create a reference to the current firefox file. |
242 | + string firefoxPath = Path.Combine (ProfilePath, "places.sqlite"); |
243 | + |
244 | + // Check if the stored temp file exists. |
245 | + if ((String.IsNullOrEmpty(storedTempDatabasePath)) || (!File.Exists(storedTempDatabasePath))) { |
246 | + // If it doesn't, make one. |
247 | + string copyPath = Path.GetTempFileName(); |
248 | + System.IO.File.Copy(firefoxPath, copyPath, true); |
249 | + storedTempDatabasePath = copyPath; |
250 | + } |
251 | + else if (File.Exists(storedTempDatabasePath)) |
252 | + { |
253 | + FileInfo currentFileInfo = new FileInfo(firefoxPath); |
254 | + FileInfo firefoxFileInfo = new FileInfo(storedTempDatabasePath); |
255 | + |
256 | + if (currentFileInfo.Length != firefoxFileInfo.Length) |
257 | + System.IO.File.Copy(firefoxPath, storedTempDatabasePath, true); |
258 | + } |
259 | + |
260 | + return storedTempDatabasePath; |
261 | + } |
262 | + } |
263 | + |
264 | + /// <summary> |
265 | + /// Creates the current SQL connection string to the temporary database in use. |
266 | + /// </summary> |
267 | + /// <returns> |
268 | + /// The current SQL connection string to the temporary database in use. |
269 | + /// </returns> |
270 | + string connectionString { |
271 | + get { return String.Format ("URI=file:{0},version=3",tempDatabasePath); } |
272 | + } |
273 | + |
274 | + /// <summary> |
275 | + /// Opens a connection to the current temporary database copy, |
276 | + /// and searches for bookmark directories, then adds those to |
277 | + /// the IEnumerable collection to be returned. |
278 | + /// </summary> |
279 | + /// <returns> |
280 | + /// A collection of bookmark directory Folder Items. |
281 | + /// </returns> |
282 | + IEnumerable<FolderItem> LoadFolderItems () |
283 | + { |
284 | + |
285 | + using (IDbConnection dbcon = (IDbConnection) new SqliteConnection(connectionString)) { |
286 | + dbcon.Open(); |
287 | + using (IDbCommand dbcmd = dbcon.CreateCommand()) { |
288 | + dbcmd.CommandText = @"SELECT title, |
289 | + id, |
290 | + parent |
291 | + FROM moz_bookmarks |
292 | + WHERE type = 2"; |
293 | + using (IDataReader reader = dbcmd.ExecuteReader()) { |
294 | + while(reader.Read()) { |
295 | + string title = reader.GetString(0); |
296 | + int id = reader.GetInt32(1); |
297 | + /* Firefox's parent system uses the field with ID 1 as a |
298 | + * parent for all other directories. It doesn't have a name, |
299 | + * so we'll give it one. */ |
300 | + if (id == 1) |
301 | + yield return new FolderItem("Mozilla Bookmarks", |
302 | + reader.GetInt32(1), |
303 | + reader.GetInt32(2)); |
304 | + /* Firefox uses another field that doesn't have a name. |
305 | + * It references portions of their menu that generate |
306 | + * information dynamically from History, Tags, etc. |
307 | + * Ignore it. */ |
308 | + else if (title != "") { |
309 | + yield return new FolderItem(title, |
310 | + reader.GetInt32(1), |
311 | + reader.GetInt32(2)); |
312 | + } |
313 | + } |
314 | + } |
315 | + } |
316 | + dbcon.Close(); |
317 | + } |
318 | + } |
319 | + |
320 | + /// <summary> |
321 | + /// Opens a connection to the current temporary database, and searches for all |
322 | + /// place entries then adds those to the IEnumerable collection to be returned. |
323 | + /// </summary> |
324 | + /// <returns> |
325 | + /// A collection of bookmarks and history Place Items. |
326 | + /// </returns> |
327 | + IEnumerable<PlaceItem> LoadPlaceItems () |
328 | + { |
329 | + using (IDbConnection dbcon = (IDbConnection) new SqliteConnection(connectionString)) { |
330 | + dbcon.Open(); |
331 | + using (IDbCommand dbcmd = dbcon.CreateCommand()) { |
332 | + dbcmd.CommandText = @"SELECT moz_places.title, |
333 | + moz_places.url, |
334 | + moz_bookmarks.parent, |
335 | + moz_bookmarks.title |
336 | + FROM moz_places LEFT OUTER JOIN moz_bookmarks |
337 | + ON moz_places.id=moz_bookmarks.fk |
338 | + ORDER BY moz_places.frecency DESC"; |
339 | + using (IDataReader reader = dbcmd.ExecuteReader()) { |
340 | + while(reader.Read()) { |
341 | + string url = reader.GetString(1); |
342 | + // Firefox stores some interesting non-url places. Ignore them. |
343 | + if (url[0] != 'p') { |
344 | + string title = reader.GetString(0); |
345 | + // If the place is a bookmark, use the title stored in Bookmarks. |
346 | + if (!reader.IsDBNull(2)) |
347 | + yield return new PlaceItem (reader.GetString(3), |
348 | + reader.GetString(1), |
349 | + reader.GetInt32(2)); |
350 | + // If the place has no title, use the url as a title so it's searchable. |
351 | + else if (title == "") |
352 | + yield return new PlaceItem (reader.GetString(1), |
353 | + reader.GetString(1)); |
354 | + else |
355 | + yield return new PlaceItem (title, |
356 | + reader.GetString(1)); |
357 | + } |
358 | + } |
359 | + } |
360 | + } |
361 | + dbcon.Close(); |
362 | + } |
363 | + } |
364 | + } |
365 | +} |
366 | + |
367 | + |
368 | |
369 | === added file 'Firefox/src/FABarItems.cs' |
370 | --- Firefox/src/FABarItems.cs 1970-01-01 00:00:00 +0000 |
371 | +++ Firefox/src/FABarItems.cs 2009-04-11 21:58:01 +0000 |
372 | @@ -0,0 +1,79 @@ |
373 | +// FABarItems.cs |
374 | +// GNOME Do is the legal property of its developers, whose names are too |
375 | +// numerous to list here. Please refer to the COPYRIGHT file distributed with |
376 | +// this source distribution. |
377 | +// |
378 | +// This program is free software: you can redistribute it and/or modify |
379 | +// it under the terms of the GNU General Public License as published by |
380 | +// the Free Software Foundation, either version 3 of the License, or |
381 | +// (at your option) any later version. |
382 | +// |
383 | +// This program is distributed in the hope that it will be useful, |
384 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
385 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
386 | +// GNU General Public License for more details. |
387 | +// |
388 | +// You should have received a copy of the GNU General Public License |
389 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. |
390 | + |
391 | +using System; |
392 | +using Do.Universe; |
393 | +using Do.Universe.Common; |
394 | + |
395 | + |
396 | +namespace Mozilla.Firefox |
397 | +{ |
398 | + public class FolderItem : Item { |
399 | + string title; |
400 | + int id; |
401 | + int parentID; |
402 | + |
403 | + public FolderItem (string title, int id) |
404 | + { |
405 | + this.title = title; |
406 | + this.id = id; |
407 | + } |
408 | + |
409 | + public FolderItem (string title, int id, int parentID) |
410 | + { |
411 | + this.title = title; |
412 | + this.id = id; |
413 | + this.parentID = parentID; |
414 | + } |
415 | + |
416 | + public override string Name { get { return title; } } |
417 | + public override string Description { get { return "Mozilla Firefox Bookmark Directory"; } } |
418 | + public override string Icon { get { return "folder"; } } |
419 | + public int Id { get { return id; } } |
420 | + public int ParentId { |
421 | + get { return parentID; } |
422 | + } |
423 | + } |
424 | + |
425 | + public class PlaceItem : Item, IBookmarkItem |
426 | + { |
427 | + string title, url; |
428 | + int? parentID; |
429 | + |
430 | + public PlaceItem (string title, string url) |
431 | + { |
432 | + this.title = title; |
433 | + this.url = url; |
434 | + } |
435 | + |
436 | + public PlaceItem (string title, string url, int parentID) |
437 | + { |
438 | + this.title = title; |
439 | + this.url = url; |
440 | + this.parentID = parentID; |
441 | + } |
442 | + |
443 | + public override string Name { get { return title; } } |
444 | + public override string Description { get { return url; } } |
445 | + public override string Icon { get { return "www"; } } |
446 | + public string Url { get { return url; } } |
447 | + public int? ParentId { |
448 | + get { return parentID; } |
449 | + } |
450 | + } |
451 | +} |
Another try!
This version allows you to search through your Firefox Bookmarks from Gnome Do directly.
Bookmarks and History are both provided as children of the Firefox Application.