2008-11-04 Anders Carlsson <andersca@apple.com>
[webkit/qt.git] / WebCore / dom / make_names.pl
blobc0d0d869346453b5a608301c9557db2de56156ed
1 #!/usr/bin/perl -w
3 # Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 # its contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 use strict;
31 use Config;
32 use Getopt::Long;
33 use File::Path;
34 use IO::File;
35 use InFilesParser;
36 use Switch;
38 my $printFactory = 0;
39 my $printWrapperFactory = 0;
40 my $tagsFile = "";
41 my $attrsFile = "";
42 my $outputDir = ".";
43 my %tags = ();
44 my %attrs = ();
45 my %parameters = ();
46 my $extraDefines = 0;
47 my $preprocessor = "/usr/bin/gcc -E -P -x c++";
48 my %svgCustomMappings = ();
49 my %htmlCustomMappings = ();
51 GetOptions('tags=s' => \$tagsFile,
52 'attrs=s' => \$attrsFile,
53 'factory' => \$printFactory,
54 'outputDir=s' => \$outputDir,
55 'extraDefines=s' => \$extraDefines,
56 'preprocessor=s' => \$preprocessor,
57 'wrapperFactory' => \$printWrapperFactory);
59 die "You must specify at least one of --tags <file> or --attrs <file>" unless (length($tagsFile) || length($attrsFile));
61 readNames($tagsFile, "tags") if length($tagsFile);
62 readNames($attrsFile, "attrs") if length($attrsFile);
64 die "You must specify a namespace (e.g. SVG) for <namespace>Names.h" unless $parameters{'namespace'};
65 die "You must specify a namespaceURI (e.g. http://www.w3.org/2000/svg)" unless $parameters{'namespaceURI'};
67 $parameters{'namespacePrefix'} = $parameters{'namespace'} unless $parameters{'namespacePrefix'};
69 mkpath($outputDir);
70 my $namesBasePath = "$outputDir/$parameters{'namespace'}Names";
71 my $factoryBasePath = "$outputDir/$parameters{'namespace'}ElementFactory";
72 my $wrapperFactoryBasePath = "$outputDir/JS$parameters{'namespace'}ElementWrapperFactory";
74 printNamesHeaderFile("$namesBasePath.h");
75 printNamesCppFile("$namesBasePath.cpp");
77 if ($printFactory) {
78 printFactoryCppFile("$factoryBasePath.cpp");
79 printFactoryHeaderFile("$factoryBasePath.h");
82 if ($printWrapperFactory) {
83 printWrapperFactoryCppFile("$wrapperFactoryBasePath.cpp");
84 printWrapperFactoryHeaderFile("$wrapperFactoryBasePath.h");
87 ### Hash initialization
89 sub initializeTagPropertyHash
91 return ('interfaceName' => upperCaseName($_[0])."Element",
92 'applyAudioHack' => 0,
93 'exportString' => 0);
96 sub initializeAttrPropertyHash
98 return ('exportString' => 0);
101 sub initializeParametersHash
103 return ('namespace' => '',
104 'namespacePrefix' => '',
105 'namespaceURI' => '',
106 'guardFactoryWith' => '',
107 'tagsNullNamespace' => 0,
108 'attrsNullNamespace' => 0,
109 'exportStrings' => 0);
112 ### Parsing handlers
114 sub tagsHandler
116 my ($tag, $property, $value) = @_;
118 $tag =~ s/-/_/g;
120 # Initialize default properties' values.
121 $tags{$tag} = { initializeTagPropertyHash($tag) } if !defined($tags{$tag});
123 if ($property) {
124 die "Unknown property $property for tag $tag\n" if !defined($tags{$tag}{$property});
125 $tags{$tag}{$property} = $value;
129 sub attrsHandler
131 my ($attr, $property, $value) = @_;
133 $attr =~ s/-/_/g;
135 # Initialize default properties' values.
136 $attrs{$attr} = { initializeAttrPropertyHash($attr) } if !defined($attrs{$attr});
138 if ($property) {
139 die "Unknown property $property for attribute $attr\n" if !defined($attrs{$attr}{$property});
140 $attrs{$attr}{$property} = $value;
144 sub parametersHandler
146 my ($parameter, $value) = @_;
148 # Initialize default properties' values.
149 %parameters = initializeParametersHash() if !(keys %parameters);
151 die "Unknown parameter $parameter for tags/attrs\n" if !defined($parameters{$parameter});
152 $parameters{$parameter} = $value;
155 ## Support routines
157 sub readNames
159 my ($namesFile, $type) = @_;
161 my $names = new IO::File;
163 if ($extraDefines eq 0) {
164 open($names, $preprocessor . " " . $namesFile . "|") or die "Failed to open file: $namesFile";
165 } else {
166 open($names, $preprocessor . " -D" . join(" -D", split(" ", $extraDefines)) . " " . $namesFile . "|") or die "Failed to open file: $namesFile";
169 # Store hashes keys count to know if some insertion occured.
170 my $tagsCount = keys %tags;
171 my $attrsCount = keys %attrs;
173 my $InParser = InFilesParser->new();
175 switch ($type) {
176 case "tags" {
177 $InParser->parse($names, \&parametersHandler, \&tagsHandler);
179 case "attrs" {
180 $InParser->parse($names, \&parametersHandler, \&attrsHandler);
182 else {
183 die "Do not know how to parse $type";
187 close($names);
189 die "Failed to read names from file: $namesFile" if ((keys %tags == $tagsCount) && (keys %attrs == $attrsCount));
192 sub printMacros
194 my ($F, $macro, $suffix, $namesRef) = @_;
195 my %names = %$namesRef;
197 for my $name (sort keys %$namesRef) {
198 print F "$macro $name","$suffix;\n";
200 if ($parameters{'exportStrings'} or $names{$name}{"exportString"}) {
201 print F "extern char $name", "${suffix}String[];\n";
206 sub printConstructors
208 my ($F, $namesRef) = @_;
209 my %names = %$namesRef;
211 print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
212 for my $name (sort keys %names) {
213 my $ucName = $names{$name}{"interfaceName"};
215 print F "$parameters{'namespace'}Element* ${name}Constructor(Document* doc, bool createdByParser)\n";
216 print F "{\n";
217 print F " return new $parameters{'namespace'}${ucName}($parameters{'namespace'}Names::${name}Tag, doc);\n";
218 print F "}\n\n";
220 print F "#endif\n" if $parameters{'guardFactoryWith'};
223 sub printFunctionInits
225 my ($F, $namesRef) = @_;
226 for my $name (sort keys %$namesRef) {
227 print F " gFunctionMap->set($parameters{'namespace'}Names::${name}Tag.localName().impl(), ${name}Constructor);\n";
231 sub svgCapitalizationHacks
233 my $name = shift;
235 if ($name =~ /^fe(.+)$/) {
236 $name = "FE" . ucfirst $1;
239 return $name;
242 sub upperCaseName
244 my $name = shift;
246 $name = svgCapitalizationHacks($name) if ($parameters{'namespace'} eq "SVG");
248 while ($name =~ /^(.*?)_(.*)/) {
249 $name = $1 . ucfirst $2;
252 return ucfirst $name;
255 sub printLicenseHeader
257 my $F = shift;
258 print F "/*
259 * THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT.
262 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
264 * Redistribution and use in source and binary forms, with or without
265 * modification, are permitted provided that the following conditions
266 * are met:
267 * 1. Redistributions of source code must retain the above copyright
268 * notice, this list of conditions and the following disclaimer.
269 * 2. Redistributions in binary form must reproduce the above copyright
270 * notice, this list of conditions and the following disclaimer in the
271 * documentation and/or other materials provided with the distribution.
273 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
274 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
275 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
276 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
277 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
278 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
279 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
280 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
281 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
282 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
283 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
290 sub printNamesHeaderFile
292 my ($headerPath) = shift;
293 my $F;
294 open F, ">$headerPath";
296 printLicenseHeader($F);
297 print F "#ifndef DOM_$parameters{'namespace'}NAMES_H\n";
298 print F "#define DOM_$parameters{'namespace'}NAMES_H\n\n";
299 print F "#include \"QualifiedName.h\"\n\n";
301 print F "namespace WebCore {\n\n namespace $parameters{'namespace'}Names {\n\n";
303 my $lowerNamespace = lc($parameters{'namespacePrefix'});
304 print F "#ifndef DOM_$parameters{'namespace'}NAMES_HIDE_GLOBALS\n";
305 print F "// Namespace\n";
306 print F "extern const WebCore::AtomicString ${lowerNamespace}NamespaceURI;\n\n";
308 if (keys %tags) {
309 print F "// Tags\n";
310 printMacros($F, "extern const WebCore::QualifiedName", "Tag", \%tags);
311 print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size);\n";
314 if (keys %attrs) {
315 print F "// Attributes\n";
316 printMacros($F, "extern const WebCore::QualifiedName", "Attr", \%attrs);
317 print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Attr(size_t* size);\n";
319 print F "#endif\n\n";
320 print F "void init();\n\n";
321 print F "} }\n\n";
322 print F "#endif\n\n";
324 close F;
327 sub printNamesCppFile
329 my $cppPath = shift;
330 my $F;
331 open F, ">$cppPath";
333 printLicenseHeader($F);
335 my $lowerNamespace = lc($parameters{'namespacePrefix'});
337 print F "#include \"config.h\"\n";
339 print F "#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC\n";
340 print F "#define DOM_$parameters{'namespace'}NAMES_HIDE_GLOBALS 1\n";
341 print F "#else\n";
342 print F "#define QNAME_DEFAULT_CONSTRUCTOR 1\n";
343 print F "#endif\n\n";
346 print F "#include \"$parameters{'namespace'}Names.h\"\n\n";
347 print F "#include \"StaticConstructors.h\"\n";
349 print F "namespace WebCore {\n\n namespace $parameters{'namespace'}Names {
351 using namespace WebCore;
353 DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{'namespaceURI'}\")
356 if (keys %tags) {
357 print F "// Tags\n";
358 for my $name (sort keys %tags) {
359 print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI);\n";
362 print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size)\n";
363 print F "{\n static WebCore::QualifiedName* $parameters{'namespace'}Tags[] = {\n";
364 for my $name (sort keys %tags) {
365 print F " (WebCore::QualifiedName*)&${name}Tag,\n";
367 print F " };\n";
368 print F " *size = ", scalar(keys %tags), ";\n";
369 print F " return $parameters{'namespace'}Tags;\n";
370 print F "}\n";
373 if (keys %attrs) {
374 print F "\n// Attributes\n";
375 for my $name (sort keys %attrs) {
376 print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI);\n";
378 print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Attrs(size_t* size)\n";
379 print F "{\n static WebCore::QualifiedName* $parameters{'namespace'}Attr[] = {\n";
380 for my $name (sort keys %attrs) {
381 print F " (WebCore::QualifiedName*)&${name}Attr,\n";
383 print F " };\n";
384 print F " *size = ", scalar(keys %attrs), ";\n";
385 print F " return $parameters{'namespace'}Attr;\n";
386 print F "}\n";
389 if (keys %tags) {
390 printDefinitionStrings($F, \%tags, "tags");
393 if (keys %attrs) {
394 printDefinitionStrings($F, \%attrs, "attributes");
397 print F "\nvoid init()
399 static bool initialized = false;
400 if (initialized)
401 return;
402 initialized = true;
404 // Use placement new to initialize the globals.
406 AtomicString::init();
409 print(F " AtomicString ${lowerNamespace}NS(\"$parameters{'namespaceURI'}\");\n\n");
411 print(F " // Namespace\n");
412 print(F " new ((void*)&${lowerNamespace}NamespaceURI) AtomicString(${lowerNamespace}NS);\n\n");
413 if (keys %tags) {
414 my $tagsNamespace = $parameters{'tagsNullNamespace'} ? "nullAtom" : "${lowerNamespace}NS";
415 printDefinitions($F, \%tags, "tags", $tagsNamespace);
417 if (keys %attrs) {
418 my $attrsNamespace = $parameters{'attrsNullNamespace'} ? "nullAtom" : "${lowerNamespace}NS";
419 printDefinitions($F, \%attrs, "attributes", $attrsNamespace);
422 print F "}\n\n} }\n\n";
423 close F;
426 sub printJSElementIncludes
428 my ($F, $namesRef) = @_;
429 my %names = %$namesRef;
430 for my $name (sort keys %names) {
431 next if (hasCustomMapping($name));
433 my $ucName = $names{$name}{"interfaceName"};
434 print F "#include \"JS$parameters{'namespace'}${ucName}.h\"\n";
438 sub printElementIncludes
440 my ($F, $namesRef, $shouldSkipCustomMappings) = @_;
441 my %names = %$namesRef;
442 for my $name (sort keys %names) {
443 next if ($shouldSkipCustomMappings && hasCustomMapping($name));
445 my $ucName = $names{$name}{"interfaceName"};
446 print F "#include \"$parameters{'namespace'}${ucName}.h\"\n";
450 sub printDefinitionStrings
452 my ($F, $namesRef, $type) = @_;
453 my $singularType = substr($type, 0, -1);
454 my $shortType = substr($singularType, 0, 4);
455 my $shortCamelType = ucfirst($shortType);
456 print F "\n// " . ucfirst($type) . " as strings\n";
458 my %names = %$namesRef;
459 for my $name (sort keys %$namesRef) {
460 next if (!$parameters{'exportStrings'} and !$names{$name}{"exportString"});
462 my $realName = $name;
463 $realName =~ s/_/-/g;
465 print F "char $name","${shortCamelType}String[] = \"$realName\";\n";
469 sub printDefinitions
471 my ($F, $namesRef, $type, $namespaceURI) = @_;
472 my $singularType = substr($type, 0, -1);
473 my $shortType = substr($singularType, 0, 4);
474 my $shortCamelType = ucfirst($shortType);
475 my $shortUpperType = uc($shortType);
477 print F " // " . ucfirst($type) . "\n";
479 my %names = %$namesRef;
480 for my $name (sort keys %$namesRef) {
481 next if ($parameters{'exportStrings'} or $names{$name}{"exportString"});
483 my $realName = $name;
484 $realName =~ s/_/-/g;
485 print F " const char *$name","${shortCamelType}String = \"$realName\";\n";
488 print "\n";
490 for my $name (sort keys %$namesRef) {
491 print F " new ((void*)&$name","${shortCamelType}) QualifiedName(nullAtom, $name","${shortCamelType}String, $namespaceURI);\n";
495 ## ElementFactory routines
497 sub printFactoryCppFile
499 my $cppPath = shift;
500 my $F;
501 open F, ">$cppPath";
503 printLicenseHeader($F);
505 print F <<END
506 #include "config.h"
507 #include "$parameters{'namespace'}ElementFactory.h"
509 #include "$parameters{'namespace'}Names.h"
510 #if ENABLE(DASHBOARD_SUPPORT)
511 #include "Document.h"
512 #include "Settings.h"
513 #endif
518 printElementIncludes($F, \%tags, 0);
520 print F <<END
521 #include <wtf/HashMap.h>
523 using namespace WebCore;
525 typedef $parameters{'namespace'}Element* (*ConstructorFunc)(Document* doc, bool createdByParser);
526 typedef WTF::HashMap<AtomicStringImpl*, ConstructorFunc> FunctionMap;
528 static FunctionMap* gFunctionMap = 0;
530 namespace WebCore {
535 printConstructors($F, \%tags);
537 print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
539 print F <<END
540 static inline void createFunctionMapIfNecessary()
542 if (gFunctionMap)
543 return;
544 // Create the table.
545 gFunctionMap = new FunctionMap;
547 // Populate it with constructor functions.
551 printFunctionInits($F, \%tags);
553 print F "}\n";
554 print F "#endif\n\n" if $parameters{'guardFactoryWith'};
556 print F <<END
557 $parameters{'namespace'}Element* $parameters{'namespace'}ElementFactory::create$parameters{'namespace'}Element(const QualifiedName& qName, Document* doc, bool createdByParser)
562 print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
564 print F <<END
565 // Don't make elements without a document
566 if (!doc)
567 return 0;
569 #if ENABLE(DASHBOARD_SUPPORT)
570 Settings* settings = doc->settings();
571 if (settings && settings->usesDashboardBackwardCompatibilityMode())
572 return 0;
573 #endif
575 createFunctionMapIfNecessary();
576 ConstructorFunc func = gFunctionMap->get(qName.localName().impl());
577 if (func)
578 return func(doc, createdByParser);
580 return new $parameters{'namespace'}Element(qName, doc);
584 if ($parameters{'guardFactoryWith'}) {
586 print F <<END
587 #else
588 return 0;
589 #endif
595 print F <<END
598 } // namespace
603 close F;
606 sub printFactoryHeaderFile
608 my $headerPath = shift;
609 my $F;
610 open F, ">$headerPath";
612 printLicenseHeader($F);
614 print F "#ifndef $parameters{'namespace'}ELEMENTFACTORY_H\n";
615 print F "#define $parameters{'namespace'}ELEMENTFACTORY_H\n\n";
617 print F "
618 namespace WebCore {
619 class Element;
620 class Document;
621 class QualifiedName;
622 class AtomicString;
625 namespace WebCore {
627 class $parameters{'namespace'}Element;
629 // The idea behind this class is that there will eventually be a mapping from namespace URIs to ElementFactories that can dispense
630 // elements. In a compound document world, the generic createElement function (will end up being virtual) will be called.
631 class $parameters{'namespace'}ElementFactory
633 public:
634 WebCore::Element* createElement(const WebCore::QualifiedName& qName, WebCore::Document* doc, bool createdByParser = true);
635 static $parameters{'namespace'}Element* create$parameters{'namespace'}Element(const WebCore::QualifiedName& qName, WebCore::Document* doc, bool createdByParser = true);
639 #endif
643 close F;
646 ## Wrapper Factory routines
648 sub initializeCustomMappings
650 if (!keys %svgCustomMappings) {
651 # These are used to map a tag to another one in WrapperFactory
652 # (for example, "h2" is mapped to "h1" so that they use the same JS Wrapper ("h1" wrapper))
653 # Mapping to an empty string will not generate a wrapper
654 %svgCustomMappings = ('animateMotion' => '',
655 'hkern' => '',
656 'mpath' => '');
657 %htmlCustomMappings = ('abbr' => '',
658 'acronym' => '',
659 'address' => '',
660 'b' => '',
661 'bdo' => '',
662 'big' => '',
663 'center' => '',
664 'cite' => '',
665 'code' => '',
666 'colgroup' => 'col',
667 'dd' => '',
668 'dfn' => '',
669 'dt' => '',
670 'em' => '',
671 'h2' => 'h1',
672 'h3' => 'h1',
673 'h4' => 'h1',
674 'h5' => 'h1',
675 'h6' => 'h1',
676 'i' => '',
677 'image' => 'img',
678 'ins' => 'del',
679 'kbd' => '',
680 'keygen' => 'select',
681 'listing' => 'pre',
682 'layer' => '',
683 'nobr' => '',
684 'noembed' => '',
685 'noframes' => '',
686 'nolayer' => '',
687 'noscript' => '',
688 'plaintext' => '',
689 's' => '',
690 'samp' => '',
691 'small' => '',
692 'span' => '',
693 'strike' => '',
694 'strong' => '',
695 'sub' => '',
696 'sup' => '',
697 'tfoot' => 'tbody',
698 'th' => 'td',
699 'thead' => 'tbody',
700 'tt' => '',
701 'u' => '',
702 'var' => '',
703 'wbr' => '',
704 'xmp' => 'pre');
708 sub hasCustomMapping
710 my $name = shift;
711 initializeCustomMappings();
712 return 1 if $parameters{'namespace'} eq "HTML" && exists($htmlCustomMappings{$name});
713 return 1 if $parameters{'namespace'} eq "SVG" && exists($svgCustomMappings{$name});
714 return 0;
717 sub printWrapperFunctions
719 my ($F, $namesRef) = @_;
720 my %names = %$namesRef;
721 for my $name (sort keys %names) {
722 # Custom mapping do not need a JS wrapper
723 next if (hasCustomMapping($name));
725 my $ucName = $names{$name}{"interfaceName"};
726 # Hack for the media tags
727 if ($names{$name}{"applyAudioHack"}) {
728 print F <<END
729 static JSNode* create${ucName}Wrapper(ExecState* exec, PassRefPtr<$parameters{'namespace'}Element> element)
731 if (!MediaPlayer::isAvailable())
732 return CREATE_DOM_NODE_WRAPPER(exec, $parameters{'namespace'}Element, element.get());
733 return CREATE_DOM_NODE_WRAPPER(exec, $parameters{'namespace'}${ucName}, element.get());
738 } else {
739 print F <<END
740 static JSNode* create${ucName}Wrapper(ExecState* exec, PassRefPtr<$parameters{'namespace'}Element> element)
742 return CREATE_DOM_NODE_WRAPPER(exec, $parameters{'namespace'}${ucName}, element.get());
751 sub printWrapperFactoryCppFile
753 my $cppPath = shift;
754 my $F;
755 open F, ">$cppPath";
757 printLicenseHeader($F);
759 print F "#include \"config.h\"\n\n";
761 print F "#if $parameters{'guardFactoryWith'}\n\n" if $parameters{'guardFactoryWith'};
763 print F "#include \"JS$parameters{'namespace'}ElementWrapperFactory.h\"\n";
765 printJSElementIncludes($F, \%tags);
767 print F "\n#include \"$parameters{'namespace'}Names.h\"\n\n";
769 printElementIncludes($F, \%tags, 1);
771 print F <<END
772 using namespace JSC;
774 namespace WebCore {
776 using namespace $parameters{'namespace'}Names;
778 typedef JSNode* (*Create$parameters{'namespace'}ElementWrapperFunction)(ExecState*, PassRefPtr<$parameters{'namespace'}Element>);
783 printWrapperFunctions($F, \%tags);
785 print F <<END
786 JSNode* createJS$parameters{'namespace'}Wrapper(ExecState* exec, PassRefPtr<$parameters{'namespace'}Element> element)
788 static HashMap<WebCore::AtomicStringImpl*, Create$parameters{'namespace'}ElementWrapperFunction> map;
789 if (map.isEmpty()) {
793 for my $tag (sort keys %tags) {
794 next if (hasCustomMapping($tag));
796 my $ucTag = $tags{$tag}{"interfaceName"};
797 print F " map.set(${tag}Tag.localName().impl(), create${ucTag}Wrapper);\n";
800 if ($parameters{'namespace'} eq "HTML") {
801 for my $tag (sort keys %htmlCustomMappings) {
802 next if !$htmlCustomMappings{$tag};
804 my $ucCustomTag = $tags{$htmlCustomMappings{$tag}}{"interfaceName"};
805 print F " map.set(${tag}Tag.localName().impl(), create${ucCustomTag}Wrapper);\n";
809 # Currently SVG has no need to add custom map.set as it only has empty elements
811 print F <<END
813 Create$parameters{'namespace'}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl());
814 if (createWrapperFunction)
815 return createWrapperFunction(exec, element);
816 return CREATE_DOM_NODE_WRAPPER(exec, $parameters{'namespace'}Element, element.get());
824 print F "#endif\n" if $parameters{'guardFactoryWith'};
826 close F;
829 sub printWrapperFactoryHeaderFile
831 my $headerPath = shift;
832 my $F;
833 open F, ">$headerPath";
835 printLicenseHeader($F);
837 print F "#ifndef JS$parameters{'namespace'}ElementWrapperFactory_h\n";
838 print F "#define JS$parameters{'namespace'}ElementWrapperFactory_h\n\n";
840 print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
842 print F <<END
843 #include <wtf/Forward.h>
845 namespace JSC {
846 class ExecState;
849 namespace WebCore {
851 class JSNode;
852 class $parameters{'namespace'}Element;
854 JSNode* createJS$parameters{'namespace'}Wrapper(JSC::ExecState*, PassRefPtr<$parameters{'namespace'}Element>);
861 print F "#endif // $parameters{'guardFactoryWith'}\n\n" if $parameters{'guardFactoryWith'};
863 print F "#endif // JS$parameters{'namespace'}ElementWrapperFactory_h\n";
865 close F;