Bookmarks Decorators
The Bookmarks decorators allow you to easily respond to browser bookmark events in your extension services. These decorators provide a clean way to handle bookmark creation, updates, and deletions.
Method Decorators
onBookmarkCreated
This decorator handles events that fire when a bookmark is created.
import { onBookmarkCreated, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkCreated()
handleNewBookmark(arg: { id: string, bookmark: browser.Bookmarks.BookmarkTreeNode }) {
console.log(`New bookmark created with ID: ${arg.id}`);
console.log(`Title: ${arg.bookmark.title}`);
console.log(`URL: ${arg.bookmark.url}`);
}
}
With parameter decorators:
import { onBookmarkCreated, bookmarkId, bookmarkNode, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkCreated()
handleNewBookmark(
@bookmarkId() id: string,
@bookmarkNode('title') title: string,
@bookmarkNode('url') url: string
) {
console.log(`New bookmark: "${title}" (${url})`);
console.log(`ID: ${id}`);
}
}
onBookmarkChanged
This decorator handles events that fire when a bookmark is updated.
import { onBookmarkChanged, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkChanged()
handleBookmarkUpdate(arg: {
id: string,
changeInfo: browser.Bookmarks.OnChangedChangeInfoType
}) {
console.log(`Bookmark updated with ID: ${arg.id}`);
if (arg.changeInfo.title) {
console.log(`New title: ${arg.changeInfo.title}`);
}
if (arg.changeInfo.url) {
console.log(`New URL: ${arg.changeInfo.url}`);
}
}
}
With parameter decorators:
import { onBookmarkChanged, bookmarkChangedId, bookmarkChangeInfo, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkChanged()
handleBookmarkUpdate(
@bookmarkChangedId() id: string,
@bookmarkChangeInfo('title') newTitle: string,
@bookmarkChangeInfo('url') newUrl: string
) {
console.log(`Bookmark ${id} was updated`);
if (newTitle) {
console.log(`Title changed to: ${newTitle}`);
}
if (newUrl) {
console.log(`URL changed to: ${newUrl}`);
}
}
}
onBookmarkMoved
This decorator handles events that fire when a bookmark is moved to a different location in the bookmark tree.
import { onBookmarkMoved, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkMoved()
handleBookmarkMove(arg: {
id: string,
moveInfo: browser.Bookmarks.OnMovedMoveInfoType
}) {
console.log(`Bookmark moved: ${arg.id}`);
console.log(`Old parent folder: ${arg.moveInfo.oldParentId}`);
console.log(`New parent folder: ${arg.moveInfo.parentId}`);
console.log(`Old index: ${arg.moveInfo.oldIndex}`);
console.log(`New index: ${arg.moveInfo.index}`);
}
}
With parameter decorators:
import { onBookmarkMoved, bookmarkMovedId, bookmarkMoveInfo, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkMoved()
handleBookmarkMove(
@bookmarkMovedId() id: string,
@bookmarkMoveInfo('oldParentId') oldFolder: string,
@bookmarkMoveInfo('parentId') newFolder: string
) {
console.log(`Bookmark ${id} moved from folder ${oldFolder} to ${newFolder}`);
}
}
onBookmarkRemoved
This decorator handles events that fire when a bookmark or folder is removed.
import { onBookmarkRemoved, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkRemoved()
handleBookmarkRemoval(arg: {
id: string,
removeInfo: browser.Bookmarks.OnRemovedRemoveInfoType
}) {
console.log(`Bookmark removed: ${arg.id}`);
console.log(`Parent folder: ${arg.removeInfo.parentId}`);
console.log(`Index: ${arg.removeInfo.index}`);
if (arg.removeInfo.node) {
console.log(`Title: ${arg.removeInfo.node.title}`);
console.log(`Was folder: ${!arg.removeInfo.node.url}`);
}
}
}
With parameter decorators:
import { onBookmarkRemoved, bookmarkRemovedId, bookmarkRemoveInfo, InjectableService } from 'deco-ext';
@InjectableService()
class BookmarkService {
@onBookmarkRemoved()
handleBookmarkRemoval(
@bookmarkRemovedId() id: string,
@bookmarkRemoveInfo('parentId') parentFolder: string,
@bookmarkRemoveInfo('node') node?: browser.Bookmarks.BookmarkTreeNode
) {
const itemType = node && node.url ? 'bookmark' : 'folder';
console.log(`${itemType} "${node?.title}" was removed from folder ${parentFolder}`);
}
}
Parameter Decorators
The Bookmarks API provides several parameter decorators for each event type:
For onBookmarkCreated
bookmarkId()
: Gets the ID of the created bookmarkbookmarkNode([property])
: Gets specific properties from the bookmark node, such as 'title', 'url', etc.
For onBookmarkChanged
bookmarkChangedId()
: Gets the ID of the changed bookmarkbookmarkChangeInfo([property])
: Gets specific change properties, such as 'title' or 'url'
For onBookmarkMoved
bookmarkMovedId()
: Gets the ID of the moved bookmarkbookmarkMoveInfo([property])
: Gets specific move information properties, such as 'parentId', 'oldParentId', 'index', or 'oldIndex'
For onBookmarkRemoved
bookmarkRemovedId()
: Gets the ID of the removed bookmarkbookmarkRemoveInfo([property])
: Gets specific remove information properties, such as 'parentId', 'index', or 'node'
BookmarkTreeNode Object
The BookmarkTreeNode
object represents a bookmark or folder in the bookmark tree:
interface BookmarkTreeNode {
id: string; // A unique identifier for the node
parentId?: string; // The ID of the parent folder
index?: number; // The 0-based position within its parent folder
url?: string; // The URL for the bookmark (not present for folders)
title: string; // The title of the bookmark or folder
dateAdded?: number; // When the node was created (milliseconds since epoch)
dateGroupModified?: number; // When the contents were last modified (folders only)
children?: BookmarkTreeNode[]; // Child nodes (folders only)
unmodifiable?: string; // If present, node cannot be modified ("managed")
}
Implementation Details
These decorators use a singleton pattern to ensure only one event listener is registered per event type, and then route events to all decorated methods. When a bookmark event occurs:
- The event is received by the single registered browser API listener
- The event data is passed to all registered method handlers
- For each handler:
- The class instance is resolved from the dependency injection container
- If the class has an
init
method, it's called before handling the event - If parameter decorators are used, the event data is transformed accordingly
- The method is called with the appropriate parameters
The decorators can only be used on methods within classes that have been decorated with the InjectableService
decorator from deco-ext.