[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