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