Skip to content

Commit

Permalink
Merge pull request #1 from ahmadassaf/master
Browse files Browse the repository at this point in the history
Sync with main repo
  • Loading branch information
Immortalin committed Nov 16, 2015
2 parents 5e69a6f + 9c0361b commit e892874
Show file tree
Hide file tree
Showing 12 changed files with 1,760 additions and 635 deletions.
72 changes: 63 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Booklight](https://chrome.google.com/webstore/detail/booklight/lkdhojpobehkcldjmileiancjjpdeakk)
Booklight
==========

I got fed up wasting my time trying to navigate my way through bunch of bookmarks folder to arrange them. So if you are:
Expand All @@ -8,28 +8,82 @@ I got fed up wasting my time trying to navigate my way through bunch of bookmark

then you came to the right place. **Booklight** is a clean Chrome Extension to ease the way of adding a bookmark.

To Launch press (ctrl/Control + b) and thats it !
- To launch press (ctrl/Control + b)
- To enable bookmarks search mode hit `space` after booklight is launched

[![booklightVideo](https://www.dropbox.com/s/dgu57k0424rnjhq/booklight_video.png?dl=1)](https://www.youtube.com/watch?v=8AB1kE6U-2g)
[Download from Chrome Store](https://chrome.google.com/webstore/detail/booklight/lkdhojpobehkcldjmileiancjjpdeakk)

## Watch Booklight Video
[![booklightVideo](https://www.dropbox.com/s/dgu57k0424rnjhq/booklight_video.png?dl=1)](https://www.youtube.com/watch?v=fxqaToLRLNo)

### Features

- Filter bookmarks based on manual entry
- Show the path of the current selected folder
- Navigate easily through the folders tree using keyboard
- if the folder is highlighted in blue this means that it contains sub-folders as well. The right arrow (->) keyboard key will go inside that folder. You can go back one step to the back using the left keyboard arrow (<-)
- Bookmark directly when you find your target
- The ability to switch to urls search **NEW**
- Launching urls in current or new tab **NEW**
- Fuzzy search enabled for filtering on both folders and urls **NEW**
- Clean current URL before bookmarking (sometimes the url is polluted with query strings e.g `?source= ...` for various tracking information). To clean the url from those, hit `ctrl+alt+x` and this will solve this issue.

![booklight](http://g.recordit.co/ZsvnnFqYdu.gif)

## Bookmark Search & launch

Booklight now has the ability to search on your bookmakrs **and it is blazing fast**. I have around 20,000 bookmarks ! and through smart lazy loading and fuzzy search, you can now easily search and launch bookmarks anywhere while browsing.
To switch to the url search mode just hit `space` and then you will see that you can now search urls by having the `|` symbol in the input box.
To launch a url in the current window, simply hit `enter` and to open it in a new tab hit `ctr\control + enter`
![booklight-urls](http://g.recordit.co/aala9MAKo9.gif)

### Booklight Performance
I currently have over 1000 folders and 20,000 bookmarked urls. Booklight is blazing fast, to achieve this i implement various hacks to minimize DOM manipulations and most importantly lazy-loading of urls. The lazy loading happens in the following function:

```javascript
lazyloader: function lazyloader(elements){

var lazyloader = this;

this.elements = elements;
this.showLimit = 15;
this.urlsDOM = '';

this.load = function(empty, hide) {

var urlsDOM = '';
var currentAttachedUrls = this.urlsDOM == '' ? 0 : $('.booklight_list li[data-type="url"]').length;
var limit = this.elements.length > this.showLimit ? this.showLimit : this.elements.length;
var urlsToAdd = this.elements.slice(currentAttachedUrls, currentAttachedUrls + limit);

// the idea is build a kind of lazy loading for urls to minimize the building of the DOM elements
urlsToAdd.forEach(function(url){
urlsDOM += '<li id="' + url.id + '" data-url="' + url.url + '" data-parent="' + url.parentId + '" data-type="url">' +
'<img src="http://www.google.com/s2/favicons?domain_url=' + url.url + '"</img>' +
url.title + '</li>';
});

lazyloader.urlsDOM += urlsDOM;

booklight.UI.showSection(urlsDOM, empty, hide);
booklight.UI.updateCounter();
}
}
```
You can tweak the number of elements you want to show on every iteration and it works for both searching and filtering.

### Things i would like to do

- Add mouse interactions
- Add better logic to the star icon (at the moment it only shows when the page is successfully bookmarked) but it will not update if remove the bookmark ... etc.
- Add fuzzy search for filtering from input box
- ~~Add fuzzy search for filtering from input box~~
- Smart folder suggestions
- ~~Remember last location when going back to main screen or removing filters~~ **done**

## Life before Booklight
![before-booklight](http://g.recordit.co/uqYqp8o08e.gif)

## Life AFTER Booklight
![before-booklight](http://g.recordit.co/mprXGGOr1k.gif)

[Download from Chrome Store](https://chrome.google.com/webstore/detail/booklight/lkdhojpobehkcldjmileiancjjpdeakk)

### Thoughts

- [Google Chrome’s awful new bookmark manager (and how to switch it off)](http://blog.garethjmsaunders.co.uk/2015/04/19/google-chromes-awful-new-bookmark-manager-and-how-to-switch-it-off/)
- [Chrome users roast Google on spit of hate over revamped bookmarks manager](http://www.computerworld.com/article/2913426/web-browsers/chrome-users-roast-google-on-spit-of-hate-over-revamped-bookmarks-manager.html)
89 changes: 53 additions & 36 deletions background.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,63 @@
var foldersList = [], urls = [];
var booklight = function booklight() {

chrome.bookmarks.getTree(function(bookmarksTree) {
var booklight = this;

foldersList = filterRecursively(bookmarksTree, "children", function(node) {
if (node.url) urls.push(node);
return !node.url && node.id > 0;
}).sort(function(a, b) {
// The sort functions make sure that we will have the last used folders on top
return b.dateGroupModified - a.dateGroupModified;
});
this.foldersList = [];
this.urls = [];

this.getBookmarks = function() {

chrome.storage.local.set({"booklight": foldersList }, function(bookmarks) { console.log("Setting the folders list into the local storage !!") });
chrome.storage.local.set({"urls": urls }, function(bookmarks) { console.log("Setting the urls list into the local storage !!") });
chrome.bookmarks.getTree(function(bookmarksTree) {

});
booklight.foldersList = filterRecursively(bookmarksTree, "children", function(node) {
if (node.url) booklight.urls.push(node);
return !node.url && node.id > 0;
}).sort(function(a, b) {
// The sort functions make sure that we will have the last used folders on top
return b.dateGroupModified - a.dateGroupModified;
});

// Recursively filter the passed TreeNodes
function filterRecursively(nodeArray, childrenProperty, filterFn, results) {
chrome.storage.local.set({"booklightFolders": booklight.foldersList }, function(bookmarks) { console.log("Setting the folders list into the local storage !!") });
chrome.storage.local.set({"booklightUrls": booklight.urls }, function(bookmarks) { console.log("Setting the urls list into the local storage !!") });

});

results = results || [];
// Recursively filter the passed TreeNodes
function filterRecursively(nodeArray, childrenProperty, filterFn, results) {

results = results || [];

nodeArray.forEach( function( node ) {
if (filterFn(node)) results.push({title: node.title, id: node.id, dateGroupModified: node.dateGroupModified, folder: isLeaf(node), parentId: node.parentId});
if (node.children) filterRecursively(node.children, childrenProperty, filterFn, results);
});
return results;
};

// Check if the current bookmark is a leaf (does not contain more folders)
function isLeaf(node) {
var leafyNodes = [];
node.children.forEach(function(child){
if (!child.hasOwnProperty('children')) leafyNodes.push(1);
});
var isLeaf = leafyNodes.length == node.children.length ? true : false;
return isLeaf;
}
}

nodeArray.forEach( function( node ) {
if (filterFn(node)) results.push({title: node.title, id: node.id, dateGroupModified: node.dateGroupModified, folder: isLeaf(node), parent: node.parentId});
if (node.children) filterRecursively(node.children, childrenProperty, filterFn, results);
});
return results;
};
this.attachListeners = function() {

function isLeaf(node) {
var leafyNodes = [];
node.children.forEach(function(child){
if (!child.hasOwnProperty('children')) leafyNodes.push(1);
});
var isLeaf = leafyNodes.length == node.children.length ? true : false;
return isLeaf;
chrome.runtime.onMessage.addListener(function(request, sender, sendrequest) {
if (request.message == "booklight") {
console.log("adding: " + request.url + " title: " + request.title + " to folder id: " + request.folder);
chrome.bookmarks.create({ 'parentId': request.folder, 'title': request.title, 'url': request.url });
sendrequest({message: "success"});
}
});
}
}

chrome.runtime.onMessage.addListener(
function(request, sender, sendrequest) {
if (request.message == "booklight") {
console.log("adding: " + request.url + " title: " + request.title + " to folder id: " + request.folder);
chrome.bookmarks.create({ 'parentId': request.folder, 'title': request.title, 'url': request.url });
sendrequest({message: "success"});
}
});
var booklight = new booklight();

booklight.attachListeners();
booklight.getBookmarks();
Loading

0 comments on commit e892874

Please sign in to comment.