Generate toFooElement() functions from tagname data.
[WebKit-https.git] / Source / WebCore / dom / make_names.pl
1 #!/usr/bin/perl -w
2
3 # Copyright (C) 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
4 # Copyright (C) 2009, Julien Chaffraix <jchaffraix@webkit.org>
5 # Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
6 # Copyright (C) 2011 Ericsson AB. All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 #
12 # 1.  Redistributions of source code must retain the above copyright
13 #     notice, this list of conditions and the following disclaimer. 
14 # 2.  Redistributions in binary form must reproduce the above copyright
15 #     notice, this list of conditions and the following disclaimer in the
16 #     documentation and/or other materials provided with the distribution. 
17 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
18 #     its contributors may be used to endorse or promote products derived
19 #     from this software without specific prior written permission. 
20 #
21 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
22 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
25 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 use strict;
33
34 use StaticString;
35 use Config;
36 use Getopt::Long;
37 use File::Path;
38 use File::Spec;
39 use IO::File;
40 use InFilesParser;
41
42 sub readTags($$);
43 sub readAttrs($$);
44
45 my $printFactory = 0; 
46 my $printWrapperFactory = 0; 
47 my $fontNamesIn = "";
48 my $tagsFile = "";
49 my $attrsFile = "";
50 my $outputDir = ".";
51 my %parsedTags = ();
52 my %parsedAttrs = ();
53 my %enabledTags = ();
54 my %enabledAttrs = ();
55 my %allTags = ();
56 my %allAttrs = ();
57 my %allStrings = ();
58 my %parameters = ();
59 my $extraDefines = 0;
60 my $initDefaults = 1;
61 my %extensionAttrs = ();
62
63 require Config;
64
65 my $gccLocation = "";
66 if ($ENV{CC}) {
67     $gccLocation = $ENV{CC};
68 } elsif (($Config::Config{'osname'}) =~ /solaris/i) {
69     $gccLocation = "/usr/sfw/bin/gcc";
70 } else {
71     $gccLocation = "/usr/bin/gcc";
72 }
73 my $preprocessor = $gccLocation . " -E -x c++";
74
75 GetOptions(
76     'tags=s' => \$tagsFile, 
77     'attrs=s' => \$attrsFile,
78     'factory' => \$printFactory,
79     'outputDir=s' => \$outputDir,
80     'extraDefines=s' => \$extraDefines,
81     'preprocessor=s' => \$preprocessor,
82     'wrapperFactory' => \$printWrapperFactory,
83     'fonts=s' => \$fontNamesIn
84 );
85
86 mkpath($outputDir);
87
88 if (length($fontNamesIn)) {
89     my $names = new IO::File;
90     my $familyNamesFileBase = "WebKitFontFamily";
91
92     open($names, $fontNamesIn) or die "Failed to open file: $fontNamesIn";
93
94     $initDefaults = 0;
95     my $Parser = InFilesParser->new();
96     my $dummy;
97     $Parser->parse($names, \&parametersHandler, \&dummy);
98
99     my $F;
100     my $header = File::Spec->catfile($outputDir, "${familyNamesFileBase}Names.h");
101     open F, ">$header" or die "Unable to open $header for writing.";
102
103     printLicenseHeader($F);
104     printHeaderHead($F, "CSS", $familyNamesFileBase, "#include <wtf/text/AtomicString.h>");
105
106     printMacros($F, "extern const WTF::AtomicString", "", \%parameters);
107     print F "#endif\n\n";
108
109     printInit($F, 1);
110     close F;
111
112     my $source = File::Spec->catfile($outputDir, "${familyNamesFileBase}Names.cpp");
113     open F, ">$source" or die "Unable to open $source for writing.";
114
115     printLicenseHeader($F);
116     printCppHead($F, "CSS", $familyNamesFileBase, "WTF");
117
118     print F StaticString::GenerateStrings(\%parameters);
119
120     while ( my ($name, $identifier) = each %parameters ) {
121         print F "DEFINE_GLOBAL(AtomicString, $name)\n";
122     }
123
124     printInit($F, 0);
125
126     print F "\n";
127     print F StaticString::GenerateStringAsserts(\%parameters);
128
129     while ( my ($name, $identifier) = each %parameters ) {
130         print F "    new (NotNull, (void*)&$name) AtomicString(${name}Impl);\n";
131     }
132
133     print F "}\n}\n}\n";
134     close F;
135     exit 0;
136 }
137
138 die "You must specify at least one of --tags <file> or --attrs <file>" unless (length($tagsFile) || length($attrsFile));
139
140 if (length($tagsFile)) {
141     %allTags = %{readTags($tagsFile, 0)};
142     %enabledTags = %{readTags($tagsFile, 1)};
143     namesToStrings(\%allTags, \%allStrings);
144 }
145
146 if (length($attrsFile)) {
147     %allAttrs = %{readAttrs($attrsFile, 0)};
148     %enabledAttrs = %{readAttrs($attrsFile, 1)};
149     namesToStrings(\%allAttrs, \%allStrings);
150 }
151
152 die "You must specify a namespace (e.g. SVG) for <namespace>Names.h" unless $parameters{namespace};
153 die "You must specify a namespaceURI (e.g. http://www.w3.org/2000/svg)" unless $parameters{namespaceURI};
154
155 $parameters{namespacePrefix} = $parameters{namespace} unless $parameters{namespacePrefix};
156 $parameters{fallbackJSInterfaceName} = $parameters{fallbackInterfaceName} unless $parameters{fallbackJSInterfaceName};
157
158 my $typeHelpersBasePath = "$outputDir/$parameters{namespace}ElementTypeHelpers";
159 my $namesBasePath = "$outputDir/$parameters{namespace}Names";
160 my $factoryBasePath = "$outputDir/$parameters{namespace}ElementFactory";
161 my $wrapperFactoryFileName = "$parameters{namespace}ElementWrapperFactory";
162
163 printNamesHeaderFile("$namesBasePath.h");
164 printNamesCppFile("$namesBasePath.cpp");
165 printTypeHelpersHeaderFile("$typeHelpersBasePath.h");
166
167 if ($printFactory) {
168     printFactoryCppFile("$factoryBasePath.cpp");
169     printFactoryHeaderFile("$factoryBasePath.h");
170 }
171
172 if ($printWrapperFactory) {
173     printWrapperFactoryCppFile($outputDir, $wrapperFactoryFileName);
174     printWrapperFactoryHeaderFile($outputDir, $wrapperFactoryFileName);
175 }
176
177 ### Hash initialization
178
179 sub defaultTagPropertyHash
180 {
181     return (
182         'constructorNeedsCreatedByParser' => 0,
183         'constructorNeedsFormElement' => 0,
184         'noConstructor' => 0,
185         'interfaceName' => defaultInterfaceName($_[0]),
186         # By default, the JSInterfaceName is the same as the interfaceName.
187         'JSInterfaceName' => defaultInterfaceName($_[0]),
188         'mapToTagName' => '',
189         'wrapperOnlyIfMediaIsAvailable' => 0,
190         'conditional' => 0,
191         'contextConditional' => 0,
192         'runtimeConditional' => 0,
193         'generateTypeHelpers' => 0
194     );
195 }
196
197 sub defaultParametersHash
198 {
199     return (
200         'namespace' => '',
201         'namespacePrefix' => '',
202         'namespaceURI' => '',
203         'guardFactoryWith' => '',
204         'tagsNullNamespace' => 0,
205         'attrsNullNamespace' => 0,
206         'fallbackInterfaceName' => '',
207         'fallbackJSInterfaceName' => ''
208     );
209 }
210
211 sub defaultInterfaceName
212 {
213     die "No namespace found" if !$parameters{namespace};
214     return $parameters{namespace} . upperCaseName($_[0]) . "Element"
215 }
216
217 ### Parsing handlers
218
219 sub valueForName
220 {
221     my $name = shift;
222     my $value = $extensionAttrs{$name};
223
224     if (!$value) {
225         $value = $name;
226         $value =~ s/_/-/g;
227     }
228
229     return $value;
230 }
231
232 sub namesToStrings
233 {
234     my $namesRef = shift;
235     my $stringsRef = shift;
236
237     my %names = %$namesRef;
238
239     for my $name (keys %names) {
240         $stringsRef->{$name} = valueForName($name);
241     }
242 }
243
244 sub tagsHandler
245 {
246     my ($tag, $property, $value) = @_;
247
248     $tag =~ s/-/_/g;
249
250     # Initialize default property values.
251     $parsedTags{$tag} = { defaultTagPropertyHash($tag) } if !defined($parsedTags{$tag});
252
253     if ($property) {
254         die "Unknown property $property for tag $tag\n" if !defined($parsedTags{$tag}{$property});
255
256         # The code relies on JSInterfaceName deriving from interfaceName to check for custom JSInterfaceName.
257         # So override JSInterfaceName if it was not already set.
258         $parsedTags{$tag}{JSInterfaceName} = $value if $property eq "interfaceName" && $parsedTags{$tag}{JSInterfaceName} eq $parsedTags{$tag}{interfaceName};
259
260         $parsedTags{$tag}{$property} = $value;
261     }
262 }
263
264 sub attrsHandler
265 {
266     my ($attr, $property, $value) = @_;
267     # Translate HTML5 extension attributes of the form 'x-webkit-feature' to 'webkitfeature'.
268     # We don't just check for the 'x-' prefix because there are attributes such as x-height
269     # which should follow the default path below.
270     if ($attr =~ m/^x-webkit-(.*)/) {
271         my $newAttr = "webkit$1";
272         $extensionAttrs{$newAttr} = $attr;
273         $attr = $newAttr;
274     }
275     $attr =~ s/-/_/g;
276
277     # Initialize default properties' values.
278     $parsedAttrs{$attr} = {} if !defined($parsedAttrs{$attr});
279
280     if ($property) {
281         die "Unknown property $property for attribute $attr\n" if !defined($parsedAttrs{$attr}{$property});
282         $parsedAttrs{$attr}{$property} = $value;
283     }
284 }
285
286 sub parametersHandler
287 {
288     my ($parameter, $value) = @_;
289
290     # Initialize default properties' values.
291     %parameters = defaultParametersHash() if (!(keys %parameters) && $initDefaults);
292
293     die "Unknown parameter $parameter for tags/attrs\n" if (!defined($parameters{$parameter}) && $initDefaults);
294     $parameters{$parameter} = $value;
295 }
296
297 ## Support routines
298
299 sub preprocessorCommand()
300 {
301     return $preprocessor if $extraDefines eq 0;
302     return $preprocessor . " -D" . join(" -D", split(" ", $extraDefines));
303 }
304
305 sub readNames($$$$)
306 {
307     my ($namesFile, $hashToFillRef, $handler, $usePreprocessor) = @_;
308
309     my $names = new IO::File;
310     if ($usePreprocessor) {
311         open($names, preprocessorCommand() . " " . $namesFile . "|") or die "Failed to open file: $namesFile";
312     } else {
313         open($names, $namesFile) or die "Failed to open file: $namesFile";
314     }
315
316     my $InParser = InFilesParser->new();
317     $InParser->parse($names, \&parametersHandler, $handler);
318
319     close($names);
320     die "Failed to read names from file: $namesFile" if (keys %{$hashToFillRef} == 0);
321     return $hashToFillRef;
322 }
323
324 sub readAttrs($$)
325 {
326     my ($namesFile, $usePreprocessor) = @_;
327     %parsedAttrs = ();
328     return readNames($namesFile, \%parsedAttrs, \&attrsHandler, $usePreprocessor);
329 }
330
331 sub readTags($$)
332 {
333     my ($namesFile, $usePreprocessor) = @_;
334     %parsedTags = ();
335     return readNames($namesFile, \%parsedTags, \&tagsHandler, $usePreprocessor);
336 }
337
338 sub printMacros
339 {
340     my ($F, $macro, $suffix, $namesRef) = @_;
341     my %names = %$namesRef;
342
343     for my $name (sort keys %names) {
344         print F "$macro $name","$suffix;\n";
345     }
346 }
347
348 sub usesDefaultWrapper
349 {
350     my $tagName = shift;
351     return $tagName eq $parameters{namespace} . "Element";
352 }
353
354 # Build a direct mapping from the tags to the Element to create.
355 sub buildConstructorMap
356 {
357     my %tagConstructorMap = ();
358     for my $tagName (keys %enabledTags) {
359         my $interfaceName = $enabledTags{$tagName}{interfaceName};
360
361         if ($enabledTags{$tagName}{mapToTagName}) {
362             die "Cannot handle multiple mapToTagName for $tagName\n" if $enabledTags{$enabledTags{$tagName}{mapToTagName}}{mapToTagName};
363             $interfaceName = $enabledTags{ $enabledTags{$tagName}{mapToTagName} }{interfaceName};
364         }
365
366         # Chop the string to keep the interesting part.
367         $interfaceName =~ s/$parameters{namespace}(.*)Element/$1/;
368         $tagConstructorMap{$tagName} = lc($interfaceName);
369     }
370
371     return %tagConstructorMap;
372 }
373
374 # Helper method that print the constructor's signature avoiding
375 # unneeded arguments.
376 sub printConstructorSignature
377 {
378     my ($F, $tagName, $constructorName, $constructorTagName) = @_;
379
380     print F "static PassRefPtr<$parameters{namespace}Element> ${constructorName}Constructor(const QualifiedName& $constructorTagName, Document* document";
381     if ($parameters{namespace} eq "HTML") {
382         print F ", HTMLFormElement*";
383         print F " formElement" if $enabledTags{$tagName}{constructorNeedsFormElement};
384     }
385     print F ", bool";
386     print F " createdByParser" if $enabledTags{$tagName}{constructorNeedsCreatedByParser};
387     print F ")\n{\n";
388 }
389
390 # Helper method to dump the constructor interior and call the 
391 # Element constructor with the right arguments.
392 # The variable names should be kept in sync with the previous method.
393 sub printConstructorInterior
394 {
395     my ($F, $tagName, $interfaceName, $constructorTagName) = @_;
396
397     # Handle media elements.
398     if ($enabledTags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
399         print F <<END
400     Settings* settings = document->settings();
401     if (!MediaPlayer::isAvailable() || (settings && !settings->mediaEnabled()))
402         return 0;
403     
404 END
405 ;
406     }
407
408     my $contextConditional = $enabledTags{$tagName}{contextConditional};
409     if ($contextConditional) {
410         print F <<END
411     if (!ContextFeatures::${contextConditional}Enabled(document))
412         return 0;
413 END
414 ;
415     }
416
417     my $runtimeConditional = $enabledTags{$tagName}{runtimeConditional};
418     if ($runtimeConditional) {
419         print F <<END
420     if (!RuntimeEnabledFeatures::${runtimeConditional}Enabled())
421         return 0;
422 END
423 ;
424     }
425
426     # Call the constructor with the right parameters.
427     print F "    return ${interfaceName}::create($constructorTagName, document";
428     print F ", formElement" if $enabledTags{$tagName}{constructorNeedsFormElement};
429     print F ", createdByParser" if $enabledTags{$tagName}{constructorNeedsCreatedByParser};
430     print F ");\n}\n";
431 }
432
433 sub printConstructors
434 {
435     my ($F, $tagConstructorMapRef) = @_;
436     my %tagConstructorMap = %$tagConstructorMapRef;
437
438     # This is to avoid generating the same constructor several times.
439     my %uniqueTags = ();
440     for my $tagName (sort keys %tagConstructorMap) {
441         my $interfaceName = $enabledTags{$tagName}{interfaceName};
442
443         # Ignore the mapped tag
444         # FIXME: It could be moved inside this loop but was split for readibility.
445         next if (defined($uniqueTags{$interfaceName}) || $enabledTags{$tagName}{mapToTagName});
446         # Tags can have wrappers without constructors.
447         # This is useful to make user-agent shadow elements internally testable
448         # while keeping them from being avaialble in the HTML markup.
449         next if $enabledTags{$tagName}{noConstructor};
450
451         $uniqueTags{$interfaceName} = '1';
452
453         my $conditional = $enabledTags{$tagName}{conditional};
454         if ($conditional) {
455             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
456             print F "#if ${conditionalString}\n";
457         }
458
459         printConstructorSignature($F, $tagName, $tagConstructorMap{$tagName}, "tagName");
460         printConstructorInterior($F, $tagName, $interfaceName, "tagName");
461
462         if ($conditional) {
463             print F "#endif\n";
464         }
465
466         print F "\n";
467     }
468
469     # Mapped tag name uses a special wrapper to keep their prefix and namespaceURI while using the mapped localname.
470     for my $tagName (sort keys %tagConstructorMap) {
471         if ($enabledTags{$tagName}{mapToTagName}) {
472             my $mappedName = $enabledTags{$tagName}{mapToTagName};
473             printConstructorSignature($F, $mappedName, $mappedName . "To" . $tagName, "tagName");
474             printConstructorInterior($F, $mappedName, $enabledTags{$mappedName}{interfaceName}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");
475         }
476     }
477 }
478
479 sub printFunctionInits
480 {
481     my ($F, $tagConstructorMap) = @_;
482     my %tagConstructorMap = %$tagConstructorMap;
483
484     for my $tagName (sort keys %tagConstructorMap) {
485         next if $enabledTags{$tagName}{noConstructor};
486
487         my $conditional = $enabledTags{$tagName}{conditional};
488         if ($conditional) {
489             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
490             print F "#if ${conditionalString}\n";
491         }
492
493         if ($enabledTags{$tagName}{mapToTagName}) {
494             print F "    addTag(${tagName}Tag, $enabledTags{$tagName}{mapToTagName}To${tagName}Constructor);\n";
495         } else {
496             print F "    addTag(${tagName}Tag, $tagConstructorMap{$tagName}Constructor);\n";
497         }
498
499         if ($conditional) {
500             print F "#endif\n";
501         }
502     }
503 }
504
505 sub svgCapitalizationHacks
506 {
507     my $name = shift;
508
509     $name = "FE" . ucfirst $1 if $name =~ /^fe(.+)$/;
510
511     return $name;
512 }
513
514 sub upperCaseName
515 {
516     my $name = shift;
517     
518     $name = svgCapitalizationHacks($name) if ($parameters{namespace} eq "SVG");
519
520     while ($name =~ /^(.*?)_(.*)/) {
521         $name = $1 . ucfirst $2;
522     }
523     
524     return ucfirst $name;
525 }
526
527 sub printHeaderHead
528 {
529     my ($F, $prefix, $nsName, $includes) = @_;
530
531     print F "#ifndef ${prefix}_${nsName}Names_h\n";
532     print F "#define ${prefix}_${nsName}Names_h\n\n";
533     print F "$includes\n\n";
534
535     print F "namespace WebCore {\n\n";
536     print F "namespace ${nsName}Names {\n\n";
537
538     print F "#ifndef ${prefix}_${nsName}NAMES_HIDE_GLOBALS\n";
539 }
540
541 sub printCppHead
542 {
543     my ($F, $prefix, $nsName, $usedNamespace) = @_;
544
545     print F "#include \"config.h\"\n\n";
546     print F "#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC\n";
547     print F "#define ${prefix}_${nsName}NAMES_HIDE_GLOBALS 1\n";
548     print F "#else\n";
549     print F "#define QNAME_DEFAULT_CONSTRUCTOR 1\n";
550     print F "#endif\n\n";
551
552     print F "#include \"${nsName}Names.h\"\n\n";
553     print F "#include <wtf/StaticConstructors.h>\n";
554
555     print F "namespace WebCore {\n\n";
556     print F "namespace ${nsName}Names {\n\n";
557     print F "using namespace $usedNamespace;\n\n";
558 }
559
560 sub printInit
561 {
562     my ($F, $isDefinition) = @_;
563
564     if ($isDefinition) {
565         print F "\nvoid init();\n\n";
566         print F "} }\n\n";
567         print F "#endif\n\n";
568         return;
569     }
570
571 print F "\nvoid init()
572 {
573     static bool initialized = false;
574     if (initialized)
575         return;
576     initialized = true;
577
578     // Use placement new to initialize the globals.
579
580     AtomicString::init();
581 ";
582 }
583
584 sub printLicenseHeader
585 {
586     my $F = shift;
587     print F "/*
588  * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
589  *
590  * This file was generated by the dom/make_names.pl script.
591  *
592  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc.  All rights reserved.
593  *
594  * Redistribution and use in source and binary forms, with or without
595  * modification, are permitted provided that the following conditions
596  * are met:
597  * 1. Redistributions of source code must retain the above copyright
598  *    notice, this list of conditions and the following disclaimer.
599  * 2. Redistributions in binary form must reproduce the above copyright
600  *    notice, this list of conditions and the following disclaimer in the
601  *    documentation and/or other materials provided with the distribution.
602  *
603  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
604  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
605  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
606  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
607  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
608  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
609  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
610  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
611  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
612  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
613  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
614  */
615
616 ";
617 }
618
619 sub printTypeHelpers
620 {
621     my ($F, $namesRef) = @_;
622     my %names = %$namesRef;
623
624     for my $name (sort keys %names) {
625         if (!$parsedTags{$name}{generateTypeHelpers}) {
626             next;
627         }
628
629         my $class = $parsedTags{$name}{interfaceName};
630         my $checkHelper = "is$class";
631         my $castingHelper = "to$class";
632
633         print F "class $class;\n";
634         print F "inline bool $checkHelper(const Element& element) { return element.hasTagName(".$parameters{namespace}."Names::".$name."Tag); }\n";
635         print F "inline bool $checkHelper(const Element* element) { ASSERT(element); return $checkHelper(*element); }\n";
636         print F "inline bool $checkHelper(const Node* node) { ASSERT(node); return node->isElementNode() && $checkHelper(toElement(node)); }\n";
637         print F "template <> inline bool isElementOfType<$class>(const Element* element) { return $checkHelper(element); }\n";
638         print F "inline $class* $castingHelper(Node* node) { ASSERT_WITH_SECURITY_IMPLICATION(!node || $checkHelper(node)); return reinterpret_cast<".$class."*>(node); }\n";
639         print F "inline $class* $castingHelper(Element* element) { ASSERT_WITH_SECURITY_IMPLICATION(!element || $checkHelper(element)); return reinterpret_cast<".$class."*>(element); }\n";
640
641         print F "\n";
642     }
643 }
644
645 sub printTypeHelpersHeaderFile
646 {
647     my ($headerPath) = shift;
648     my $F;
649     open F, ">$headerPath";
650     printLicenseHeader($F);
651
652     print F "#ifndef ".$parameters{namespace}."ElementTypeHelpers_h\n";
653     print F "#define ".$parameters{namespace}."ElementTypeHelpers_h\n\n";
654     print F "#include \"".$parameters{namespace}."Names.h\"\n\n";
655     print F "namespace WebCore {\n\n";
656
657     printTypeHelpers($F, \%allTags);
658
659     print F "}\n\n";
660     print F "#endif\n";
661
662     close F;
663 }
664
665 sub printNamesHeaderFile
666 {
667     my ($headerPath) = shift;
668     my $F;
669     open F, ">$headerPath";
670
671     printLicenseHeader($F);
672     printHeaderHead($F, "DOM", $parameters{namespace}, "#include \"QualifiedName.h\"");
673
674     my $lowerNamespace = lc($parameters{namespacePrefix});
675     print F "// Namespace\n";
676     print F "extern const WTF::AtomicString ${lowerNamespace}NamespaceURI;\n\n";
677
678     if (keys %allTags) {
679         print F "// Tags\n";
680         printMacros($F, "extern const WebCore::QualifiedName", "Tag", \%allTags);
681     }
682
683     if (keys %allAttrs) {
684         print F "// Attributes\n";
685         printMacros($F, "extern const WebCore::QualifiedName", "Attr", \%allAttrs);
686     }
687     print F "#endif\n\n";
688
689     if (keys %allTags) {
690         print F "const unsigned $parameters{namespace}TagsCount = ", scalar(keys %allTags), ";\n";
691         print F "WebCore::QualifiedName** get$parameters{namespace}Tags();\n";
692     }
693
694     if (keys %allAttrs) {
695         print F "const unsigned $parameters{namespace}AttrsCount = ", scalar(keys %allAttrs), ";\n";
696         print F "WebCore::QualifiedName** get$parameters{namespace}Attrs();\n";
697     }
698
699     printInit($F, 1);
700     close F;
701 }
702
703 sub printNamesCppFile
704 {
705     my $cppPath = shift;
706     my $F;
707     open F, ">$cppPath";
708     
709     printLicenseHeader($F);
710     printCppHead($F, "DOM", $parameters{namespace}, "WebCore");
711     
712     my $lowerNamespace = lc($parameters{namespacePrefix});
713
714     print F "DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI)\n\n";
715
716     print F StaticString::GenerateStrings(\%allStrings);
717
718     if (keys %allTags) {
719         print F "// Tags\n";
720         for my $name (sort keys %allTags) {
721             print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag)\n";
722         }
723         
724         print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Tags()\n";
725         print F "{\n    static WebCore::QualifiedName* $parameters{namespace}Tags[] = {\n";
726         for my $name (sort keys %allTags) {
727             print F "        (WebCore::QualifiedName*)&${name}Tag,\n";
728         }
729         print F "    };\n";
730         print F "    return $parameters{namespace}Tags;\n";
731         print F "}\n";
732     }
733
734     if (keys %allAttrs) {
735         print F "\n// Attributes\n";
736         for my $name (sort keys %allAttrs) {
737             print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr)\n";
738         }
739         print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Attrs()\n";
740         print F "{\n    static WebCore::QualifiedName* $parameters{namespace}Attr[] = {\n";
741         for my $name (sort keys %allAttrs) {
742             print F "        (WebCore::QualifiedName*)&${name}Attr,\n";
743         }
744         print F "    };\n";
745         print F "    return $parameters{namespace}Attr;\n";
746         print F "}\n";
747     }
748
749     printInit($F, 0);
750
751     print(F "    AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\", AtomicString::ConstructFromLiteral);\n\n");
752
753     print(F "    // Namespace\n");
754     print(F "    new (NotNull, (void*)&${lowerNamespace}NamespaceURI) AtomicString(${lowerNamespace}NS);\n");
755     print(F "\n");
756     print F StaticString::GenerateStringAsserts(\%allStrings);
757
758     if (keys %allTags) {
759         my $tagsNamespace = $parameters{tagsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
760         printDefinitions($F, \%allTags, "tags", $tagsNamespace);
761     }
762     if (keys %allAttrs) {
763         my $attrsNamespace = $parameters{attrsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
764         printDefinitions($F, \%allAttrs, "attributes", $attrsNamespace);
765     }
766
767     print F "}\n\n} }\n\n";
768     close F;
769 }
770
771 sub printJSElementIncludes
772 {
773     my $F = shift;
774
775     my %tagsSeen;
776     for my $tagName (sort keys %enabledTags) {
777         my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName};
778         next if defined($tagsSeen{$JSInterfaceName}) || usesDefaultJSWrapper($tagName);
779         if ($enabledTags{$tagName}{conditional}) {
780             # We skip feature-define-specific #includes here since we handle them separately.
781             next;
782         }
783         $tagsSeen{$JSInterfaceName} = 1;
784
785         print F "#include \"JS${JSInterfaceName}.h\"\n";
786     }
787     print F "#include \"JS$parameters{fallbackJSInterfaceName}.h\"\n";
788 }
789
790 sub printElementIncludes
791 {
792     my $F = shift;
793
794     my %tagsSeen;
795     for my $tagName (sort keys %enabledTags) {
796         my $interfaceName = $enabledTags{$tagName}{interfaceName};
797         next if defined($tagsSeen{$interfaceName});
798         if ($enabledTags{$tagName}{conditional}) {
799             # We skip feature-define-specific #includes here since we handle them separately.
800             next;
801         }
802         $tagsSeen{$interfaceName} = 1;
803
804         print F "#include \"${interfaceName}.h\"\n";
805     }
806     print F "#include \"$parameters{fallbackInterfaceName}.h\"\n";
807 }
808
809 sub printConditionalElementIncludes
810 {
811     my ($F, $wrapperIncludes) = @_;
812
813     my %conditionals;
814     my %unconditionalElementIncludes;
815     my %unconditionalJSElementIncludes;
816
817     for my $tagName (keys %enabledTags) {
818         my $conditional = $enabledTags{$tagName}{conditional};
819         my $interfaceName = $enabledTags{$tagName}{interfaceName};
820         my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName};
821
822         if ($conditional) {
823             $conditionals{$conditional}{interfaceNames}{$interfaceName} = 1;
824             $conditionals{$conditional}{JSInterfaceNames}{$JSInterfaceName} = 1;
825         } else {
826             $unconditionalElementIncludes{$interfaceName} = 1;
827             $unconditionalJSElementIncludes{$JSInterfaceName} = 1;
828         }
829     }
830
831     for my $conditional (sort keys %conditionals) {
832         print F "\n#if ENABLE($conditional)\n";
833         for my $interfaceName (sort keys %{$conditionals{$conditional}{interfaceNames}}) {
834             next if $unconditionalElementIncludes{$interfaceName};
835             print F "#include \"$interfaceName.h\"\n";
836         }
837         if ($wrapperIncludes) {
838             for my $JSInterfaceName (sort keys %{$conditionals{$conditional}{JSInterfaceNames}}) {
839                 next if $unconditionalJSElementIncludes{$JSInterfaceName};
840                 print F "#include \"JS$JSInterfaceName.h\"\n";
841             }
842         }
843         print F "#endif\n";
844     }
845 }
846
847 sub printDefinitions
848 {
849     my ($F, $namesRef, $type, $namespaceURI) = @_;
850     my $singularType = substr($type, 0, -1);
851     my $shortType = substr($singularType, 0, 4);
852     my $shortCamelType = ucfirst($shortType);
853     my $shortUpperType = uc($shortType);
854     
855     print F "    // " . ucfirst($type) . "\n";
856
857     for my $name (sort keys %$namesRef) {
858         # To generate less code in init(), the common case of nullAtom for the namespace, we call createQualifiedName() without passing $namespaceURI.
859         if ($namespaceURI eq "nullAtom") {
860             print F "    createQualifiedName((void*)&$name","${shortCamelType}, ${name}Impl);\n";
861         } else {
862             print F "    createQualifiedName((void*)&$name","${shortCamelType}, ${name}Impl, $namespaceURI);\n";
863         }
864     }
865 }
866
867 ## ElementFactory routines
868
869 sub printFactoryCppFile
870 {
871     my $cppPath = shift;
872     my $F;
873     open F, ">$cppPath";
874
875 printLicenseHeader($F);
876
877 print F <<END
878 #include "config.h"
879 END
880 ;
881
882 print F "\n#if $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
883
884 print F <<END
885 #include "$parameters{namespace}ElementFactory.h"
886 #include "$parameters{namespace}Names.h"
887 END
888 ;
889
890 printElementIncludes($F);
891
892 print F "\n#include <wtf/HashMap.h>\n";
893
894 printConditionalElementIncludes($F, 0);
895
896 print F <<END
897
898 #include "ContextFeatures.h"
899 #include "RuntimeEnabledFeatures.h"
900
901 #if ENABLE(CUSTOM_ELEMENTS)
902 #include "CustomElementConstructor.h"
903 #include "CustomElementRegistry.h"
904 #endif
905
906 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(VIDEO)
907 #include "Document.h"
908 #include "Settings.h"
909 #endif
910
911 namespace WebCore {
912
913 using namespace $parameters{namespace}Names;
914
915 END
916 ;
917
918 print F "typedef PassRefPtr<$parameters{namespace}Element> (*ConstructorFunction)(const QualifiedName&, Document*";
919 print F ", HTMLFormElement*" if $parameters{namespace} eq "HTML";
920 print F ", bool createdByParser);\n";
921 print F <<END
922 typedef HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
923
924 static FunctionMap* gFunctionMap = 0;
925
926 END
927 ;
928
929 my %tagConstructorMap = buildConstructorMap();
930
931 printConstructors($F, \%tagConstructorMap);
932
933 print F <<END
934 static void addTag(const QualifiedName& tag, ConstructorFunction func)
935 {
936     gFunctionMap->set(tag.localName().impl(), func);
937 }
938
939 static void createFunctionMap()
940 {
941     ASSERT(!gFunctionMap);
942
943     // Create the table.
944     gFunctionMap = new FunctionMap;
945     
946     // Populate it with constructor functions.
947 END
948 ;
949
950 printFunctionInits($F, \%tagConstructorMap);
951
952 print F "}\n";
953
954
955 print F "\nPassRefPtr<$parameters{namespace}Element> $parameters{namespace}ElementFactory::create$parameters{namespace}Element(const QualifiedName& qName, Document* document";
956 print F ", HTMLFormElement* formElement" if $parameters{namespace} eq "HTML";
957 print F ", bool createdByParser)\n{\n";
958
959 print F <<END
960     if (!document)
961         return 0;
962
963 END
964 ;
965
966 if ($parameters{namespace} ne "HTML" and $parameters{namespace} ne "SVG") {
967 print F <<END
968 #if ENABLE(DASHBOARD_SUPPORT)
969     Settings* settings = document->settings();
970     if (settings && settings->usesDashboardBackwardCompatibilityMode())
971         return 0;
972 #endif
973 END
974 ;
975
976 }
977
978 print F <<END
979 #if ENABLE(CUSTOM_ELEMENTS)
980     if (document->registry()) {
981         if (RefPtr<CustomElementConstructor> constructor = document->registry()->find(nullQName(), qName)) {
982             RefPtr<Element> element = constructor->createElement();
983             ASSERT(element->is$parameters{namespace}Element());
984             return static_pointer_cast<$parameters{namespace}Element>(element.release());
985         }
986     }
987 #endif
988
989     if (!gFunctionMap)
990         createFunctionMap();
991     if (ConstructorFunction function = gFunctionMap->get(qName.localName().impl())) {
992 END
993 ;
994
995 if ($parameters{namespace} eq "HTML") {
996     print F "        if (PassRefPtr<$parameters{namespace}Element> element = function(qName, document, formElement, createdByParser))\n";
997     print F "            return element;\n";
998 } else {
999     print F "        if (PassRefPtr<$parameters{namespace}Element> element = function(qName, document, createdByParser))\n";
1000     print F "            return element;\n";
1001 }
1002 print F <<END
1003     }
1004
1005     return $parameters{fallbackInterfaceName}::create(qName, document);
1006 }
1007
1008 } // namespace WebCore
1009
1010 END
1011 ;
1012
1013     print F "#endif\n" if $parameters{guardFactoryWith};
1014
1015     close F;
1016 }
1017
1018 sub printFactoryHeaderFile
1019 {
1020     my $headerPath = shift;
1021     my $F;
1022     open F, ">$headerPath";
1023
1024     printLicenseHeader($F);
1025
1026     print F<<END
1027 #ifndef $parameters{namespace}ElementFactory_h
1028 #define $parameters{namespace}ElementFactory_h
1029
1030 #include <wtf/Forward.h>
1031 #include <wtf/PassRefPtr.h>
1032
1033 namespace WebCore {
1034     class Element;
1035     class Document;
1036     class QualifiedName;
1037 }
1038
1039 namespace WebCore {
1040
1041     class $parameters{namespace}Element;
1042 END
1043 ;
1044
1045 print F "     class HTMLFormElement;\n" if $parameters{namespace} eq "HTML";
1046
1047 print F<<END
1048     // The idea behind this class is that there will eventually be a mapping from namespace URIs to ElementFactories that can dispense
1049     // elements. In a compound document world, the generic createElement function (will end up being virtual) will be called.
1050     class $parameters{namespace}ElementFactory {
1051     public:
1052         PassRefPtr<Element> createElement(const WebCore::QualifiedName&, WebCore::Document*, bool createdByParser = true);
1053 END
1054 ;
1055 print F "        static PassRefPtr<$parameters{namespace}Element> create$parameters{namespace}Element(const WebCore::QualifiedName&, WebCore::Document*";
1056 print F ", HTMLFormElement* = 0" if $parameters{namespace} eq "HTML";
1057 print F ", bool createdByParser = true);\n";
1058
1059 printf F<<END
1060     };
1061 }
1062
1063 #endif // $parameters{namespace}ElementFactory_h
1064
1065 END
1066 ;
1067
1068     close F;
1069 }
1070
1071 ## Wrapper Factory routines
1072
1073 sub usesDefaultJSWrapper
1074 {
1075     my $name = shift;
1076
1077     # A tag reuses the default wrapper if its JSInterfaceName matches the default namespace Element.
1078     return $enabledTags{$name}{JSInterfaceName} eq $parameters{namespace} . "Element";
1079 }
1080
1081 sub printWrapperFunctions
1082 {
1083     my $F = shift;
1084
1085     my %tagsSeen;
1086     for my $tagName (sort keys %enabledTags) {
1087         # Avoid defining the same wrapper method twice.
1088         my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName};
1089         next if defined($tagsSeen{$JSInterfaceName}) || (usesDefaultJSWrapper($tagName) && ($parameters{fallbackJSInterfaceName} eq $parameters{namespace} . "Element"));
1090         $tagsSeen{$JSInterfaceName} = 1;
1091
1092         my $conditional = $enabledTags{$tagName}{conditional};
1093         if ($conditional) {
1094             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
1095             print F "#if ${conditionalString}\n\n";
1096         }
1097
1098         # Hack for the media tags
1099         # FIXME: This should have been done via a CustomWrapper attribute and a separate *Custom file.
1100         if ($enabledTags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
1101             print F <<END
1102 static JSDOMWrapper* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
1103 {
1104     Settings* settings = element->document().settings();
1105     if (!MediaPlayer::isAvailable() || (settings && !settings->mediaEnabled()))
1106         return CREATE_DOM_WRAPPER(exec, globalObject, $parameters{namespace}Element, element.get());
1107     return CREATE_DOM_WRAPPER(exec, globalObject, ${JSInterfaceName}, element.get());
1108 }
1109
1110 END
1111     ;
1112         } elsif ($enabledTags{$tagName}{contextConditional}) {
1113             my $contextConditional = $enabledTags{$tagName}{contextConditional};
1114             print F <<END
1115 static JSDOMWrapper* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
1116 {
1117     if (!ContextFeatures::${contextConditional}Enabled(&element->document())) {
1118         ASSERT(!element || element->is$parameters{fallbackInterfaceName}());
1119         return CREATE_DOM_WRAPPER(exec, globalObject, $parameters{fallbackJSInterfaceName}, element.get());
1120     }
1121
1122     return CREATE_DOM_WRAPPER(exec, globalObject, ${JSInterfaceName}, element.get());
1123 }
1124 END
1125     ;
1126         } elsif ($enabledTags{$tagName}{runtimeConditional}) {
1127             my $runtimeConditional = $enabledTags{$tagName}{runtimeConditional};
1128             print F <<END
1129 static JSDOMWrapper* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
1130 {
1131     if (!RuntimeEnabledFeatures::${runtimeConditional}Enabled()) {
1132         ASSERT(!element || element->is$parameters{fallbackInterfaceName}());
1133         return CREATE_DOM_WRAPPER(exec, globalObject, $parameters{fallbackJSInterfaceName}, element.get());
1134     }
1135
1136     return CREATE_DOM_WRAPPER(exec, globalObject, ${JSInterfaceName}, element.get());
1137 }
1138 END
1139     ;
1140         } else {
1141             print F <<END
1142 static JSDOMWrapper* create${JSInterfaceName}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
1143 {
1144     return CREATE_DOM_WRAPPER(exec, globalObject, ${JSInterfaceName}, element.get());
1145 }
1146
1147 END
1148     ;
1149         }
1150
1151         if ($conditional) {
1152             print F "#endif\n\n";
1153         }
1154     }
1155 }
1156
1157 sub printWrapperFactoryCppFile
1158 {
1159     my $outputDir = shift;
1160     my $wrapperFactoryFileName = shift;
1161     my $F;
1162     open F, ">" . $outputDir . "/JS" . $wrapperFactoryFileName . ".cpp";
1163
1164     printLicenseHeader($F);
1165
1166     print F "#include \"config.h\"\n";
1167     print F "#include \"JS$parameters{namespace}ElementWrapperFactory.h\"\n";
1168
1169     print F "\n#if $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
1170
1171     printJSElementIncludes($F);
1172
1173     print F "\n#include \"$parameters{namespace}Names.h\"\n\n";
1174
1175     printElementIncludes($F);
1176
1177     print F "\n#include <wtf/StdLibExtras.h>\n";
1178
1179     printConditionalElementIncludes($F, 1);
1180
1181     print F <<END
1182
1183 #include "ContextFeatures.h"
1184 #include "RuntimeEnabledFeatures.h"
1185
1186 #if ENABLE(VIDEO)
1187 #include "Document.h"
1188 #include "Settings.h"
1189 #endif
1190
1191 END
1192 ;
1193
1194     print F <<END
1195 using namespace JSC;
1196 END
1197 ;
1198
1199     print F <<END
1200
1201 namespace WebCore {
1202
1203 using namespace $parameters{namespace}Names;
1204
1205 END
1206 ;
1207 print F <<END
1208 typedef JSDOMWrapper* (*Create$parameters{namespace}ElementWrapperFunction)(ExecState*, JSDOMGlobalObject*, PassRefPtr<$parameters{namespace}Element>);
1209
1210 END
1211 ;
1212
1213     printWrapperFunctions($F);
1214
1215 print F <<END
1216 JSDOMWrapper* createJS$parameters{namespace}Wrapper(ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<$parameters{namespace}Element> element)
1217 {
1218     typedef HashMap<WTF::AtomicStringImpl*, Create$parameters{namespace}ElementWrapperFunction> FunctionMap;
1219     DEFINE_STATIC_LOCAL(FunctionMap, map, ());
1220     if (map.isEmpty()) {
1221 END
1222 ;
1223
1224     for my $tag (sort keys %enabledTags) {
1225         # Do not add the name to the map if it does not have a JS wrapper constructor or uses the default wrapper.
1226         next if (usesDefaultJSWrapper($tag, \%enabledTags) && ($parameters{fallbackJSInterfaceName} eq $parameters{namespace} . "Element"));
1227
1228         my $conditional = $enabledTags{$tag}{conditional};
1229         if ($conditional) {
1230             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
1231             print F "#if ${conditionalString}\n";
1232         }
1233
1234         my $ucTag = $enabledTags{$tag}{JSInterfaceName};
1235         print F "       map.set(${tag}Tag.localName().impl(), create${ucTag}Wrapper);\n";
1236
1237         if ($conditional) {
1238             print F "#endif\n";
1239         }
1240     }
1241
1242     print F <<END
1243     }
1244 END
1245 ;
1246
1247     print F <<END
1248     Create$parameters{namespace}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl());
1249     if (createWrapperFunction)
1250 END
1251 ;
1252     print F <<END
1253         return createWrapperFunction(exec, globalObject, element);
1254     return CREATE_DOM_WRAPPER(exec, globalObject, $parameters{fallbackJSInterfaceName}, element.get());
1255 END
1256 ;
1257     print F <<END
1258 }
1259 END
1260 ;
1261
1262     print F "}\n\n";
1263     print F "#endif\n" if $parameters{guardFactoryWith};
1264
1265     close F;
1266 }
1267
1268 sub printWrapperFactoryHeaderFile
1269 {
1270     my $outputDir = shift;
1271     my $wrapperFactoryFileName = shift;
1272     my $F;
1273     open F, ">" . $outputDir . "/JS" . $wrapperFactoryFileName . ".h";
1274
1275     printLicenseHeader($F);
1276
1277     print F "#ifndef JS$parameters{namespace}ElementWrapperFactory_h\n";
1278     print F "#define JS$parameters{namespace}ElementWrapperFactory_h\n\n";
1279
1280     print F "#if $parameters{guardFactoryWith}\n" if $parameters{guardFactoryWith};
1281
1282     print F <<END
1283 #include <wtf/Forward.h>
1284
1285 namespace JSC {
1286     class ExecState;
1287 }                                            
1288                                              
1289 namespace WebCore {
1290
1291     class JSDOMWrapper;
1292     class JSDOMGlobalObject;
1293     class $parameters{namespace}Element;
1294
1295     JSDOMWrapper* createJS$parameters{namespace}Wrapper(JSC::ExecState*, JSDOMGlobalObject*, PassRefPtr<$parameters{namespace}Element>);
1296
1297 }
1298  
1299 END
1300     ;
1301
1302     print F "#endif // $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
1303
1304     print F "#endif // JS$parameters{namespace}ElementWrapperFactory_h\n";
1305
1306     close F;
1307 }