[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
sullivan
sullivan at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:21:20 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit dff49790f2957ca31af54aa38bfb5dc15c218bea
Author: sullivan <sullivan at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Jan 23 03:16:24 2003 +0000
- fixed 3152427 -- Need unique IDs for bookmarks, for
synching's sake
Bookmarks now have a UUID string so that each can maintain its identity
even in the face of multi-machine synching. One known loose end is written
up in 3153832 (unique IDs in bookmarks aren't preserved correctly after copy/paste).
This should be good enough now for the iSynch folks to start implementing
the bookmarks-synching conduit.
I also did some cleanup in this area to share more code and handle
init methods more cleanly, inspired by earlier feedback from Trey and Darin.
Reviewed by Trey and Darin
* Bookmarks.subproj/WebBookmark.h:
new _UUID ivar, UUID declaration
* Bookmarks.subproj/WebBookmarkPrivate.h:
new _setUUID and _hasUUID declarations
* Bookmarks.subproj/WebBookmark.m:
(-[WebBookmark dealloc]):
assert that group is nil here; release _UUID
(-[WebBookmark copyWithZone:]):
implement the code shared by each subclass; formerly had no implementation.
(-[WebBookmark _setUUID:]):
private method to set the UUID
(-[WebBookmark UUID]):
public method to get the UUID; this lazily creates the UUID.
(-[WebBookmark _hasUUID]):
private method to check whether there's a UUID without creating
one by side effect (as calling -[WebBookmark UUID] would)
(-[WebBookmark initFromDictionaryRepresentation:withGroup:]):
implement the code shared by each subclass; formerly had no implementation.
(-[WebBookmark dictionaryRepresentation]):
implement the code shared by each subclass; formerly had no implementation.
* Bookmarks.subproj/WebBookmarkGroup.h:
new _bookmarksByUUID ivar
* Bookmarks.subproj/WebBookmarkGroupPrivate.h:
declarations for new methods _addBookmark: and _removeBookmark:
* Bookmarks.subproj/WebBookmarkGroup.m:
(-[WebBookmarkGroup init]):
new method, just complains that you should have called initWithFile: instead.
(-[WebBookmarkGroup initWithFile:]):
create _bookmarksByUUID
(-[WebBookmarkGroup dealloc]):
release _bookmarksByUUID
(-[WebBookmarkGroup _addBookmark:]):
new method, if bookmark has UUID, adds it to table, and recursively
processes children the same way
(-[WebBookmarkGroup _removeBookmark:]):
new method, if bookmark has UUID, removes it from table, and recursively
processes children the same way
(-[WebBookmarkGroup _setTopBookmark:]):
replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
so it runs through the UUID code
(-[WebBookmarkGroup _bookmarkChildren:wereRemovedFromParent:]):
retitled this from "wereRemovedToParent"
* Bookmarks.subproj/WebBookmarkLeaf.m:
(-[WebBookmarkLeaf init]):
now calls initWithURLString:title:group with nil parameters so that
there's a designated initializer
(-[WebBookmarkLeaf initFromDictionaryRepresentation:withGroup:]):
rewritten to do only the subclasses' part now
(-[WebBookmarkLeaf dictionaryRepresentation]):
rewritten to do only the subclasses' part now
(-[WebBookmarkLeaf copyWithZone:]):
rewritten to do only the subclasses' part now
* Bookmarks.subproj/WebBookmarkList.m:
(-[WebBookmarkList init]):
now calls initWithTitle:group with nil parameters so that
there's a designated initializer
(-[WebBookmarkList initWithTitle:group:]):
replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
so it runs through the UUID code
(-[WebBookmarkList initFromDictionaryRepresentation:withGroup:]):
rewritten to do only the subclasses' part now
(-[WebBookmarkList dictionaryRepresentation]):
rewritten to do only the subclasses' part now
(-[WebBookmarkList copyWithZone:]):
rewritten to do only the subclasses' part now
(-[WebBookmarkList _setGroup:]):
removed this override, which used to do the recursion to set the group
of children; this recursion is now done by -[WebBookmarkGroup _addBookmark:]
and _removeBookmark:
(-[WebBookmarkList removeChild:]):
wereRemovedToParent -> wereRemovedFromParent
(-[WebBookmarkList insertChild:atIndex:]):
replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
so it runs through the UUID code
* Bookmarks.subproj/WebBookmarkProxy.m:
(-[WebBookmarkProxy init]):
now calls initWithTitle:group with nil parameters so that
there's a designated initializer
(-[WebBookmarkProxy initWithTitle:group:]):
replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
so it runs through the UUID code
(-[WebBookmarkProxy initFromDictionaryRepresentation:withGroup:]):
rewritten to do only the subclasses' part now
(-[WebBookmarkProxy dictionaryRepresentation]):
rewritten to do only the subclasses' part now
(-[WebBookmarkProxy copyWithZone:]):
rewritten to do only the subclasses' part now
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3414 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKit/Bookmarks.subproj/WebBookmark.h b/WebKit/Bookmarks.subproj/WebBookmark.h
index 71ca9cf..9538c3d 100644
--- a/WebKit/Bookmarks.subproj/WebBookmark.h
+++ b/WebKit/Bookmarks.subproj/WebBookmark.h
@@ -20,12 +20,14 @@ typedef enum {
WebBookmark *_parent;
WebBookmarkGroup *_group;
NSString *_identifier;
+ NSString *_UUID;
}
+ (WebBookmark *)bookmarkFromDictionaryRepresentation:(NSDictionary *)dict withGroup:(WebBookmarkGroup *)group;
+ (WebBookmark *)bookmarkOfType:(WebBookmarkType)type;
- (id)initFromDictionaryRepresentation:(NSDictionary *)dict withGroup:(WebBookmarkGroup *)group;
+// Note: this returns an NSMutableDictionary for subclasses' sake; other callers should treat it as non-mutable
- (NSDictionary *)dictionaryRepresentation;
- (NSString *)title;
@@ -51,6 +53,9 @@ typedef enum {
// in any way; clients can use it as they see fit.
- (void)setIdentifier:(NSString *)identifier;
+// Globally unique ID for this bookmark.
+- (NSString *)UUID;
+
// Array of child WebBookmarks. Returns nil if bookmarkType is not WebBookmarkTypeList.
// This creates a copy of the internal data structure, and thus is safe to (for example),
// iterate through, removing items from their parent as you go.
diff --git a/WebKit/Bookmarks.subproj/WebBookmark.m b/WebKit/Bookmarks.subproj/WebBookmark.m
index b06d92b..f25791c 100644
--- a/WebKit/Bookmarks.subproj/WebBookmark.m
+++ b/WebKit/Bookmarks.subproj/WebBookmark.m
@@ -21,17 +21,37 @@
@implementation WebBookmark
- (void)dealloc
-{
- [_group release];
+{
+ // a bookmark must be removed from its group before this,
+ // so the UUID table removes its (optional) entry for the bookmark.
+ ASSERT (_group == nil);
+
[_identifier release];
+ [_UUID release];
[super dealloc];
}
- (id)copyWithZone:(NSZone *)zone
{
- NSRequestConcreteImplementation(self, _cmd, [self class]);
- return nil;
+ WebBookmark *copy = NSCopyObject(self, 0, zone);
+ copy->_group = nil;
+ copy->_parent = nil;
+ copy->_identifier = nil;
+ copy->_UUID = nil;
+
+ [copy setIdentifier:[self identifier]];
+
+ // UUID starts the same as the original, which is OK
+ // since the copy isn't in a group yet. When it's added
+ // to a group, the UUID will be uniqued if necessary at that time.
+ if ([self _hasUUID]) {
+ [copy _setUUID:[self UUID]];
+ }
+
+ // parent and group are left nil for fresh copies
+
+ return copy;
}
- (NSString *)title
@@ -124,6 +144,31 @@
_parent = parent;
}
+- (void)_setUUID:(NSString *)UUID
+{
+ ASSERT(_UUID == nil || UUID == nil);
+
+ [_UUID release];
+ _UUID = [UUID copy];
+}
+
+- (NSString *)UUID
+{
+ // lazily generate
+ if (_UUID == nil) {
+ CFUUIDRef UUIDRef = CFUUIDCreate(kCFAllocatorDefault);
+ _UUID = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, UUIDRef);
+ CFRelease(UUIDRef);
+ }
+
+ return _UUID;
+}
+
+- (BOOL)_hasUUID
+{
+ return _UUID != nil;
+}
+
- (WebBookmarkGroup *)group
{
return _group;
@@ -182,15 +227,26 @@
}
- (id)initFromDictionaryRepresentation:(NSDictionary *)dict withGroup:(WebBookmarkGroup *)group
-{
- NSRequestConcreteImplementation(self, _cmd, [self class]);
- return nil;
+{
+ [self init];
+
+ [self setIdentifier:[dict objectForKey:WebBookmarkIdentifierKey]];
+ [self _setUUID:[dict objectForKey:WebBookmarkUUIDKey]];
+ [group _addBookmark:self];
+
+ return self;
}
- (NSDictionary *)dictionaryRepresentation
{
- NSRequestConcreteImplementation(self, _cmd, [self class]);
- return nil;
+ NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+ if ([self identifier] != nil) {
+ [dict setObject:[self identifier] forKey:WebBookmarkIdentifierKey];
+ }
+ // UUID is generated lazily; guaranteed to be non-nil
+ [dict setObject:[self UUID] forKey:WebBookmarkUUIDKey];
+
+ return dict;
}
- (BOOL)contentMatches:(WebBookmark *)otherBookmark
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkGroup.h b/WebKit/Bookmarks.subproj/WebBookmarkGroup.h
index 26a93b9..c765a50 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkGroup.h
+++ b/WebKit/Bookmarks.subproj/WebBookmarkGroup.h
@@ -28,6 +28,7 @@ extern NSString *WebBookmarkChildrenKey;
NSString *_tag;
NSString *_file;
WebBookmark *_topBookmark;
+ NSMutableDictionary *_bookmarksByUUID;
BOOL _loading;
}
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkGroup.m b/WebKit/Bookmarks.subproj/WebBookmarkGroup.m
index 108a8c7..b78fca2 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkGroup.m
+++ b/WebKit/Bookmarks.subproj/WebBookmarkGroup.m
@@ -33,6 +33,13 @@ NSString *TagKey = @"WebBookmarkGroupTag";
return [[[WebBookmarkGroup alloc] initWithFile:file] autorelease];
}
+- (id)init
+{
+ ERROR("[WebBookmarkGroup init] not supported, use initWithFile: instead");
+ [self release];
+ return nil;
+}
+
- (id)initWithFile: (NSString *)file
{
if (![super init]) {
@@ -41,6 +48,7 @@ NSString *TagKey = @"WebBookmarkGroupTag";
_file = [file copy];
[self _setTopBookmark:nil];
+ _bookmarksByUUID = [[NSMutableDictionary alloc] init];
// read history from disk
[self loadBookmarkGroup];
@@ -50,12 +58,60 @@ NSString *TagKey = @"WebBookmarkGroupTag";
- (void)dealloc
{
+ [_bookmarksByUUID release];
[_file release];
[_tag release];
[_topBookmark release];
[super dealloc];
}
+- (void)_addBookmark:(WebBookmark *)bookmark
+{
+ if ([bookmark group] == self) {
+ return;
+ }
+
+ ASSERT([bookmark group] == nil);
+
+ if ([bookmark _hasUUID]) {
+ NSString *UUID = [bookmark UUID];
+ // Clear UUID on former owner of this UUID (if any) -- new copy gets to keep it
+ // FIXME 3153832: this means copy/paste transfers the UUID to the new bookmark.
+ [[_bookmarksByUUID objectForKey:UUID] _setUUID:nil];
+ [_bookmarksByUUID setObject:bookmark forKey:UUID];
+ }
+
+ [bookmark _setGroup:self];
+
+ // Recurse with bookmark's children
+ NSArray *rawChildren = [bookmark rawChildren];
+ unsigned count = [rawChildren count];
+ unsigned childIndex;
+ for (childIndex = 0; childIndex < count; ++childIndex) {
+ [self _addBookmark:[rawChildren objectAtIndex:childIndex]];
+ }
+}
+
+- (void)_removeBookmark:(WebBookmark *)bookmark
+{
+ ASSERT([bookmark group] == self);
+
+ if ([bookmark _hasUUID]) {
+ ASSERT([_bookmarksByUUID objectForKey:[bookmark UUID]] == bookmark);
+ [_bookmarksByUUID removeObjectForKey:[bookmark UUID]];
+ }
+
+ [bookmark _setGroup:nil];
+
+ // Recurse with bookmark's children
+ NSArray *rawChildren = [bookmark rawChildren];
+ unsigned count = [rawChildren count];
+ unsigned childIndex;
+ for (childIndex = 0; childIndex < count; ++childIndex) {
+ [self _removeBookmark:[rawChildren objectAtIndex:childIndex]];
+ }
+}
+
- (NSString *)tag
{
return _tag;
@@ -90,8 +146,10 @@ NSString *TagKey = @"WebBookmarkGroupTag";
[newTopBookmark bookmarkType] == WebBookmarkTypeList);
[newTopBookmark retain];
-
- [_topBookmark _setGroup:nil];
+
+ if (_topBookmark != nil) {
+ [self _removeBookmark:_topBookmark];
+ }
[_topBookmark release];
if (newTopBookmark) {
@@ -117,7 +175,7 @@ NSString *TagKey = @"WebBookmarkGroupTag";
[self _sendNotification:WebBookmarksWereAddedNotification forBookmark:bookmark children:kids];
}
-- (void)_bookmarkChildren:(NSArray *)kids wereRemovedToParent:(WebBookmark *)bookmark
+- (void)_bookmarkChildren:(NSArray *)kids wereRemovedFromParent:(WebBookmark *)bookmark
{
ASSERT_ARG(bookmark, [bookmark bookmarkType] == WebBookmarkTypeList);
[self _sendNotification:WebBookmarksWereRemovedNotification forBookmark:bookmark children:kids];
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkGroupPrivate.h b/WebKit/Bookmarks.subproj/WebBookmarkGroupPrivate.h
index 74dbf21..28b4074 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkGroupPrivate.h
+++ b/WebKit/Bookmarks.subproj/WebBookmarkGroupPrivate.h
@@ -14,7 +14,10 @@
- (void)_bookmarkWillChange:(WebBookmark *)bookmark;
- (void)_bookmarkDidChange:(WebBookmark *)bookmark;
- (void)_bookmarkChildren:(NSArray *)kids wereAddedToParent:(WebBookmark *)bookmark;
-- (void)_bookmarkChildren:(NSArray *)kids wereRemovedToParent:(WebBookmark *)bookmark;
+- (void)_bookmarkChildren:(NSArray *)kids wereRemovedFromParent:(WebBookmark *)bookmark;
+
+- (void)_addBookmark:(WebBookmark *)bookmark;
+- (void)_removeBookmark:(WebBookmark *)bookmark;
@end
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m b/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m
index 08d9d0f..b9164b5 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m
+++ b/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m
@@ -22,24 +22,23 @@
- (id)init
{
- [super init];
- _entry = [[WebHistoryItem alloc] init];
- return self;
+ return [self initWithURLString:nil title:nil group:nil];
}
- (id)initWithURLString:(NSString *)URLString
title:(NSString *)title
group:(WebBookmarkGroup *)group;
{
- [self init];
+ [super init];
// Since our URLString may not be valid for creating an NSURL object,
// just hang onto the string separately and don't bother creating
// an NSURL object for the WebHistoryItem.
+ _entry = [[WebHistoryItem alloc] init];
[_entry setTitle:title]; // to avoid sending notifications, don't call setTitle or setURL
_URLString = [URLString copy];
[_entry setURL:[NSURL _web_URLWithString:_URLString]];
- [self _setGroup:group];
+ [group _addBookmark:self];
return self;
}
@@ -48,38 +47,31 @@
{
ASSERT_ARG(dict, dict != nil);
+ self = [super initFromDictionaryRepresentation:dict withGroup:group];
+
if (![[dict objectForKey:URIDictionaryKey] isKindOfClass:[NSDictionary class]]
|| ![[dict objectForKey:URLStringKey] isKindOfClass:[NSString class]]) {
ERROR("bad dictionary");
+ [self release];
return nil;
}
- [super init];
-
- [self _setGroup:group];
-
_entry = [[WebHistoryItem alloc] initFromDictionaryRepresentation:
[dict objectForKey:URIDictionaryKey]];
_URLString = [[dict objectForKey:URLStringKey] copy];
- [self setIdentifier:[dict objectForKey:WebBookmarkIdentifierKey]];
return self;
}
- (NSDictionary *)dictionaryRepresentation
{
- NSMutableDictionary *dict;
-
- dict = [NSMutableDictionary dictionaryWithCapacity:3];
+ NSMutableDictionary *dict = (NSMutableDictionary *)[super dictionaryRepresentation];
[dict setObject:WebBookmarkTypeLeafValue forKey:WebBookmarkTypeKey];
[dict setObject:[_entry dictionaryRepresentation] forKey:URIDictionaryKey];
if (_URLString != nil) {
[dict setObject:_URLString forKey:URLStringKey];
}
- if ([self identifier] != nil) {
- [dict setObject:[self identifier] forKey:WebBookmarkIdentifierKey];
- }
return dict;
}
@@ -93,10 +85,13 @@
- (id)copyWithZone:(NSZone *)zone
{
- id copy = [[WebBookmarkLeaf allocWithZone:zone] initWithURLString:_URLString
- title:[self title]
- group:[self group]];
- [copy setIdentifier:[self identifier]];
+ WebBookmarkLeaf *copy = [super copyWithZone:zone];
+
+ copy->_entry = [[WebHistoryItem alloc] init];
+ [copy->_entry setTitle:[self title]];
+ copy->_URLString = [[self URLString] copy];
+ [copy->_entry setURL:[NSURL _web_URLWithString:_URLString]];
+
return copy;
}
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkList.m b/WebKit/Bookmarks.subproj/WebBookmarkList.m
index 3670717..1621646 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkList.m
+++ b/WebKit/Bookmarks.subproj/WebBookmarkList.m
@@ -19,11 +19,7 @@
- (id)init
{
- [super init];
-
- _list = [[NSMutableArray alloc] init];
-
- return self;
+ return [self initWithTitle:nil group:nil];
}
- (id)initWithTitle:(NSString *)title
@@ -31,9 +27,9 @@
{
[super init];
- _title = [title copy];
_list = [[NSMutableArray alloc] init];
- [self _setGroup:group];
+ _title = [title copy];
+ [group _addBookmark:self];
return self;
}
@@ -42,24 +38,24 @@
{
ASSERT_ARG(dict, dict != nil);
+ self = [super initFromDictionaryRepresentation:dict withGroup:group];
+
if (![[dict objectForKey:WebBookmarkTypeKey] isKindOfClass:[NSString class]]
|| ([dict objectForKey:TitleKey] && ![[dict objectForKey:TitleKey] isKindOfClass:[NSString class]])
|| ([dict objectForKey:ChildrenKey] && ![[dict objectForKey:ChildrenKey] isKindOfClass:[NSArray class]])) {
ERROR("bad dictionary");
+ [self release];
return nil;
}
if (![[dict objectForKey:WebBookmarkTypeKey] isEqualToString:WebBookmarkTypeListValue]) {
ERROR("Can't initialize Bookmark list from non-list type");
+ [self release];
return nil;
}
-
- [super init];
- [self _setGroup:group];
-
- _title = [[dict objectForKey:TitleKey] copy];
_list = [[NSMutableArray alloc] init];
+ _title = [[dict objectForKey:TitleKey] copy];
NSArray *storedChildren = [dict objectForKey:ChildrenKey];
unsigned count = [storedChildren count];
@@ -72,18 +68,13 @@
[self insertChild:child atIndex:indexWritten++];
}
}
- [self setIdentifier:[dict objectForKey:WebBookmarkIdentifierKey]];
return self;
}
- (NSDictionary *)dictionaryRepresentation
{
- NSMutableDictionary *dict;
- NSMutableArray *childrenAsDictionaries;
- unsigned index, childCount;
-
- dict = [NSMutableDictionary dictionaryWithCapacity: 3];
+ NSMutableDictionary *dict = (NSMutableDictionary *)[super dictionaryRepresentation];
if (_title != nil) {
[dict setObject:_title forKey:TitleKey];
@@ -91,10 +82,11 @@
[dict setObject:WebBookmarkTypeListValue forKey:WebBookmarkTypeKey];
- childCount = [self numberOfChildren];
+ unsigned childCount = [self numberOfChildren];
if (childCount > 0) {
- childrenAsDictionaries = [NSMutableArray arrayWithCapacity:childCount];
+ NSMutableArray *childrenAsDictionaries = [NSMutableArray arrayWithCapacity:childCount];
+ unsigned index;
for (index = 0; index < childCount; ++index) {
WebBookmark *child;
@@ -105,10 +97,6 @@
[dict setObject:childrenAsDictionaries forKey:ChildrenKey];
}
- if ([self identifier] != nil) {
- [dict setObject:[self identifier] forKey:WebBookmarkIdentifierKey];
- }
-
return dict;
}
@@ -121,14 +109,12 @@
- (id)copyWithZone:(NSZone *)zone
{
- WebBookmarkList *copy;
- unsigned index, count;
+ WebBookmarkList *copy = [super copyWithZone:zone];
+ copy->_title = [_title copy];
+ copy->_list = [[NSMutableArray alloc] init];
- copy = [[WebBookmarkList alloc] initWithTitle:[self title]
- group:[self group]];
- [copy setIdentifier:[self identifier]];
-
- count = [self numberOfChildren];
+ unsigned index;
+ unsigned count = [self numberOfChildren];
for (index = 0; index < count; ++index) {
WebBookmark *childCopy = [[_list objectAtIndex:index] copyWithZone:zone];
[copy insertChild:childCopy atIndex:index];
@@ -207,9 +193,10 @@
[bookmark retain];
[_list removeObjectIdenticalTo:bookmark];
[bookmark _setParent:nil];
+ [[bookmark group] _removeBookmark:bookmark];
[bookmark release];
- [[self group] _bookmarkChildren:[NSArray arrayWithObject:bookmark] wereRemovedToParent:self];
+ [[self group] _bookmarkChildren:[NSArray arrayWithObject:bookmark] wereRemovedFromParent:self];
}
@@ -220,19 +207,9 @@
[_list insertObject:bookmark atIndex:index];
[bookmark _setParent:self];
- [bookmark _setGroup:[self group]];
+ [[self group] _addBookmark:self];
[[self group] _bookmarkChildren:[NSArray arrayWithObject:bookmark] wereAddedToParent:self];
}
-- (void)_setGroup:(WebBookmarkGroup *)group
-{
- if (group == [self group]) {
- return;
- }
-
- [super _setGroup:group];
- [_list makeObjectsPerformSelector:@selector(_setGroup:) withObject:group];
-}
-
@end
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkPrivate.h b/WebKit/Bookmarks.subproj/WebBookmarkPrivate.h
index 458d3cd..1e608c7 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkPrivate.h
+++ b/WebKit/Bookmarks.subproj/WebBookmarkPrivate.h
@@ -15,12 +15,21 @@
#define WebBookmarkTypeProxyValue @"WebBookmarkTypeProxy"
#define WebBookmarkIdentifierKey @"WebBookmarkIdentifier"
+#define WebBookmarkUUIDKey @"WebBookmarkUUID"
@interface WebBookmark(WebPrivate)
- (void)_setParent:(WebBookmark *)parent;
- (void)_setGroup:(WebBookmarkGroup *)group;
+// Set the globally unique id for this bookmark to the specified value.
+- (void)_setUUID:(NSString *)UUID;
+
+// Returns YES if UUID is non-nil; can't simply use -[WebBookmark UUID] because
+// it will generate a UUID if there isn't one already.
+- (BOOL)_hasUUID;
+
+
- (unsigned)_numberOfDescendants;
@end
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkProxy.m b/WebKit/Bookmarks.subproj/WebBookmarkProxy.m
index 43e6ac4..5670e26 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkProxy.m
+++ b/WebKit/Bookmarks.subproj/WebBookmarkProxy.m
@@ -16,10 +16,15 @@
@implementation WebBookmarkProxy
+- (id)init
+{
+ return [self initWithTitle:nil group:nil];
+}
+
- (id)initWithTitle:(NSString *)title group:(WebBookmarkGroup *)group;
{
[super init];
- [self _setGroup:group];
+ [group _addBookmark:self];
_title = [title copy]; // to avoid sending notifications, don't call setTitle
return self;
@@ -27,18 +32,22 @@
- (id)initFromDictionaryRepresentation:(NSDictionary *)dict withGroup:(WebBookmarkGroup *)group
{
+ self = [super initFromDictionaryRepresentation:dict withGroup:group];
+
if (![[dict objectForKey:WebBookmarkTypeKey] isKindOfClass:[NSString class]]) {
ERROR("bad dictionary");
+ [self release];
return nil;
}
if (![[dict objectForKey:WebBookmarkTypeKey] isEqualToString:WebBookmarkTypeProxyValue]) {
ERROR("Can't initialize Bookmark proxy from non-proxy type");
+ [self release];
return nil;
}
- WebBookmark *result = [self initWithTitle:[dict objectForKey:TitleKey] group:group];
- [result setIdentifier:[dict objectForKey:WebBookmarkIdentifierKey]];
- return result;
+ _title = [[dict objectForKey:TitleKey] copy];
+
+ return self;
}
- (void)dealloc
@@ -49,14 +58,11 @@
- (NSDictionary *)dictionaryRepresentation
{
- NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:2];
+ NSMutableDictionary *dict = (NSMutableDictionary *)[super dictionaryRepresentation];
[dict setObject:WebBookmarkTypeProxyValue forKey:WebBookmarkTypeKey];
if (_title != nil) {
[dict setObject:_title forKey:TitleKey];
}
- if ([self identifier] != nil) {
- [dict setObject:[self identifier] forKey:WebBookmarkIdentifierKey];
- }
return dict;
}
@@ -68,8 +74,8 @@
- (id)copyWithZone:(NSZone *)zone
{
- id copy = [[WebBookmarkProxy alloc] initWithTitle:_title group:[self group]];
- [copy setIdentifier:[self identifier]];
+ WebBookmarkProxy *copy = [super copyWithZone:zone];
+ copy->_title = [_title copy];
return copy;
}
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index ea07670..21a3eba 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,113 @@
+2003-01-22 John Sullivan <sullivan at apple.com>
+
+ - fixed 3152427 -- Need unique IDs for bookmarks, for
+ synching's sake
+
+ Bookmarks now have a UUID string so that each can maintain its identity
+ even in the face of multi-machine synching. One known loose end is written
+ up in 3153832 (unique IDs in bookmarks aren't preserved correctly after copy/paste).
+ This should be good enough now for the iSynch folks to start implementing
+ the bookmarks-synching conduit.
+
+ I also did some cleanup in this area to share more code and handle
+ init methods more cleanly, inspired by earlier feedback from Trey and Darin.
+
+ Reviewed by Trey and Darin
+
+ * Bookmarks.subproj/WebBookmark.h:
+ new _UUID ivar, UUID declaration
+ * Bookmarks.subproj/WebBookmarkPrivate.h:
+ new _setUUID and _hasUUID declarations
+
+ * Bookmarks.subproj/WebBookmark.m:
+ (-[WebBookmark dealloc]):
+ assert that group is nil here; release _UUID
+ (-[WebBookmark copyWithZone:]):
+ implement the code shared by each subclass; formerly had no implementation.
+ (-[WebBookmark _setUUID:]):
+ private method to set the UUID
+ (-[WebBookmark UUID]):
+ public method to get the UUID; this lazily creates the UUID.
+ (-[WebBookmark _hasUUID]):
+ private method to check whether there's a UUID without creating
+ one by side effect (as calling -[WebBookmark UUID] would)
+ (-[WebBookmark initFromDictionaryRepresentation:withGroup:]):
+ implement the code shared by each subclass; formerly had no implementation.
+ (-[WebBookmark dictionaryRepresentation]):
+ implement the code shared by each subclass; formerly had no implementation.
+
+ * Bookmarks.subproj/WebBookmarkGroup.h:
+ new _bookmarksByUUID ivar
+ * Bookmarks.subproj/WebBookmarkGroupPrivate.h:
+ declarations for new methods _addBookmark: and _removeBookmark:
+
+ * Bookmarks.subproj/WebBookmarkGroup.m:
+ (-[WebBookmarkGroup init]):
+ new method, just complains that you should have called initWithFile: instead.
+ (-[WebBookmarkGroup initWithFile:]):
+ create _bookmarksByUUID
+ (-[WebBookmarkGroup dealloc]):
+ release _bookmarksByUUID
+ (-[WebBookmarkGroup _addBookmark:]):
+ new method, if bookmark has UUID, adds it to table, and recursively
+ processes children the same way
+ (-[WebBookmarkGroup _removeBookmark:]):
+ new method, if bookmark has UUID, removes it from table, and recursively
+ processes children the same way
+ (-[WebBookmarkGroup _setTopBookmark:]):
+ replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
+ so it runs through the UUID code
+ (-[WebBookmarkGroup _bookmarkChildren:wereRemovedFromParent:]):
+ retitled this from "wereRemovedToParent"
+
+ * Bookmarks.subproj/WebBookmarkLeaf.m:
+ (-[WebBookmarkLeaf init]):
+ now calls initWithURLString:title:group with nil parameters so that
+ there's a designated initializer
+ (-[WebBookmarkLeaf initFromDictionaryRepresentation:withGroup:]):
+ rewritten to do only the subclasses' part now
+ (-[WebBookmarkLeaf dictionaryRepresentation]):
+ rewritten to do only the subclasses' part now
+ (-[WebBookmarkLeaf copyWithZone:]):
+ rewritten to do only the subclasses' part now
+
+ * Bookmarks.subproj/WebBookmarkList.m:
+ (-[WebBookmarkList init]):
+ now calls initWithTitle:group with nil parameters so that
+ there's a designated initializer
+ (-[WebBookmarkList initWithTitle:group:]):
+ replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
+ so it runs through the UUID code
+ (-[WebBookmarkList initFromDictionaryRepresentation:withGroup:]):
+ rewritten to do only the subclasses' part now
+ (-[WebBookmarkList dictionaryRepresentation]):
+ rewritten to do only the subclasses' part now
+ (-[WebBookmarkList copyWithZone:]):
+ rewritten to do only the subclasses' part now
+ (-[WebBookmarkList _setGroup:]):
+ removed this override, which used to do the recursion to set the group
+ of children; this recursion is now done by -[WebBookmarkGroup _addBookmark:]
+ and _removeBookmark:
+ (-[WebBookmarkList removeChild:]):
+ wereRemovedToParent -> wereRemovedFromParent
+ (-[WebBookmarkList insertChild:atIndex:]):
+ replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
+ so it runs through the UUID code
+
+ * Bookmarks.subproj/WebBookmarkProxy.m:
+ (-[WebBookmarkProxy init]):
+ now calls initWithTitle:group with nil parameters so that
+ there's a designated initializer
+ (-[WebBookmarkProxy initWithTitle:group:]):
+ replace [bookmark setGroup:group] with [group _addBookmark:bookmark]
+ so it runs through the UUID code
+ (-[WebBookmarkProxy initFromDictionaryRepresentation:withGroup:]):
+ rewritten to do only the subclasses' part now
+ (-[WebBookmarkProxy dictionaryRepresentation]):
+ rewritten to do only the subclasses' part now
+ (-[WebBookmarkProxy copyWithZone:]):
+ rewritten to do only the subclasses' part now
+
2003-01-22 Darin Adler <darin at apple.com>
Reviewed by Maciej.
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list