<iframe .../> maps to WOIFrame
<body .../> maps to WOBody
<entity .../> maps to WOEntity
+ <container .../> removes the tag and embeds the content
*/
@interface WOxHTMLElemBuilder : WOxTagClassElemBuilder
@end
+#include "WOCompoundElement.h"
#include "common.h"
#include <SaxObjC/XMLNamespaces.h>
@implementation WOxHTMLElemBuilder
+static Class WOGenericContainerClass = Nil;
+static Class WOGenericElementClass = Nil;
+
++ (void)initialize {
+ WOGenericContainerClass = NSClassFromString(@"WOGenericContainer");
+ WOGenericElementClass = NSClassFromString(@"WOGenericElement");
+}
+
- (Class)classForInputElement:(id<DOMElement>)_element {
NSString *type;
unsigned tl;
}
- (Class)classForElement:(id<DOMElement>)_element {
- NSString *nsuri;
+ /* Note: namespace is checked in build-element */
NSString *tag;
unsigned tl;
+ unichar c0;
- if ((nsuri = [_element namespaceURI]) == nil)
- return Nil;
-
- if (![nsuri isEqualToString:XMLNS_XHTML]) {
- /* check HTML 4 namespace */
- if (![nsuri isEqualToString:XMLNS_HTML40])
- return Nil;
- }
-
tag = [_element tagName];
if ((tl = [tag length]) == 0)
return Nil;
+ c0 = [tag characterAtIndex:0];
switch (tl) {
case 1:
- if ([tag isEqualToString:@"a"]) {
- if ([_element hasAttribute:@"name" namespaceURI:@"*"])
- return NSClassFromString(@"WOGenericContainer");
-
- return NSClassFromString(@"WOHyperlink");
- }
+ if (c0 == 'a') {
+ // TODO: improve this section
+ if ([_element hasAttribute:@"name" namespaceURI:@"*"])
+ return NSClassFromString(@"WOGenericContainer");
+
+ return NSClassFromString(@"WOHyperlink");
+ }
break;
case 3:
- if ([tag isEqualToString:@"img"])
+ if (c0 == 'i' && [tag isEqualToString:@"img"])
return NSClassFromString(@"WOImage");
break;
case 4:
- if ([tag isEqualToString:@"body"])
+ if (c0 == 'b' && [tag isEqualToString:@"body"])
return NSClassFromString(@"WOBody");
-#if 0
- if ([tag isEqualToString:@"html"])
+#if WRAP_HTML_ROOT_TAG
+ if (c0 == 'h' && [tag isEqualToString:@"html"])
return NSClassFromString(@"WOHtml");
#endif
- if ([tag isEqualToString:@"form"])
+ if (c0 == 'f' && [tag isEqualToString:@"form"])
return NSClassFromString(@"WOForm");
- if ([tag isEqualToString:@"meta"]) {
+ if (c0 == 'm' && [tag isEqualToString:@"meta"]) {
NSString *val;
val = [_element attribute:@"http-equiv" namespaceURI:XMLNS_XHTML];
break;
case 5:
- if ([tag isEqualToString:@"input"])
+ if (c0 == 'i' && [tag isEqualToString:@"input"])
return [self classForInputElement:_element];
- if ([tag isEqualToString:@"frame"])
+ if (c0 == 'f' && [tag isEqualToString:@"frame"])
return NSClassFromString(@"WOFrame");
- if ([tag isEqualToString:@"embed"])
+ if (c0 == 'e' && [tag isEqualToString:@"embed"])
return NSClassFromString(@"WOEmbeddedObject");
break;
-
- default:
- if ([tag isEqualToString:@"textarea"])
- return NSClassFromString(@"WOText");
- if ([tag isEqualToString:@"iframe"])
+
+ case 6:
+ if (c0 == 'i' && [tag isEqualToString:@"iframe"])
return NSClassFromString(@"WOIFrame");
-
- if ([tag isEqualToString:@"entity"])
+ if (c0 == 'e' && [tag isEqualToString:@"entity"])
return NSClassFromString(@"WOEntity");
break;
+
+ case 8:
+ if (c0 == 't' && [tag isEqualToString:@"textarea"])
+ return NSClassFromString(@"WOText");
+ break;
+ }
+
+ return [_element hasChildNodes]
+ ? WOGenericContainerClass
+ : WOGenericElementClass;
+}
+
+- (WOElement *)buildContainer:(id<DOMElement>)_element templateBuilder:(id)_b {
+ /*
+ this is a 'noop' tag, which only generates its children, useful
+ as a root tag for templates
+ */
+ NSArray *children;
+ unsigned count;
+
+ children = [_element hasChildNodes]
+ ? [_b buildNodes:[_element childNodes] templateBuilder:_b]
+ : nil;
+
+ if ((count = [children count]) == 0)
+ return nil;
+
+ if (count == 1)
+ return [[children objectAtIndex:0] retain];
+
+ return [[WOCompoundElement allocForCount:count
+ zone:NULL] initWithContentElements:children];
+}
+
+- (WOElement *)buildElement:(id<DOMElement>)_element templateBuilder:(id)_b {
+ NSString *nsuri;
+
+ /* only build HTML namespace tags */
+
+ if ((nsuri = [_element namespaceURI]) == nil)
+ return [self buildNextElement:_element templateBuilder:_b];
+
+ if (![nsuri isEqualToString:XMLNS_XHTML]) {
+ /* check HTML 4 namespace */
+ if (![nsuri isEqualToString:XMLNS_HTML40])
+ return [self buildNextElement:_element templateBuilder:_b];
}
+
+ /* check for container tag (has not class ...) */
- if ([_element hasChildNodes])
- return NSClassFromString(@"WOGenericContainer");
- else
- return NSClassFromString(@"WOGenericElement");
+ if ([[_element tagName] isEqualToString:@"container"])
+ return [self buildContainer:_element templateBuilder:_b];
+
+ /* call class based builder in superclass */
+
+ return [super buildElement:_element templateBuilder:_b];
}
@end /* WOxHTMLElemBuilder */