#include <NGObjWeb/WOElement.h>
#include <NGObjWeb/WOAssociation.h>
#include <NGObjWeb/WOComponentScript.h>
+#include <NGObjWeb/WODynamicElement.h>
#include "WOComponentFault.h"
#include "common.h"
@interface WOElement(UsedPrivates)
- (id)initWithValue:(id)_value escapeHTML:(BOOL)_flag;
++ (id)allocForCount:(int)_count zone:(NSZone *)_zone;
+- (id)initWithContentElements:(NSArray *)_elements;
@end
@interface WOAssociation(misc)
@implementation WOxElemBuilder
-static Class StrClass = Nil;
-static Class AStrClass = Nil;
-static NSDictionary *defaultAssocMap = nil;
-static Class ValAssoc = Nil;
-static BOOL logAssocMap = NO;
-static BOOL logAssocCreation = NO;
-static BOOL debugOn = NO;
-static NGLogger *logger = nil;
+static Class StrClass = Nil;
+static Class AStrClass = Nil;
+static NSDictionary *defaultAssocMap = nil;
+static Class ValAssoc = Nil;
+static BOOL logAssocMap = NO;
+static BOOL logAssocCreation = NO;
+static BOOL debugOn = NO;
+static NGLogger *logger = nil;
+static Class CompoundElemClass = Nil;
+static NSNumber *yesNum = nil;
+static WOAssociation *yesAssoc = nil;
+ (int)version {
return 1;
if (ValAssoc == Nil)
ValAssoc = NSClassFromString(@"WOValueAssociation");
+
+ CompoundElemClass = NSClassFromString(@"WOCompoundElement");
+
+ if (yesNum == nil)
+ yesNum = [[NSNumber numberWithBool:YES] retain];
+ if (yesAssoc == nil)
+ yesAssoc = [[WOAssociation associationWithValue:yesNum] retain];
}
+ (WOxElemBuilder *)createBuilderQueue:(NSArray *)_classNames {
- (void)reset {
[self->subcomponentInfos removeAllObjects];
- ASSIGN(self->script, (id)nil);
+ [self->script release]; self->script = nil;
+}
+
+/* support methods for subclasses */
+
+- (id<DOMElement>)lookupUniqueTag:(NSString *)_name
+ inElement:(id<DOMElement>)_elem
+{
+ id<DOMNodeList> list;
+
+ if ((list = [_elem getElementsByTagName:_name]) == nil)
+ return nil;
+ if ([list length] == 0)
+ return nil;
+ if ([list length] > 1) {
+ [self warnWithFormat:
+ @"more than once occurence of tag %@ in element: %@",
+ _name, _elem];
+ }
+ return [list objectAtIndex:0];
+}
+
+- (WOElement *)elementForRawString:(NSString *)_rawstr {
+ /* Note: returns a retained element! */
+ WOAssociation *a;
+
+ if (_rawstr == nil) return nil;
+ a = [WOAssociation associationWithValue:_rawstr];
+ return [[StrClass alloc] initWithValue:a escapeHTML:NO];
+}
+
+- (WOElement *)elementForElementsAndStrings:(NSArray *)_elements {
+ /* Note: returns a retained element! */
+ NSMutableArray *ma;
+ WOElement *element;
+ unsigned i, count;
+
+ if ((count = [_elements count]) == 0)
+ return nil;
+
+ ma = [[NSMutableArray alloc] initWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ id elem;
+
+ elem = [_elements objectAtIndex:i];
+ if ([elem isKindOfClass:[WOElement class]]) {
+ [ma addObject:elem];
+ continue;
+ }
+
+ if ((elem = [self elementForRawString:[elem stringValue]]))
+ [ma addObject:elem];
+ }
+ if ((count = [ma count]) == 0)
+ element = nil;
+ else if (count == 1) {
+ element = [[ma objectAtIndex:0] retain];
+ }
+ else {
+ element = [[CompoundElemClass allocForCount:count zone:NULL]
+ initWithContentElements:ma];
+ }
+ [ma release];
+ return element;
+}
+
+- (WOElement *)wrapElement:(WOElement *)_element
+ inCondition:(WOAssociation *)_condition
+ negate:(BOOL)_flag
+{
+ // NOTE: *releases* _element parameter!
+ // returns retained conditional
+ static Class WOConditionalClass = Nil;
+ static NSString *key = @"condition";
+ NSMutableDictionary *assocs;
+ WOElement *element;
+ NSArray *children;
+
+ if (WOConditionalClass == Nil)
+ WOConditionalClass = NSClassFromString(@"WOConditional");
+
+ if (_element == nil)
+ return nil;
+ if (_condition == nil)
+ return _element;
+
+ if (_flag) {
+ assocs = [[NSMutableDictionary alloc]
+ initWithObjectsAndKeys:_condition, key,
+ yesAssoc, @"negate", nil];
+ }
+ else {
+ assocs = [[NSMutableDictionary alloc] initWithObjects:&_condition
+ forKeys:&key count:1];
+ }
+ children = [[NSArray alloc] initWithObjects:&_element count:1];
+ element = [[WOConditionalClass alloc] initWithName:nil
+ associations:assocs
+ contentElements:children];
+ [children release];
+ [_element release];
+ [assocs release];
+ return element;
+}
+
+- (WOElement *)wrapElements:(NSArray *)_sub inElementOfClass:(Class)_class {
+ WOElement *element;
+
+ if (_sub == nil)
+ return nil;
+
+ element = [[_class alloc] initWithName:nil
+ associations:nil
+ contentElements:_sub];
+ return element;
+}
+
+- (WOElement *)wrapChildrenOfElement:(id<DOMElement>)_tag
+ inElementOfClass:(Class)_class
+ templateBuilder:(id)_b
+{
+ NSArray *children;
+
+ children = [_tag hasChildNodes]
+ ? [_b buildNodes:[_tag childNodes] templateBuilder:_b]
+ : nil;
+
+ return [self wrapElements:children inElementOfClass:_class];
}
@end /* WOxElemBuilder */