From fac747bdbdba6aeaba4bed91ef49b2378c1798e4 Mon Sep 17 00:00:00 2001 From: Marcus Bointon Date: Tue, 16 Jul 2013 13:56:14 +0200 Subject: [PATCH] PSR-2 reformatting PHPDoc corrections With minor corrections. Signed-off-by: Marcus Bointon Signed-off-by: Edward Z. Yang --- benchmarks/Lexer.php | 15 +- extras/ConfigDoc/HTMLXSLTProcessor.php | 15 +- extras/FSTools.php | 21 +- extras/FSTools/File.php | 45 +- extras/HTMLPurifierExtras.autoload.php | 3 +- extras/HTMLPurifierExtras.php | 6 +- library/HTMLPurifier.autoload.php | 3 +- library/HTMLPurifier.func.php | 8 +- library/HTMLPurifier.kses.php | 4 +- library/HTMLPurifier.php | 71 +- library/HTMLPurifier/AttrCollections.php | 53 +- library/HTMLPurifier/AttrDef.php | 53 +- library/HTMLPurifier/AttrDef/CSS.php | 39 +- library/HTMLPurifier/AttrDef/CSS/AlphaValue.php | 27 +- library/HTMLPurifier/AttrDef/CSS/Background.php | 58 +- .../AttrDef/CSS/BackgroundPosition.php | 54 +- library/HTMLPurifier/AttrDef/CSS/Border.php | 21 +- library/HTMLPurifier/AttrDef/CSS/Color.php | 67 +- library/HTMLPurifier/AttrDef/CSS/Composite.php | 22 +- .../AttrDef/CSS/DenyElementDecorator.php | 28 +- library/HTMLPurifier/AttrDef/CSS/Filter.php | 49 +- library/HTMLPurifier/AttrDef/CSS/Font.php | 89 +- library/HTMLPurifier/AttrDef/CSS/FontFamily.php | 42 +- library/HTMLPurifier/AttrDef/CSS/Ident.php | 20 +- .../AttrDef/CSS/ImportantDecorator.php | 28 +- library/HTMLPurifier/AttrDef/CSS/Length.php | 60 +- library/HTMLPurifier/AttrDef/CSS/ListStyle.php | 78 +- library/HTMLPurifier/AttrDef/CSS/Multiple.php | 31 +- library/HTMLPurifier/AttrDef/CSS/Number.php | 45 +- library/HTMLPurifier/AttrDef/CSS/Percentage.php | 36 +- .../HTMLPurifier/AttrDef/CSS/TextDecoration.php | 20 +- library/HTMLPurifier/AttrDef/CSS/URI.php | 31 +- library/HTMLPurifier/AttrDef/Clone.php | 26 +- library/HTMLPurifier/AttrDef/Enum.php | 28 +- library/HTMLPurifier/AttrDef/HTML/Bool.php | 35 +- library/HTMLPurifier/AttrDef/HTML/Class.php | 22 +- library/HTMLPurifier/AttrDef/HTML/Color.php | 84 +- library/HTMLPurifier/AttrDef/HTML/FrameTarget.php | 25 +- library/HTMLPurifier/AttrDef/HTML/ID.php | 55 +- library/HTMLPurifier/AttrDef/HTML/Length.php | 41 +- library/HTMLPurifier/AttrDef/HTML/LinkTypes.php | 43 +- library/HTMLPurifier/AttrDef/HTML/MultiLength.php | 51 +- library/HTMLPurifier/AttrDef/HTML/Nmtokens.php | 40 +- library/HTMLPurifier/AttrDef/HTML/Pixels.php | 60 +- library/HTMLPurifier/AttrDef/Integer.php | 56 +- library/HTMLPurifier/AttrDef/Lang.php | 39 +- library/HTMLPurifier/AttrDef/Switch.php | 27 +- library/HTMLPurifier/AttrDef/Text.php | 10 +- library/HTMLPurifier/AttrDef/URI.php | 70 +- library/HTMLPurifier/AttrDef/URI/Email.php | 5 +- .../HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php | 14 +- library/HTMLPurifier/AttrDef/URI/Host.php | 40 +- library/HTMLPurifier/AttrDef/URI/IPv4.php | 28 +- library/HTMLPurifier/AttrDef/URI/IPv6.php | 188 +- library/HTMLPurifier/AttrTransform.php | 28 +- library/HTMLPurifier/AttrTransform/Background.php | 21 +- library/HTMLPurifier/AttrTransform/BdoDir.php | 14 +- library/HTMLPurifier/AttrTransform/BgColor.php | 21 +- library/HTMLPurifier/AttrTransform/BoolToCSS.php | 33 +- library/HTMLPurifier/AttrTransform/Border.php | 18 +- library/HTMLPurifier/AttrTransform/EnumToCSS.php | 46 +- library/HTMLPurifier/AttrTransform/ImgRequired.php | 19 +- library/HTMLPurifier/AttrTransform/ImgSpace.php | 39 +- library/HTMLPurifier/AttrTransform/Input.php | 34 +- library/HTMLPurifier/AttrTransform/Lang.php | 15 +- library/HTMLPurifier/AttrTransform/Length.php | 28 +- library/HTMLPurifier/AttrTransform/Name.php | 22 +- library/HTMLPurifier/AttrTransform/NameSync.php | 28 +- library/HTMLPurifier/AttrTransform/Nofollow.php | 19 +- library/HTMLPurifier/AttrTransform/SafeEmbed.php | 12 +- library/HTMLPurifier/AttrTransform/SafeObject.php | 16 +- library/HTMLPurifier/AttrTransform/SafeParam.php | 19 +- .../HTMLPurifier/AttrTransform/ScriptRequired.php | 9 +- library/HTMLPurifier/AttrTransform/TargetBlank.php | 19 +- library/HTMLPurifier/AttrTransform/Textarea.php | 19 +- library/HTMLPurifier/AttrTypes.php | 33 +- library/HTMLPurifier/AttrValidator.php | 62 +- library/HTMLPurifier/Bootstrap.php | 45 +- library/HTMLPurifier/CSSDefinition.php | 438 +- library/HTMLPurifier/ChildDef.php | 22 +- library/HTMLPurifier/ChildDef/Chameleon.php | 33 +- library/HTMLPurifier/ChildDef/Custom.php | 43 +- library/HTMLPurifier/ChildDef/Empty.php | 22 +- library/HTMLPurifier/ChildDef/List.php | 35 +- library/HTMLPurifier/ChildDef/Optional.php | 27 +- library/HTMLPurifier/ChildDef/Required.php | 44 +- library/HTMLPurifier/ChildDef/StrictBlockquote.php | 70 +- library/HTMLPurifier/ChildDef/Table.php | 91 +- library/HTMLPurifier/Config.php | 86 +- library/HTMLPurifier/ConfigSchema.php | 70 +- .../ConfigSchema/Builder/ConfigSchema.php | 8 +- library/HTMLPurifier/ConfigSchema/Builder/Xml.php | 94 +- library/HTMLPurifier/ConfigSchema/Interchange.php | 11 +- .../ConfigSchema/Interchange/Directive.php | 28 +- .../HTMLPurifier/ConfigSchema/Interchange/Id.php | 33 +- .../ConfigSchema/InterchangeBuilder.php | 90 +- library/HTMLPurifier/ConfigSchema/Validator.php | 90 +- .../HTMLPurifier/ConfigSchema/ValidatorAtom.php | 108 +- library/HTMLPurifier/ContentSets.php | 55 +- library/HTMLPurifier/Context.php | 53 +- library/HTMLPurifier/Definition.php | 15 +- library/HTMLPurifier/DefinitionCache.php | 57 +- library/HTMLPurifier/DefinitionCache/Decorator.php | 42 +- .../DefinitionCache/Decorator/Cleanup.php | 61 +- .../DefinitionCache/Decorator/Memory.php | 65 +- .../DefinitionCache/Decorator/Template.php.in | 59 +- library/HTMLPurifier/DefinitionCache/Null.php | 53 +- .../HTMLPurifier/DefinitionCache/Serializer.php | 202 +- library/HTMLPurifier/DefinitionCacheFactory.php | 24 +- library/HTMLPurifier/Doctype.php | 17 +- library/HTMLPurifier/DoctypeRegistry.php | 87 +- library/HTMLPurifier/ElementDef.php | 69 +- library/HTMLPurifier/Encoder.php | 158 +- library/HTMLPurifier/EntityLookup.php | 16 +- library/HTMLPurifier/EntityParser.php | 53 +- library/HTMLPurifier/ErrorCollector.php | 87 +- library/HTMLPurifier/ErrorStruct.php | 20 +- library/HTMLPurifier/Filter.php | 18 +- library/HTMLPurifier/Filter/ExtractStyleBlocks.php | 91 +- library/HTMLPurifier/Filter/YouTube.php | 56 +- library/HTMLPurifier/Generator.php | 110 +- library/HTMLPurifier/HTMLDefinition.php | 204 +- library/HTMLPurifier/HTMLModule.php | 122 +- library/HTMLPurifier/HTMLModule/Bdo.php | 19 +- .../HTMLPurifier/HTMLModule/CommonAttributes.php | 7 +- library/HTMLPurifier/HTMLModule/Edit.php | 25 +- library/HTMLPurifier/HTMLModule/Forms.php | 309 +- library/HTMLPurifier/HTMLModule/Hypertext.php | 15 +- library/HTMLPurifier/HTMLModule/Iframe.php | 19 +- library/HTMLPurifier/HTMLModule/Image.php | 17 +- library/HTMLPurifier/HTMLModule/Legacy.php | 73 +- library/HTMLPurifier/HTMLModule/List.php | 14 +- library/HTMLPurifier/HTMLModule/Name.php | 11 +- library/HTMLPurifier/HTMLModule/Nofollow.php | 10 +- .../HTMLModule/NonXMLCommonAttributes.php | 6 + library/HTMLPurifier/HTMLModule/Object.php | 31 +- library/HTMLPurifier/HTMLModule/Presentation.php | 26 +- library/HTMLPurifier/HTMLModule/Proprietary.php | 19 +- library/HTMLPurifier/HTMLModule/Ruby.php | 17 +- library/HTMLPurifier/HTMLModule/SafeEmbed.php | 18 +- library/HTMLPurifier/HTMLModule/SafeObject.php | 32 +- library/HTMLPurifier/HTMLModule/SafeScripting.php | 15 +- library/HTMLPurifier/HTMLModule/Scripting.php | 27 +- library/HTMLPurifier/HTMLModule/StyleAttribute.php | 15 +- library/HTMLPurifier/HTMLModule/Tables.php | 28 +- library/HTMLPurifier/HTMLModule/Target.php | 11 +- library/HTMLPurifier/HTMLModule/TargetBlank.php | 11 +- library/HTMLPurifier/HTMLModule/Text.php | 56 +- library/HTMLPurifier/HTMLModule/Tidy.php | 85 +- library/HTMLPurifier/HTMLModule/Tidy/Name.php | 15 +- .../HTMLPurifier/HTMLModule/Tidy/Proprietary.php | 14 +- library/HTMLPurifier/HTMLModule/Tidy/Strict.php | 28 +- .../HTMLPurifier/HTMLModule/Tidy/Transitional.php | 7 + library/HTMLPurifier/HTMLModule/Tidy/XHTML.php | 15 +- .../HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php | 146 +- .../HTMLModule/XMLCommonAttributes.php | 6 + library/HTMLPurifier/HTMLModuleManager.php | 137 +- library/HTMLPurifier/IDAccumulator.php | 24 +- library/HTMLPurifier/Injector.php | 161 +- library/HTMLPurifier/Injector/AutoParagraph.php | 97 +- library/HTMLPurifier/Injector/DisplayLinkURI.php | 22 +- library/HTMLPurifier/Injector/Linkify.php | 24 +- library/HTMLPurifier/Injector/PurifierLinkify.php | 46 +- library/HTMLPurifier/Injector/RemoveEmpty.php | 68 +- .../Injector/RemoveSpansWithoutAttributes.php | 36 +- library/HTMLPurifier/Injector/SafeObject.php | 52 +- library/HTMLPurifier/Language.php | 97 +- .../HTMLPurifier/Language/classes/en-x-test.php | 3 - library/HTMLPurifier/Language/messages/en.php | 118 +- library/HTMLPurifier/LanguageFactory.php | 81 +- library/HTMLPurifier/Length.php | 91 +- library/HTMLPurifier/Lexer.php | 169 +- library/HTMLPurifier/Lexer/DOMLex.php | 105 +- library/HTMLPurifier/Lexer/DirectLex.php | 208 +- library/HTMLPurifier/Lexer/PH5P.php | 4322 ++++++++++++-------- library/HTMLPurifier/PercentEncoder.php | 37 +- library/HTMLPurifier/Printer.php | 134 +- library/HTMLPurifier/Printer/CSSDefinition.php | 12 +- library/HTMLPurifier/Printer/ConfigForm.php | 257 +- library/HTMLPurifier/Printer/HTMLDefinition.php | 214 +- library/HTMLPurifier/PropertyList.php | 68 +- library/HTMLPurifier/PropertyListIterator.php | 22 +- library/HTMLPurifier/Strategy.php | 8 +- library/HTMLPurifier/Strategy/Composite.php | 11 +- library/HTMLPurifier/Strategy/Core.php | 5 +- library/HTMLPurifier/Strategy/FixNesting.php | 46 +- library/HTMLPurifier/Strategy/MakeWellFormed.php | 195 +- .../Strategy/RemoveForeignElements.php | 67 +- .../HTMLPurifier/Strategy/ValidateAttributes.php | 20 +- library/HTMLPurifier/StringHash.php | 16 +- library/HTMLPurifier/StringHashParser.php | 52 +- library/HTMLPurifier/TagTransform.php | 15 +- library/HTMLPurifier/TagTransform/Font.php | 36 +- library/HTMLPurifier/TagTransform/Simple.php | 21 +- library/HTMLPurifier/Token.php | 78 +- library/HTMLPurifier/Token/Comment.php | 20 +- library/HTMLPurifier/Token/Empty.php | 1 - library/HTMLPurifier/Token/End.php | 5 +- library/HTMLPurifier/Token/Start.php | 1 - library/HTMLPurifier/Token/Tag.php | 15 +- library/HTMLPurifier/Token/Text.php | 32 +- library/HTMLPurifier/TokenFactory.php | 80 +- library/HTMLPurifier/URI.php | 138 +- library/HTMLPurifier/URIDefinition.php | 27 +- library/HTMLPurifier/URIFilter.php | 25 +- library/HTMLPurifier/URIFilter/DisableExternal.php | 45 +- .../URIFilter/DisableExternalResources.php | 17 +- .../HTMLPurifier/URIFilter/DisableResources.php | 13 +- library/HTMLPurifier/URIFilter/HostBlacklist.php | 27 +- library/HTMLPurifier/URIFilter/MakeAbsolute.php | 74 +- library/HTMLPurifier/URIFilter/Munge.php | 87 +- library/HTMLPurifier/URIFilter/SafeIframe.php | 49 +- library/HTMLPurifier/URIParser.php | 7 +- library/HTMLPurifier/URIScheme.php | 37 +- library/HTMLPurifier/URIScheme/data.php | 53 +- library/HTMLPurifier/URIScheme/file.php | 38 +- library/HTMLPurifier/URIScheme/ftp.php | 28 +- library/HTMLPurifier/URIScheme/http.php | 25 +- library/HTMLPurifier/URIScheme/https.php | 11 +- library/HTMLPurifier/URIScheme/mailto.php | 21 +- library/HTMLPurifier/URIScheme/news.php | 27 +- library/HTMLPurifier/URIScheme/nntp.php | 23 +- library/HTMLPurifier/URISchemeRegistry.php | 41 +- library/HTMLPurifier/UnitConverter.php | 117 +- library/HTMLPurifier/VarParser.php | 152 +- library/HTMLPurifier/VarParser/Flexible.php | 81 +- library/HTMLPurifier/VarParser/Native.php | 18 +- maintenance/PH5P.php | 205 +- maintenance/common.php | 9 +- maintenance/config-scanner.php | 6 +- maintenance/flush.php | 3 +- maintenance/generate-entity-file.php | 5 +- maintenance/generate-includes.php | 10 +- maintenance/generate-standalone.php | 24 +- maintenance/old-extract-schema.php | 3 +- maintenance/update-freshmeat.php | 15 +- plugins/phorum/htmlpurifier.php | 25 +- plugins/phorum/init-config.php | 6 +- plugins/phorum/migrate.bbcode.php | 3 +- plugins/phorum/settings/form.php | 6 +- plugins/phorum/settings/migrate-sigs-form.php | 4 +- plugins/phorum/settings/migrate-sigs.php | 6 +- plugins/phorum/settings/save.php | 6 +- smoketests/cacheConfig.php | 1 - smoketests/common.php | 6 +- smoketests/xssAttacks.php | 3 +- tests/CliTestCase.php | 21 +- tests/Debugger.php | 51 +- tests/FSTools/FileSystemHarness.php | 12 +- tests/FSTools/FileTest.php | 9 +- tests/HTMLPurifier/AttrCollectionsTest.php | 12 +- tests/HTMLPurifier/AttrDef/CSS/AlphaValueTest.php | 4 +- .../AttrDef/CSS/BackgroundPositionTest.php | 4 +- tests/HTMLPurifier/AttrDef/CSS/BackgroundTest.php | 4 +- tests/HTMLPurifier/AttrDef/CSS/BorderTest.php | 4 +- tests/HTMLPurifier/AttrDef/CSS/ColorTest.php | 4 +- tests/HTMLPurifier/AttrDef/CSS/CompositeTest.php | 7 +- tests/HTMLPurifier/AttrDef/CSS/FilterTest.php | 4 +- tests/HTMLPurifier/AttrDef/CSS/FontFamilyTest.php | 7 +- tests/HTMLPurifier/AttrDef/CSS/FontTest.php | 4 +- .../AttrDef/CSS/ImportantDecoratorTest.php | 21 +- tests/HTMLPurifier/AttrDef/CSS/LengthTest.php | 11 +- tests/HTMLPurifier/AttrDef/CSS/ListStyleTest.php | 4 +- tests/HTMLPurifier/AttrDef/CSS/MultipleTest.php | 3 +- tests/HTMLPurifier/AttrDef/CSS/NumberTest.php | 8 +- tests/HTMLPurifier/AttrDef/CSS/PercentageTest.php | 4 +- .../AttrDef/CSS/TextDecorationTest.php | 4 +- tests/HTMLPurifier/AttrDef/CSS/URITest.php | 4 +- tests/HTMLPurifier/AttrDef/CSSTest.php | 22 +- tests/HTMLPurifier/AttrDef/EnumTest.php | 12 +- tests/HTMLPurifier/AttrDef/HTML/BoolTest.php | 6 +- tests/HTMLPurifier/AttrDef/HTML/ClassTest.php | 15 +- tests/HTMLPurifier/AttrDef/HTML/ColorTest.php | 3 +- .../HTMLPurifier/AttrDef/HTML/FrameTargetTest.php | 9 +- tests/HTMLPurifier/AttrDef/HTML/IDTest.php | 26 +- tests/HTMLPurifier/AttrDef/HTML/LengthTest.php | 7 +- tests/HTMLPurifier/AttrDef/HTML/LinkTypesTest.php | 4 +- .../HTMLPurifier/AttrDef/HTML/MultiLengthTest.php | 7 +- tests/HTMLPurifier/AttrDef/HTML/NmtokensTest.php | 7 +- tests/HTMLPurifier/AttrDef/HTML/PixelsTest.php | 10 +- tests/HTMLPurifier/AttrDef/IntegerTest.php | 11 +- tests/HTMLPurifier/AttrDef/LangTest.php | 4 +- tests/HTMLPurifier/AttrDef/SwitchTest.php | 9 +- tests/HTMLPurifier/AttrDef/TextTest.php | 4 +- .../AttrDef/URI/Email/SimpleCheckTest.php | 3 +- tests/HTMLPurifier/AttrDef/URI/EmailHarness.php | 3 +- tests/HTMLPurifier/AttrDef/URI/HostTest.php | 7 +- tests/HTMLPurifier/AttrDef/URI/IPv4Test.php | 4 +- tests/HTMLPurifier/AttrDef/URI/IPv6Test.php | 4 +- tests/HTMLPurifier/AttrDef/URITest.php | 49 +- tests/HTMLPurifier/AttrDefHarness.php | 6 +- tests/HTMLPurifier/AttrDefTest.php | 8 +- .../HTMLPurifier/AttrTransform/BackgroundTest.php | 15 +- tests/HTMLPurifier/AttrTransform/BdoDirTest.php | 12 +- tests/HTMLPurifier/AttrTransform/BgColorTest.php | 15 +- tests/HTMLPurifier/AttrTransform/BoolToCSSTest.php | 15 +- tests/HTMLPurifier/AttrTransform/BorderTest.php | 15 +- tests/HTMLPurifier/AttrTransform/EnumToCSSTest.php | 27 +- .../HTMLPurifier/AttrTransform/ImgRequiredTest.php | 18 +- tests/HTMLPurifier/AttrTransform/ImgSpaceTest.php | 21 +- tests/HTMLPurifier/AttrTransform/InputTest.php | 33 +- tests/HTMLPurifier/AttrTransform/LangTest.php | 18 +- tests/HTMLPurifier/AttrTransform/LengthTest.php | 18 +- tests/HTMLPurifier/AttrTransform/NameSyncTest.php | 15 +- tests/HTMLPurifier/AttrTransform/NameTest.php | 12 +- tests/HTMLPurifier/AttrTransformHarness.php | 3 +- tests/HTMLPurifier/AttrTransformTest.php | 8 +- tests/HTMLPurifier/AttrTypesTest.php | 3 +- tests/HTMLPurifier/AttrValidator_ErrorsTest.php | 15 +- tests/HTMLPurifier/ChildDef/ChameleonTest.php | 12 +- tests/HTMLPurifier/ChildDef/CustomTest.php | 27 +- tests/HTMLPurifier/ChildDef/ListTest.php | 30 +- tests/HTMLPurifier/ChildDef/OptionalTest.php | 18 +- tests/HTMLPurifier/ChildDef/RequiredTest.php | 30 +- .../HTMLPurifier/ChildDef/StrictBlockquoteTest.php | 39 +- tests/HTMLPurifier/ChildDef/TableTest.php | 33 +- tests/HTMLPurifier/ChildDefHarness.php | 3 +- tests/HTMLPurifier/ComplexHarness.php | 33 +- .../HTMLPurifier/ConfigSchema/InterchangeTest.php | 6 +- .../ConfigSchema/ValidatorAtomTest.php | 54 +- tests/HTMLPurifier/ConfigSchema/ValidatorTest.php | 30 +- .../ConfigSchema/ValidatorTestCase.php | 9 +- tests/HTMLPurifier/ConfigSchemaTest.php | 15 +- tests/HTMLPurifier/ConfigTest.php | 96 +- tests/HTMLPurifier/ContextTest.php | 15 +- .../DefinitionCache/Decorator/CleanupTest.php | 24 +- .../DefinitionCache/Decorator/MemoryTest.php | 30 +- .../DefinitionCache/DecoratorHarness.php | 6 +- .../HTMLPurifier/DefinitionCache/DecoratorTest.php | 4 +- .../DefinitionCache/SerializerTest.php | 32 +- tests/HTMLPurifier/DefinitionCacheFactoryTest.php | 27 +- tests/HTMLPurifier/DefinitionCacheHarness.php | 6 +- tests/HTMLPurifier/DefinitionCacheTest.php | 3 +- tests/HTMLPurifier/DefinitionTest.php | 6 +- tests/HTMLPurifier/DoctypeRegistryTest.php | 12 +- tests/HTMLPurifier/ElementDefTest.php | 4 +- tests/HTMLPurifier/EncoderTest.php | 64 +- tests/HTMLPurifier/EntityLookupTest.php | 4 +- tests/HTMLPurifier/EntityParserTest.php | 9 +- tests/HTMLPurifier/ErrorCollectorEMock.php | 12 +- tests/HTMLPurifier/ErrorCollectorTest.php | 20 +- tests/HTMLPurifier/ErrorsHarness.php | 12 +- .../HTMLPurifier/Filter/ExtractStyleBlocksTest.php | 78 +- tests/HTMLPurifier/GeneratorTest.php | 97 +- tests/HTMLPurifier/HTMLDefinitionTest.php | 122 +- tests/HTMLPurifier/HTMLModule/FormsTest.php | 33 +- tests/HTMLPurifier/HTMLModule/ImageTest.php | 18 +- tests/HTMLPurifier/HTMLModule/NameTest.php | 12 +- tests/HTMLPurifier/HTMLModule/NofollowTest.php | 9 +- tests/HTMLPurifier/HTMLModule/ObjectTest.php | 12 +- tests/HTMLPurifier/HTMLModule/ProprietaryTest.php | 6 +- tests/HTMLPurifier/HTMLModule/RubyTest.php | 15 +- tests/HTMLPurifier/HTMLModule/SafeEmbedTest.php | 15 +- tests/HTMLPurifier/HTMLModule/SafeObjectTest.php | 18 +- .../HTMLPurifier/HTMLModule/SafeScriptingTest.php | 12 +- tests/HTMLPurifier/HTMLModule/ScriptingTest.php | 18 +- tests/HTMLPurifier/HTMLModule/TargetBlankTest.php | 6 +- tests/HTMLPurifier/HTMLModule/TidyTest.php | 24 +- tests/HTMLPurifier/HTMLModuleHarness.php | 3 +- tests/HTMLPurifier/HTMLModuleManagerTest.php | 11 +- tests/HTMLPurifier/HTMLModuleTest.php | 24 +- tests/HTMLPurifier/HTMLT.php | 6 +- tests/HTMLPurifier/Harness.php | 49 +- tests/HTMLPurifier/IDAccumulatorTest.php | 11 +- tests/HTMLPurifier/Injector/AutoParagraphTest.php | 171 +- tests/HTMLPurifier/Injector/DisplayLinkURITest.php | 12 +- tests/HTMLPurifier/Injector/LinkifyTest.php | 21 +- .../HTMLPurifier/Injector/PurifierLinkifyTest.php | 27 +- tests/HTMLPurifier/Injector/RemoveEmptyTest.php | 48 +- .../Injector/RemoveSpansWithoutAttributesTest.php | 39 +- tests/HTMLPurifier/Injector/SafeObjectTest.php | 33 +- tests/HTMLPurifier/InjectorHarness.php | 3 +- tests/HTMLPurifier/LanguageFactoryTest.php | 17 +- tests/HTMLPurifier/LanguageTest.php | 18 +- tests/HTMLPurifier/LengthTest.php | 21 +- tests/HTMLPurifier/Lexer/DirectLexTest.php | 11 +- tests/HTMLPurifier/Lexer/DirectLex_ErrorsTest.php | 27 +- tests/HTMLPurifier/LexerTest.php | 201 +- tests/HTMLPurifier/PercentEncoderTest.php | 24 +- tests/HTMLPurifier/PropertyListTest.php | 24 +- tests/HTMLPurifier/SimpleTest/Reporter.php | 15 +- tests/HTMLPurifier/SimpleTest/TextReporter.php | 9 +- tests/HTMLPurifier/Strategy/CompositeTest.php | 7 +- tests/HTMLPurifier/Strategy/CoreTest.php | 18 +- tests/HTMLPurifier/Strategy/ErrorsHarness.php | 3 +- tests/HTMLPurifier/Strategy/FixNestingTest.php | 75 +- .../Strategy/FixNesting_ErrorsTest.php | 18 +- .../Strategy/MakeWellFormed/EndInsertInjector.php | 3 +- .../MakeWellFormed/EndInsertInjectorTest.php | 27 +- .../Strategy/MakeWellFormed/EndRewindInjector.php | 9 +- .../MakeWellFormed/EndRewindInjectorTest.php | 18 +- .../Strategy/MakeWellFormed/SkipInjector.php | 3 +- .../Strategy/MakeWellFormed/SkipInjectorTest.php | 12 +- tests/HTMLPurifier/Strategy/MakeWellFormedTest.php | 63 +- .../Strategy/MakeWellFormed_ErrorsTest.php | 27 +- .../Strategy/MakeWellFormed_InjectorTest.php | 42 +- .../Strategy/RemoveForeignElementsTest.php | 54 +- .../Strategy/RemoveForeignElements_ErrorsTest.php | 30 +- .../Strategy/RemoveForeignElements_TidyTest.php | 15 +- .../Strategy/ValidateAttributesTest.php | 93 +- .../Strategy/ValidateAttributes_IDTest.php | 24 +- .../Strategy/ValidateAttributes_TidyTest.php | 147 +- tests/HTMLPurifier/StrategyHarness.php | 3 +- tests/HTMLPurifier/StringHashParserTest.php | 24 +- tests/HTMLPurifier/StringHashTest.php | 3 +- tests/HTMLPurifier/TagTransformTest.php | 15 +- tests/HTMLPurifier/TokenFactoryTest.php | 4 +- tests/HTMLPurifier/TokenTest.php | 4 +- tests/HTMLPurifier/URIDefinitionTest.php | 18 +- .../URIFilter/DisableExternalResourcesTest.php | 6 +- .../HTMLPurifier/URIFilter/DisableExternalTest.php | 21 +- .../URIFilter/DisableResourcesTest.php | 9 +- tests/HTMLPurifier/URIFilter/HostBlacklistTest.php | 12 +- tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php | 87 +- tests/HTMLPurifier/URIFilter/MungeTest.php | 69 +- tests/HTMLPurifier/URIFilterHarness.php | 3 +- tests/HTMLPurifier/URIHarness.php | 6 +- tests/HTMLPurifier/URIParserTest.php | 57 +- tests/HTMLPurifier/URISchemeRegistryTest.php | 4 +- tests/HTMLPurifier/URISchemeTest.php | 81 +- tests/HTMLPurifier/URITest.php | 87 +- tests/HTMLPurifier/UnitConverterTest.php | 33 +- tests/HTMLPurifier/VarParser/FlexibleTest.php | 10 +- tests/HTMLPurifier/VarParser/NativeTest.php | 3 +- tests/HTMLPurifier/VarParserHarness.php | 9 +- tests/HTMLPurifierTest.php | 19 +- tests/PHPT/Controller/SimpleTest.php | 6 +- tests/PHPT/Reporter/SimpleTest.php | 27 +- tests/PHPT/Section/PRESKIPIF.php | 10 +- tests/common.php | 30 +- tests/generate_mock_once.func.php | 3 +- tests/index.php | 2 +- tests/path2class.func.php | 3 +- 433 files changed, 13355 insertions(+), 6743 deletions(-) rewrite library/HTMLPurifier/AttrDef/HTML/Color.php (61%) rewrite library/HTMLPurifier/AttrDef/URI/IPv6.php (66%) rewrite library/HTMLPurifier/HTMLModule/Forms.php (66%) rewrite library/HTMLPurifier/Language/messages/en.php (95%) diff --git a/benchmarks/Lexer.php b/benchmarks/Lexer.php index 686ef63e..d612fc3c 100644 --- a/benchmarks/Lexer.php +++ b/benchmarks/Lexer.php @@ -23,15 +23,16 @@ if (version_compare(PHP_VERSION, '5', '>=')) { class RowTimer extends Benchmark_Timer { - var $name; + public $name; - function RowTimer($name, $auto = false) { + public function RowTimer($name, $auto = false) + { $this->name = htmlentities($name); $this->Benchmark_Timer($auto); } - function getOutput() { - + public function getOutput() + { $total = $this->TimeElapsed(); $result = $this->getProfiling(); $dashes = ''; @@ -68,7 +69,8 @@ class RowTimer extends Benchmark_Timer } } -function print_lexers() { +function print_lexers() +{ global $LEXERS; $first = true; foreach ($LEXERS as $key => $value) { @@ -78,7 +80,8 @@ function print_lexers() { } } -function do_benchmark($name, $document) { +function do_benchmark($name, $document) +{ global $LEXERS, $RUNS; $config = HTMLPurifier_Config::createDefault(); diff --git a/extras/ConfigDoc/HTMLXSLTProcessor.php b/extras/ConfigDoc/HTMLXSLTProcessor.php index f7095285..1cfec5d7 100644 --- a/extras/ConfigDoc/HTMLXSLTProcessor.php +++ b/extras/ConfigDoc/HTMLXSLTProcessor.php @@ -11,7 +11,8 @@ class ConfigDoc_HTMLXSLTProcessor */ protected $xsltProcessor; - public function __construct($proc = false) { + public function __construct($proc = false) + { if ($proc === false) $proc = new XSLTProcessor(); $this->xsltProcessor = $proc; } @@ -19,7 +20,8 @@ class ConfigDoc_HTMLXSLTProcessor /** * @note Allows a string $xsl filename to be passed */ - public function importStylesheet($xsl) { + public function importStylesheet($xsl) + { if (is_string($xsl)) { $xsl_file = $xsl; $xsl = new DOMDocument(); @@ -34,7 +36,8 @@ class ConfigDoc_HTMLXSLTProcessor * @return string HTML output * @todo Rename to transformToXHTML, as transformToHTML is misleading */ - public function transformToHTML($xml) { + public function transformToHTML($xml) + { if (is_string($xml)) { $dom = new DOMDocument(); $dom->load($xml); @@ -68,7 +71,8 @@ class ConfigDoc_HTMLXSLTProcessor * Bulk sets parameters for the XSL stylesheet * @param array $options Associative array of options to set */ - public function setParameters($options) { + public function setParameters($options) + { foreach ($options as $name => $value) { $this->xsltProcessor->setParameter('', $name, $value); } @@ -77,7 +81,8 @@ class ConfigDoc_HTMLXSLTProcessor /** * Forward any other calls to the XSLT processor */ - public function __call($name, $arguments) { + public function __call($name, $arguments) + { call_user_func_array(array($this->xsltProcessor, $name), $arguments); } diff --git a/extras/FSTools.php b/extras/FSTools.php index 17c35ee6..ce007631 100644 --- a/extras/FSTools.php +++ b/extras/FSTools.php @@ -15,7 +15,8 @@ class FSTools /** * Returns a global instance of FSTools */ - static public function singleton() { + public static function singleton() + { if (empty(FSTools::$singleton)) FSTools::$singleton = new FSTools(); return FSTools::$singleton; } @@ -24,7 +25,8 @@ class FSTools * Sets our global singleton to something else; useful for overloading * functions. */ - static public function setSingleton($singleton) { + public static function setSingleton($singleton) + { FSTools::$singleton = $singleton; } @@ -33,7 +35,8 @@ class FSTools * @param string $folder Name of folder to create * @note Adapted from the PHP manual comment 76612 */ - public function mkdirr($folder) { + public function mkdirr($folder) + { $folders = preg_split("#[\\\\/]#", $folder); $base = ''; for($i = 0, $c = count($folders); $i < $c; $i++) { @@ -57,7 +60,8 @@ class FSTools * so that copied files, if PHP, have includes removed * @note Adapted from http://aidanlister.com/repos/v/function.copyr.php */ - public function copyr($source, $dest) { + public function copyr($source, $dest) + { // Simple copy for a file if (is_file($source)) { return $this->copy($source, $dest); @@ -92,7 +96,8 @@ class FSTools * ignore hidden files, unreadable files, etc. This function * applies to copyr(). */ - public function copyable($file) { + public function copyable($file) + { return true; } @@ -131,7 +136,8 @@ class FSTools /** * Recursively globs a directory. */ - public function globr($dir, $pattern, $flags = NULL) { + public function globr($dir, $pattern, $flags = NULL) + { $files = $this->glob("$dir/$pattern", $flags); if ($files === false) $files = array(); $sub_dirs = $this->glob("$dir/*", GLOB_ONLYDIR); @@ -148,7 +154,8 @@ class FSTools * @warning This function will not work for functions that need * to pass references; manually define a stub function for those. */ - public function __call($name, $args) { + public function __call($name, $args) + { return call_user_func_array($name, $args); } diff --git a/extras/FSTools/File.php b/extras/FSTools/File.php index 1c76705d..6453a7a4 100644 --- a/extras/FSTools/File.php +++ b/extras/FSTools/File.php @@ -23,7 +23,8 @@ class FSTools_File * Filename of file you wish to instantiate. * @note This file need not exist */ - public function __construct($name, $fs = false) { + public function __construct($name, $fs = false) + { $this->name = $name; $this->fs = $fs ? $fs : FSTools::singleton(); } @@ -38,27 +39,32 @@ class FSTools_File * Retrieves the contents of a file * @todo Throw an exception if file doesn't exist */ - public function get() { + public function get() + { return $this->fs->file_get_contents($this->name); } /** Writes contents to a file, creates new file if necessary */ - public function write($contents) { + public function write($contents) + { return $this->fs->file_put_contents($this->name, $contents); } /** Deletes the file */ - public function delete() { + public function delete() + { return $this->fs->unlink($this->name); } /** Returns true if file exists and is a file. */ - public function exists() { + public function exists() + { return $this->fs->is_file($this->name); } /** Returns last file modification time */ - public function getMTime() { + public function getMTime() + { return $this->fs->filemtime($this->name); } @@ -67,19 +73,22 @@ class FSTools_File * @note We ignore errors because of some weird owner trickery due * to SVN duality */ - public function chmod($octal_code) { + public function chmod($octal_code) + { return @$this->fs->chmod($this->name, $octal_code); } /** Opens file's handle */ - public function open($mode) { + public function open($mode) + { if ($this->handle) $this->close(); $this->handle = $this->fs->fopen($this->name, $mode); return true; } /** Closes file's handle */ - public function close() { + public function close() + { if (!$this->handle) return false; $status = $this->fs->fclose($this->handle); $this->handle = false; @@ -87,37 +96,43 @@ class FSTools_File } /** Retrieves a line from an open file, with optional max length $length */ - public function getLine($length = null) { + public function getLine($length = null) + { if (!$this->handle) $this->open('r'); if ($length === null) return $this->fs->fgets($this->handle); else return $this->fs->fgets($this->handle, $length); } /** Retrieves a character from an open file */ - public function getChar() { + public function getChar() + { if (!$this->handle) $this->open('r'); return $this->fs->fgetc($this->handle); } /** Retrieves an $length bytes of data from an open data */ - public function read($length) { + public function read($length) + { if (!$this->handle) $this->open('r'); return $this->fs->fread($this->handle, $length); } /** Writes to an open file */ - public function put($string) { + public function put($string) + { if (!$this->handle) $this->open('a'); return $this->fs->fwrite($this->handle, $string); } /** Returns TRUE if the end of the file has been reached */ - public function eof() { + public function eof() + { if (!$this->handle) return true; return $this->fs->feof($this->handle); } - public function __destruct() { + public function __destruct() + { if ($this->handle) $this->close(); } diff --git a/extras/HTMLPurifierExtras.autoload.php b/extras/HTMLPurifierExtras.autoload.php index 4285d62d..de4a8aaa 100644 --- a/extras/HTMLPurifierExtras.autoload.php +++ b/extras/HTMLPurifierExtras.autoload.php @@ -17,7 +17,8 @@ if (function_exists('spl_autoload_register')) { spl_autoload_register('__autoload'); } } elseif (!function_exists('__autoload')) { - function __autoload($class) { + function __autoload($class) + { return HTMLPurifierExtras::autoload($class); } } diff --git a/extras/HTMLPurifierExtras.php b/extras/HTMLPurifierExtras.php index 2a0c4d12..35c2ca7e 100644 --- a/extras/HTMLPurifierExtras.php +++ b/extras/HTMLPurifierExtras.php @@ -7,14 +7,16 @@ class HTMLPurifierExtras { - public static function autoload($class) { + public static function autoload($class) + { $path = HTMLPurifierExtras::getPath($class); if (!$path) return false; require $path; return true; } - public static function getPath($class) { + public static function getPath($class) + { if ( strncmp('FSTools', $class, 7) !== 0 && strncmp('ConfigDoc', $class, 9) !== 0 diff --git a/library/HTMLPurifier.autoload.php b/library/HTMLPurifier.autoload.php index 62da5b60..c3ea67e8 100644 --- a/library/HTMLPurifier.autoload.php +++ b/library/HTMLPurifier.autoload.php @@ -14,7 +14,8 @@ if (function_exists('spl_autoload_register') && function_exists('spl_autoload_un spl_autoload_register('__autoload'); } } elseif (!function_exists('__autoload')) { - function __autoload($class) { + function __autoload($class) + { return HTMLPurifier_Bootstrap::autoload($class); } } diff --git a/library/HTMLPurifier.func.php b/library/HTMLPurifier.func.php index 56a55b2f..64b140be 100644 --- a/library/HTMLPurifier.func.php +++ b/library/HTMLPurifier.func.php @@ -8,11 +8,13 @@ /** * Purify HTML. - * @param $html String HTML to purify - * @param $config Configuration to use, can be any value accepted by + * @param string $html String HTML to purify + * @param mixed $config Configuration to use, can be any value accepted by * HTMLPurifier_Config::create() + * @return string */ -function HTMLPurifier($html, $config = null) { +function HTMLPurifier($html, $config = null) +{ static $purifier = false; if (!$purifier) { $purifier = new HTMLPurifier(); diff --git a/library/HTMLPurifier.kses.php b/library/HTMLPurifier.kses.php index 3143feb1..75229007 100644 --- a/library/HTMLPurifier.kses.php +++ b/library/HTMLPurifier.kses.php @@ -7,7 +7,8 @@ require_once dirname(__FILE__) . '/HTMLPurifier.auto.php'; -function kses($string, $allowed_html, $allowed_protocols = null) { +function kses($string, $allowed_html, $allowed_protocols = null) +{ $config = HTMLPurifier_Config::createDefault(); $allowed_elements = array(); $allowed_attributes = array(); @@ -19,7 +20,6 @@ function kses($string, $allowed_html, $allowed_protocols = null) { } $config->set('HTML.AllowedElements', $allowed_elements); $config->set('HTML.AllowedAttributes', $allowed_attributes); - $allowed_schemes = array(); if ($allowed_protocols !== null) { $config->set('URI.AllowedSchemes', $allowed_protocols); } diff --git a/library/HTMLPurifier.php b/library/HTMLPurifier.php index 02fb0902..bf8f4a61 100644 --- a/library/HTMLPurifier.php +++ b/library/HTMLPurifier.php @@ -55,36 +55,49 @@ class HTMLPurifier { /** - * @var string Version of HTML Purifier + * Version of HTML Purifier. + * @type string */ public $version = '4.5.0'; /** - * Constant with version of HTML Purifier + * Constant with version of HTML Purifier. */ const VERSION = '4.5.0'; /** - * @var HTMLPurifier_Config Global configuration object + * Global configuration object. + * @type HTMLPurifier_Config */ public $config; /** - * @var HTMLPurifier_Filter[] Array of extra filter objects to run on HTML, - * for backwards compatibility + * Array of extra filter objects to run on HTML, + * for backwards compatibility. + * @type HTMLPurifier_Filter[] */ private $filters = array(); /** - * @var HTMLPurifier Single instance of HTML Purifier + * Single instance of HTML Purifier. + * @type HTMLPurifier */ private static $instance; - protected $strategy, $generator; + /** + * @type HTMLPurifier_Strategy_Core + */ + protected $strategy; + + /** + * @type HTMLPurifier_Generator + */ + protected $generator; /** - * @var HTMLPurifier_Context Resultant context of last run purification. + * Resultant context of last run purification. * Is an array of contexts if the last called method was purifyArray(). + * @type HTMLPurifier_Context */ public $context; @@ -98,12 +111,10 @@ class HTMLPurifier * The parameter can also be any type that * HTMLPurifier_Config::create() supports. */ - public function __construct($config = null) { - + public function __construct($config = null) + { $this->config = HTMLPurifier_Config::create($config); - - $this->strategy = new HTMLPurifier_Strategy_Core(); - + $this->strategy = new HTMLPurifier_Strategy_Core(); } /** @@ -111,9 +122,10 @@ class HTMLPurifier * * @param HTMLPurifier_Filter $filter HTMLPurifier_Filter object */ - public function addFilter($filter) { + public function addFilter($filter) + { trigger_error( - 'HTMLPurifier->addFilter() is deprecated, use configuration directives'. + 'HTMLPurifier->addFilter() is deprecated, use configuration directives' . ' in the Filter namespace or Filter.Custom', E_USER_WARNING ); @@ -131,8 +143,8 @@ class HTMLPurifier * * @return string Purified HTML */ - public function purify($html, $config = null) { - + public function purify($html, $config = null) + { // :TODO: make the config merge in, instead of replace $config = $config ? HTMLPurifier_Config::create($config) : $this->config; @@ -170,8 +182,12 @@ class HTMLPurifier unset($filter_flags['Custom']); $filters = array(); foreach ($filter_flags as $filter => $flag) { - if (!$flag) continue; - if (strpos($filter, '.') !== false) continue; + if (!$flag) { + continue; + } + if (strpos($filter, '.') !== false) { + continue; + } $class = "HTMLPurifier_Filter_$filter"; $filters[] = new $class; } @@ -194,9 +210,12 @@ class HTMLPurifier // list of un-purified tokens $lexer->tokenizeHTML( // un-purified HTML - $html, $config, $context + $html, + $config, + $context ), - $config, $context + $config, + $context ) ); @@ -218,7 +237,8 @@ class HTMLPurifier * * @return string[] Array of purified HTML */ - public function purifyArray($array_of_html, $config = null) { + public function purifyArray($array_of_html, $config = null) + { $context_array = array(); foreach ($array_of_html as $key => $html) { $array_of_html[$key] = $this->purify($html, $config); @@ -238,7 +258,8 @@ class HTMLPurifier * * @return HTMLPurifier */ - public static function instance($prototype = null) { + public static function instance($prototype = null) + { if (!self::$instance || $prototype) { if ($prototype instanceof HTMLPurifier) { self::$instance = $prototype; @@ -262,10 +283,10 @@ class HTMLPurifier * @return HTMLPurifier * @note Backwards compatibility, see instance() */ - public static function getInstance($prototype = null) { + public static function getInstance($prototype = null) + { return HTMLPurifier::instance($prototype); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrCollections.php b/library/HTMLPurifier/AttrCollections.php index 555b86d0..4f6c2e39 100644 --- a/library/HTMLPurifier/AttrCollections.php +++ b/library/HTMLPurifier/AttrCollections.php @@ -8,7 +8,8 @@ class HTMLPurifier_AttrCollections { /** - * Associative array of attribute collections, indexed by name + * Associative array of attribute collections, indexed by name. + * @type array */ public $info = array(); @@ -16,10 +17,11 @@ class HTMLPurifier_AttrCollections * Performs all expansions on internal data for use by other inclusions * It also collects all attribute collection extensions from * modules - * @param $attr_types HTMLPurifier_AttrTypes instance - * @param $modules Hash array of HTMLPurifier_HTMLModule members + * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance + * @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members */ - public function __construct($attr_types, $modules) { + public function __construct($attr_types, $modules) + { // load extensions from the modules foreach ($modules as $module) { foreach ($module->attr_collections as $coll_i => $coll) { @@ -30,7 +32,9 @@ class HTMLPurifier_AttrCollections if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) { // merge in includes $this->info[$coll_i][$attr_i] = array_merge( - $this->info[$coll_i][$attr_i], $attr); + $this->info[$coll_i][$attr_i], + $attr + ); continue; } $this->info[$coll_i][$attr_i] = $attr; @@ -49,20 +53,29 @@ class HTMLPurifier_AttrCollections /** * Takes a reference to an attribute associative array and performs * all inclusions specified by the zero index. - * @param &$attr Reference to attribute array + * @param array &$attr Reference to attribute array */ - public function performInclusions(&$attr) { - if (!isset($attr[0])) return; + public function performInclusions(&$attr) + { + if (!isset($attr[0])) { + return; + } $merge = $attr[0]; $seen = array(); // recursion guard // loop through all the inclusions for ($i = 0; isset($merge[$i]); $i++) { - if (isset($seen[$merge[$i]])) continue; + if (isset($seen[$merge[$i]])) { + continue; + } $seen[$merge[$i]] = true; // foreach attribute of the inclusion, copy it over - if (!isset($this->info[$merge[$i]])) continue; + if (!isset($this->info[$merge[$i]])) { + continue; + } foreach ($this->info[$merge[$i]] as $key => $value) { - if (isset($attr[$key])) continue; // also catches more inclusions + if (isset($attr[$key])) { + continue; + } // also catches more inclusions $attr[$key] = $value; } if (isset($this->info[$merge[$i]][0])) { @@ -76,20 +89,24 @@ class HTMLPurifier_AttrCollections /** * Expands all string identifiers in an attribute array by replacing * them with the appropriate values inside HTMLPurifier_AttrTypes - * @param &$attr Reference to attribute array - * @param $attr_types HTMLPurifier_AttrTypes instance + * @param array &$attr Reference to attribute array + * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance */ - public function expandIdentifiers(&$attr, $attr_types) { - + public function expandIdentifiers(&$attr, $attr_types) + { // because foreach will process new elements we add, make sure we // skip duplicates $processed = array(); foreach ($attr as $def_i => $def) { // skip inclusions - if ($def_i === 0) continue; + if ($def_i === 0) { + continue; + } - if (isset($processed[$def_i])) continue; + if (isset($processed[$def_i])) { + continue; + } // determine whether or not attribute is required if ($required = (strpos($def_i, '*') !== false)) { @@ -120,9 +137,7 @@ class HTMLPurifier_AttrCollections unset($attr[$def_i]); } } - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef.php b/library/HTMLPurifier/AttrDef.php index b2e4f36c..5ac06522 100644 --- a/library/HTMLPurifier/AttrDef.php +++ b/library/HTMLPurifier/AttrDef.php @@ -14,23 +14,25 @@ abstract class HTMLPurifier_AttrDef { /** - * Tells us whether or not an HTML attribute is minimized. Has no - * meaning in other contexts. + * Tells us whether or not an HTML attribute is minimized. + * Has no meaning in other contexts. + * @type bool */ public $minimized = false; /** - * Tells us whether or not an HTML attribute is required. Has no - * meaning in other contexts + * Tells us whether or not an HTML attribute is required. + * Has no meaning in other contexts + * @type bool */ public $required = false; /** * Validates and cleans passed string according to a definition. * - * @param $string String to be validated and cleaned. - * @param $config Mandatory HTMLPurifier_Config object. - * @param $context Mandatory HTMLPurifier_AttrContext object. + * @param string $string String to be validated and cleaned. + * @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object. + * @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object. */ abstract public function validate($string, $config, $context); @@ -55,7 +57,8 @@ abstract class HTMLPurifier_AttrDef * parsing XML, thus, this behavior may still be correct. We * assume that newlines have been normalized. */ - public function parseCDATA($string) { + public function parseCDATA($string) + { $string = trim($string); $string = str_replace(array("\n", "\t", "\r"), ' ', $string); return $string; @@ -63,10 +66,11 @@ abstract class HTMLPurifier_AttrDef /** * Factory method for creating this class from a string. - * @param $string String construction info - * @return Created AttrDef object corresponding to $string + * @param string $string String construction info + * @return HTMLPurifier_AttrDef Created AttrDef object corresponding to $string */ - public function make($string) { + public function make($string) + { // default implementation, return a flyweight of this object. // If $string has an effect on the returned object (i.e. you // need to overload this method), it is best @@ -77,16 +81,20 @@ abstract class HTMLPurifier_AttrDef /** * Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work * properly. THIS IS A HACK! + * @param string $string a CSS colour definition + * @return string */ - protected function mungeRgb($string) { + protected function mungeRgb($string) + { return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string); } /** - * Parses a possibly escaped CSS string and returns the "pure" + * Parses a possibly escaped CSS string and returns the "pure" * version of it. */ - protected function expandCSSEscape($string) { + protected function expandCSSEscape($string) + { // flexibly parse it $ret = ''; for ($i = 0, $c = strlen($string); $i < $c; $i++) { @@ -99,25 +107,32 @@ abstract class HTMLPurifier_AttrDef if (ctype_xdigit($string[$i])) { $code = $string[$i]; for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) { - if (!ctype_xdigit($string[$i])) break; + if (!ctype_xdigit($string[$i])) { + break; + } $code .= $string[$i]; } // We have to be extremely careful when adding // new characters, to make sure we're not breaking // the encoding. $char = HTMLPurifier_Encoder::unichr(hexdec($code)); - if (HTMLPurifier_Encoder::cleanUTF8($char) === '') continue; + if (HTMLPurifier_Encoder::cleanUTF8($char) === '') { + continue; + } $ret .= $char; - if ($i < $c && trim($string[$i]) !== '') $i--; + if ($i < $c && trim($string[$i]) !== '') { + $i--; + } + continue; + } + if ($string[$i] === "\n") { continue; } - if ($string[$i] === "\n") continue; } $ret .= $string[$i]; } return $ret; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS.php b/library/HTMLPurifier/AttrDef/CSS.php index 953e7067..02c1641f 100644 --- a/library/HTMLPurifier/AttrDef/CSS.php +++ b/library/HTMLPurifier/AttrDef/CSS.php @@ -14,8 +14,14 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef { - public function validate($css, $config, $context) { - + /** + * @param string $css + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($css, $config, $context) + { $css = $this->parseCDATA($css); $definition = $config->getCSSDefinition(); @@ -36,34 +42,47 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef $context->register('CurrentCSSProperty', $property); foreach ($declarations as $declaration) { - if (!$declaration) continue; - if (!strpos($declaration, ':')) continue; + if (!$declaration) { + continue; + } + if (!strpos($declaration, ':')) { + continue; + } list($property, $value) = explode(':', $declaration, 2); $property = trim($property); - $value = trim($value); + $value = trim($value); $ok = false; do { if (isset($definition->info[$property])) { $ok = true; break; } - if (ctype_lower($property)) break; + if (ctype_lower($property)) { + break; + } $property = strtolower($property); if (isset($definition->info[$property])) { $ok = true; break; } - } while(0); - if (!$ok) continue; + } while (0); + if (!$ok) { + continue; + } // inefficient call, since the validator will do this again if (strtolower(trim($value)) !== 'inherit') { // inherit works for everything (but only on the base property) $result = $definition->info[$property]->validate( - $value, $config, $context ); + $value, + $config, + $context + ); } else { $result = 'inherit'; } - if ($result === false) continue; + if ($result === false) { + continue; + } $propvalues[$property] = $result; } diff --git a/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php b/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php index 292c040d..af2b83df 100644 --- a/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php +++ b/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php @@ -3,19 +3,32 @@ class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number { - public function __construct() { + public function __construct() + { parent::__construct(false); // opacity is non-negative, but we will clamp it } - public function validate($number, $config, $context) { + /** + * @param string $number + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function validate($number, $config, $context) + { $result = parent::validate($number, $config, $context); - if ($result === false) return $result; - $float = (float) $result; - if ($float < 0.0) $result = '0'; - if ($float > 1.0) $result = '1'; + if ($result === false) { + return $result; + } + $float = (float)$result; + if ($float < 0.0) { + $result = '0'; + } + if ($float > 1.0) { + $result = '1'; + } return $result; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Background.php b/library/HTMLPurifier/AttrDef/CSS/Background.php index e5b7438c..7f1ea3b0 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Background.php +++ b/library/HTMLPurifier/AttrDef/CSS/Background.php @@ -9,11 +9,16 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef /** * Local copy of component validators. + * @type HTMLPurifier_AttrDef[] * @note See HTMLPurifier_AttrDef_Font::$info for a similar impl. */ protected $info; - public function __construct($config) { + /** + * @param HTMLPurifier_Config $config + */ + public function __construct($config) + { $def = $config->getCSSDefinition(); $this->info['background-color'] = $def->info['background-color']; $this->info['background-image'] = $def->info['background-image']; @@ -22,11 +27,19 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef $this->info['background-position'] = $def->info['background-position']; } - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { // regular pre-processing $string = $this->parseCDATA($string); - if ($string === '') return false; + if ($string === '') { + return false; + } // munge rgb() decl if necessary $string = $this->mungeRgb($string); @@ -35,27 +48,34 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef $bits = explode(' ', $string); // bits to process $caught = array(); - $caught['color'] = false; - $caught['image'] = false; - $caught['repeat'] = false; + $caught['color'] = false; + $caught['image'] = false; + $caught['repeat'] = false; $caught['attachment'] = false; $caught['position'] = false; $i = 0; // number of catches - $none = false; foreach ($bits as $bit) { - if ($bit === '') continue; + if ($bit === '') { + continue; + } foreach ($caught as $key => $status) { if ($key != 'position') { - if ($status !== false) continue; + if ($status !== false) { + continue; + } $r = $this->info['background-' . $key]->validate($bit, $config, $context); } else { $r = $bit; } - if ($r === false) continue; + if ($r === false) { + continue; + } if ($key == 'position') { - if ($caught[$key] === false) $caught[$key] = ''; + if ($caught[$key] === false) { + $caught[$key] = ''; + } $caught[$key] .= $r . ' '; } else { $caught[$key] = $r; @@ -65,7 +85,9 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef } } - if (!$i) return false; + if (!$i) { + return false; + } if ($caught['position'] !== false) { $caught['position'] = $this->info['background-position']-> validate($caught['position'], $config, $context); @@ -73,15 +95,17 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef $ret = array(); foreach ($caught as $value) { - if ($value === false) continue; + if ($value === false) { + continue; + } $ret[] = $value; } - if (empty($ret)) return false; + if (empty($ret)) { + return false; + } return implode(' ', $ret); - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php b/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php index fae82eae..4580ef5a 100644 --- a/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php +++ b/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php @@ -44,15 +44,30 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef { + /** + * @type HTMLPurifier_AttrDef_CSS_Length + */ protected $length; + + /** + * @type HTMLPurifier_AttrDef_CSS_Percentage + */ protected $percentage; - public function __construct() { - $this->length = new HTMLPurifier_AttrDef_CSS_Length(); + public function __construct() + { + $this->length = new HTMLPurifier_AttrDef_CSS_Length(); $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage(); } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = $this->parseCDATA($string); $bits = explode(' ', $string); @@ -74,7 +89,9 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef ); foreach ($bits as $bit) { - if ($bit === '') continue; + if ($bit === '') { + continue; + } // test for keyword $lbit = ctype_lower($bit) ? $bit : strtolower($bit); @@ -104,30 +121,37 @@ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef $measures[] = $r; $i++; } - } - if (!$i) return false; // no valid values were caught + if (!$i) { + return false; + } // no valid values were caught $ret = array(); // first keyword - if ($keywords['h']) $ret[] = $keywords['h']; - elseif ($keywords['ch']) { + if ($keywords['h']) { + $ret[] = $keywords['h']; + } elseif ($keywords['ch']) { $ret[] = $keywords['ch']; $keywords['cv'] = false; // prevent re-use: center = center center + } elseif (count($measures)) { + $ret[] = array_shift($measures); } - elseif (count($measures)) $ret[] = array_shift($measures); - if ($keywords['v']) $ret[] = $keywords['v']; - elseif ($keywords['cv']) $ret[] = $keywords['cv']; - elseif (count($measures)) $ret[] = array_shift($measures); + if ($keywords['v']) { + $ret[] = $keywords['v']; + } elseif ($keywords['cv']) { + $ret[] = $keywords['cv']; + } elseif (count($measures)) { + $ret[] = array_shift($measures); + } - if (empty($ret)) return false; + if (empty($ret)) { + return false; + } return implode(' ', $ret); - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Border.php b/library/HTMLPurifier/AttrDef/CSS/Border.php index 42a1d1b4..16243ba1 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Border.php +++ b/library/HTMLPurifier/AttrDef/CSS/Border.php @@ -8,17 +8,29 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef /** * Local copy of properties this property is shorthand for. + * @type HTMLPurifier_AttrDef[] */ protected $info = array(); - public function __construct($config) { + /** + * @param HTMLPurifier_Config $config + */ + public function __construct($config) + { $def = $config->getCSSDefinition(); $this->info['border-width'] = $def->info['border-width']; $this->info['border-style'] = $def->info['border-style']; $this->info['border-top-color'] = $def->info['border-top-color']; } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = $this->parseCDATA($string); $string = $this->mungeRgb($string); $bits = explode(' ', $string); @@ -26,7 +38,9 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef $ret = ''; // return value foreach ($bits as $bit) { foreach ($this->info as $propname => $validator) { - if (isset($done[$propname])) continue; + if (isset($done[$propname])) { + continue; + } $r = $validator->validate($bit, $config, $context); if ($r !== false) { $ret .= $r . ' '; @@ -37,7 +51,6 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef } return rtrim($ret); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Color.php b/library/HTMLPurifier/AttrDef/CSS/Color.php index 07f95a67..16d2a6b9 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Color.php +++ b/library/HTMLPurifier/AttrDef/CSS/Color.php @@ -6,29 +6,47 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef { - public function validate($color, $config, $context) { - + /** + * @param string $color + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($color, $config, $context) + { static $colors = null; - if ($colors === null) $colors = $config->get('Core.ColorKeywords'); + if ($colors === null) { + $colors = $config->get('Core.ColorKeywords'); + } $color = trim($color); - if ($color === '') return false; + if ($color === '') { + return false; + } $lower = strtolower($color); - if (isset($colors[$lower])) return $colors[$lower]; + if (isset($colors[$lower])) { + return $colors[$lower]; + } if (strpos($color, 'rgb(') !== false) { // rgb literal handling $length = strlen($color); - if (strpos($color, ')') !== $length - 1) return false; + if (strpos($color, ')') !== $length - 1) { + return false; + } $triad = substr($color, 4, $length - 4 - 1); $parts = explode(',', $triad); - if (count($parts) !== 3) return false; + if (count($parts) !== 3) { + return false; + } $type = false; // to ensure that they're all the same type $new_parts = array(); foreach ($parts as $part) { $part = trim($part); - if ($part === '') return false; + if ($part === '') { + return false; + } $length = strlen($part); if ($part[$length - 1] === '%') { // handle percents @@ -37,9 +55,13 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef } elseif ($type !== 'percentage') { return false; } - $num = (float) substr($part, 0, $length - 1); - if ($num < 0) $num = 0; - if ($num > 100) $num = 100; + $num = (float)substr($part, 0, $length - 1); + if ($num < 0) { + $num = 0; + } + if ($num > 100) { + $num = 100; + } $new_parts[] = "$num%"; } else { // handle integers @@ -48,10 +70,14 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef } elseif ($type !== 'integer') { return false; } - $num = (int) $part; - if ($num < 0) $num = 0; - if ($num > 255) $num = 255; - $new_parts[] = (string) $num; + $num = (int)$part; + if ($num < 0) { + $num = 0; + } + if ($num > 255) { + $num = 255; + } + $new_parts[] = (string)$num; } } $new_triad = implode(',', $new_parts); @@ -65,14 +91,15 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef $color = '#' . $color; } $length = strlen($hex); - if ($length !== 3 && $length !== 6) return false; - if (!ctype_xdigit($hex)) return false; + if ($length !== 3 && $length !== 6) { + return false; + } + if (!ctype_xdigit($hex)) { + return false; + } } - return $color; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Composite.php b/library/HTMLPurifier/AttrDef/CSS/Composite.php index de1289cb..9c175055 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Composite.php +++ b/library/HTMLPurifier/AttrDef/CSS/Composite.php @@ -13,26 +13,36 @@ class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef { /** - * List of HTMLPurifier_AttrDef objects that may process strings + * List of objects that may process strings. + * @type HTMLPurifier_AttrDef[] * @todo Make protected */ public $defs; /** - * @param $defs List of HTMLPurifier_AttrDef objects + * @param HTMLPurifier_AttrDef[] $defs List of HTMLPurifier_AttrDef objects */ - public function __construct($defs) { + public function __construct($defs) + { $this->defs = $defs; } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { foreach ($this->defs as $i => $def) { $result = $this->defs[$i]->validate($string, $config, $context); - if ($result !== false) return $result; + if ($result !== false) { + return $result; + } } return false; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php b/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php index 6599c5b2..9d77cc9a 100644 --- a/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php +++ b/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php @@ -5,22 +5,38 @@ */ class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef { - public $def, $element; + /** + * @type HTMLPurifier_AttrDef + */ + public $def; + /** + * @type string + */ + public $element; /** - * @param $def Definition to wrap - * @param $element Element to deny + * @param HTMLPurifier_AttrDef $def Definition to wrap + * @param string $element Element to deny */ - public function __construct($def, $element) { + public function __construct($def, $element) + { $this->def = $def; $this->element = $element; } + /** * Checks if CurrentToken is set and equal to $this->element + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string */ - public function validate($string, $config, $context) { + public function validate($string, $config, $context) + { $token = $context->get('CurrentToken', true); - if ($token && $token->name == $this->element) return false; + if ($token && $token->name == $this->element) { + return false; + } return $this->def->validate($string, $config, $context); } } diff --git a/library/HTMLPurifier/AttrDef/CSS/Filter.php b/library/HTMLPurifier/AttrDef/CSS/Filter.php index 147894b8..bde4c330 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Filter.php +++ b/library/HTMLPurifier/AttrDef/CSS/Filter.php @@ -7,23 +7,37 @@ */ class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef { - + /** + * @type HTMLPurifier_AttrDef_Integer + */ protected $intValidator; - public function __construct() { + public function __construct() + { $this->intValidator = new HTMLPurifier_AttrDef_Integer(); } - public function validate($value, $config, $context) { + /** + * @param string $value + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($value, $config, $context) + { $value = $this->parseCDATA($value); - if ($value === 'none') return $value; + if ($value === 'none') { + return $value; + } // if we looped this we could support multiple filters $function_length = strcspn($value, '('); $function = trim(substr($value, 0, $function_length)); if ($function !== 'alpha' && $function !== 'Alpha' && $function !== 'progid:DXImageTransform.Microsoft.Alpha' - ) return false; + ) { + return false; + } $cursor = $function_length + 1; $parameters_length = strcspn($value, ')', $cursor); $parameters = substr($value, $cursor, $parameters_length); @@ -32,15 +46,25 @@ class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef $lookup = array(); foreach ($params as $param) { list($key, $value) = explode('=', $param); - $key = trim($key); + $key = trim($key); $value = trim($value); - if (isset($lookup[$key])) continue; - if ($key !== 'opacity') continue; + if (isset($lookup[$key])) { + continue; + } + if ($key !== 'opacity') { + continue; + } $value = $this->intValidator->validate($value, $config, $context); - if ($value === false) continue; - $int = (int) $value; - if ($int > 100) $value = '100'; - if ($int < 0) $value = '0'; + if ($value === false) { + continue; + } + $int = (int)$value; + if ($int > 100) { + $value = '100'; + } + if ($int < 0) { + $value = '0'; + } $ret_params[] = "$key=$value"; $lookup[$key] = true; } @@ -48,7 +72,6 @@ class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef $ret_function = "$function($ret_parameters)"; return $ret_function; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Font.php b/library/HTMLPurifier/AttrDef/CSS/Font.php index 699ee0b7..579b97ef 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Font.php +++ b/library/HTMLPurifier/AttrDef/CSS/Font.php @@ -7,8 +7,8 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef { /** - * Local copy of component validators. - * + * Local copy of validators + * @type HTMLPurifier_AttrDef[] * @note If we moved specific CSS property definitions to their own * classes instead of having them be assembled at run time by * CSSDefinition, this wouldn't be necessary. We'd instantiate @@ -16,18 +16,28 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef */ protected $info = array(); - public function __construct($config) { + /** + * @param HTMLPurifier_Config $config + */ + public function __construct($config) + { $def = $config->getCSSDefinition(); - $this->info['font-style'] = $def->info['font-style']; + $this->info['font-style'] = $def->info['font-style']; $this->info['font-variant'] = $def->info['font-variant']; - $this->info['font-weight'] = $def->info['font-weight']; - $this->info['font-size'] = $def->info['font-size']; - $this->info['line-height'] = $def->info['line-height']; - $this->info['font-family'] = $def->info['font-family']; + $this->info['font-weight'] = $def->info['font-weight']; + $this->info['font-size'] = $def->info['font-size']; + $this->info['line-height'] = $def->info['line-height']; + $this->info['font-family'] = $def->info['font-family']; } - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { static $system_fonts = array( 'caption' => true, 'icon' => true, @@ -39,7 +49,9 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef // regular pre-processing $string = $this->parseCDATA($string); - if ($string === '') return false; + if ($string === '') { + return false; + } // check if it's one of the keywords $lowercase_string = strtolower($string); @@ -54,15 +66,20 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef $final = ''; // output for ($i = 0, $size = count($bits); $i < $size; $i++) { - if ($bits[$i] === '') continue; + if ($bits[$i] === '') { + continue; + } switch ($stage) { - - // attempting to catch font-style, font-variant or font-weight - case 0: + case 0: // attempting to catch font-style, font-variant or font-weight foreach ($stage_1 as $validator_name) { - if (isset($caught[$validator_name])) continue; + if (isset($caught[$validator_name])) { + continue; + } $r = $this->info[$validator_name]->validate( - $bits[$i], $config, $context); + $bits[$i], + $config, + $context + ); if ($r !== false) { $final .= $r . ' '; $caught[$validator_name] = true; @@ -70,15 +87,17 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef } } // all three caught, continue on - if (count($caught) >= 3) $stage = 1; - if ($r !== false) break; - - // attempting to catch font-size and perhaps line-height - case 1: + if (count($caught) >= 3) { + $stage = 1; + } + if ($r !== false) { + break; + } + case 1: // attempting to catch font-size and perhaps line-height $found_slash = false; if (strpos($bits[$i], '/') !== false) { list($font_size, $line_height) = - explode('/', $bits[$i]); + explode('/', $bits[$i]); if ($line_height === '') { // ooh, there's a space after the slash! $line_height = false; @@ -89,14 +108,19 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef $line_height = false; } $r = $this->info['font-size']->validate( - $font_size, $config, $context); + $font_size, + $config, + $context + ); if ($r !== false) { $final .= $r; // attempt to catch line-height if ($line_height === false) { // we need to scroll forward for ($j = $i + 1; $j < $size; $j++) { - if ($bits[$j] === '') continue; + if ($bits[$j] === '') { + continue; + } if ($bits[$j] === '/') { if ($found_slash) { return false; @@ -116,7 +140,10 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef if ($found_slash) { $i = $j; $r = $this->info['line-height']->validate( - $line_height, $config, $context); + $line_height, + $config, + $context + ); if ($r !== false) { $final .= '/' . $r; } @@ -126,13 +153,14 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef break; } return false; - - // attempting to catch font-family - case 2: + case 2: // attempting to catch font-family $font_family = implode(' ', array_slice($bits, $i, $size - $i)); $r = $this->info['font-family']->validate( - $font_family, $config, $context); + $font_family, + $config, + $context + ); if ($r !== false) { $final .= $r . ' '; // processing completed successfully @@ -143,7 +171,6 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef } return false; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/FontFamily.php b/library/HTMLPurifier/AttrDef/CSS/FontFamily.php index 98dcf820..74e24c88 100644 --- a/library/HTMLPurifier/AttrDef/CSS/FontFamily.php +++ b/library/HTMLPurifier/AttrDef/CSS/FontFamily.php @@ -8,11 +8,18 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef protected $mask = null; - public function __construct() { + public function __construct() + { $this->mask = '_- '; - for ($c = 'a'; $c <= 'z'; $c++) $this->mask .= $c; - for ($c = 'A'; $c <= 'Z'; $c++) $this->mask .= $c; - for ($c = '0'; $c <= '9'; $c++) $this->mask .= $c; // cast-y, but should be fine + for ($c = 'a'; $c <= 'z'; $c++) { + $this->mask .= $c; + } + for ($c = 'A'; $c <= 'Z'; $c++) { + $this->mask .= $c; + } + for ($c = '0'; $c <= '9'; $c++) { + $this->mask .= $c; + } // cast-y, but should be fine // special bytes used by UTF-8 for ($i = 0x80; $i <= 0xFF; $i++) { // We don't bother excluding invalid bytes in this range, @@ -39,7 +46,14 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef // possible optimization: invert the mask. } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { static $generic_names = array( 'serif' => true, 'sans-serif' => true, @@ -52,9 +66,11 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef // assume that no font names contain commas in them $fonts = explode(',', $string); $final = ''; - foreach($fonts as $font) { + foreach ($fonts as $font) { $font = trim($font); - if ($font === '') continue; + if ($font === '') { + continue; + } // match a generic name if (isset($generic_names[$font])) { if ($allowed_fonts === null || isset($allowed_fonts[$font])) { @@ -65,9 +81,13 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef // match a quoted name if ($font[0] === '"' || $font[0] === "'") { $length = strlen($font); - if ($length <= 2) continue; + if ($length <= 2) { + continue; + } $quote = $font[0]; - if ($font[$length - 1] !== $quote) continue; + if ($font[$length - 1] !== $quote) { + continue; + } $font = substr($font, 1, $length - 2); } @@ -188,7 +208,9 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef $final .= "'$font', "; } $final = rtrim($final, ', '); - if ($final === '') return false; + if ($final === '') { + return false; + } return $final; } diff --git a/library/HTMLPurifier/AttrDef/CSS/Ident.php b/library/HTMLPurifier/AttrDef/CSS/Ident.php index 779794a0..973002c1 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Ident.php +++ b/library/HTMLPurifier/AttrDef/CSS/Ident.php @@ -6,19 +6,27 @@ class HTMLPurifier_AttrDef_CSS_Ident extends HTMLPurifier_AttrDef { - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = trim($string); // early abort: '' and '0' (strings that convert to false) are invalid - if (!$string) return false; + if (!$string) { + return false; + } $pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/'; - if (!preg_match($pattern, $string)) return false; + if (!preg_match($pattern, $string)) { + return false; + } return $string; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php b/library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php index 4e6b35e5..ffc989fe 100644 --- a/library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php +++ b/library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php @@ -5,20 +5,34 @@ */ class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef { - public $def, $allow; + /** + * @type HTMLPurifier_AttrDef + */ + public $def; + /** + * @type bool + */ + public $allow; /** - * @param $def Definition to wrap - * @param $allow Whether or not to allow !important + * @param HTMLPurifier_AttrDef $def Definition to wrap + * @param bool $allow Whether or not to allow !important */ - public function __construct($def, $allow = false) { + public function __construct($def, $allow = false) + { $this->def = $def; $this->allow = $allow; } + /** * Intercepts and removes !important if necessary + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string */ - public function validate($string, $config, $context) { + public function validate($string, $config, $context) + { // test for ! and important tokens $string = trim($string); $is_important = false; @@ -32,7 +46,9 @@ class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef } } $string = $this->def->validate($string, $config, $context); - if ($this->allow && $is_important) $string .= ' !important'; + if ($this->allow && $is_important) { + $string .= ' !important'; + } return $string; } } diff --git a/library/HTMLPurifier/AttrDef/CSS/Length.php b/library/HTMLPurifier/AttrDef/CSS/Length.php index a07ec581..f12453a0 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Length.php +++ b/library/HTMLPurifier/AttrDef/CSS/Length.php @@ -6,42 +6,72 @@ class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef { - protected $min, $max; + /** + * @type HTMLPurifier_Length|string + */ + protected $min; /** - * @param HTMLPurifier_Length $max Minimum length, or null for no bound. String is also acceptable. - * @param HTMLPurifier_Length $max Maximum length, or null for no bound. String is also acceptable. + * @type HTMLPurifier_Length|string */ - public function __construct($min = null, $max = null) { + protected $max; + + /** + * @param HTMLPurifier_Length|string $min Minimum length, or null for no bound. String is also acceptable. + * @param HTMLPurifier_Length|string $max Maximum length, or null for no bound. String is also acceptable. + */ + public function __construct($min = null, $max = null) + { $this->min = $min !== null ? HTMLPurifier_Length::make($min) : null; $this->max = $max !== null ? HTMLPurifier_Length::make($max) : null; } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = $this->parseCDATA($string); // Optimizations - if ($string === '') return false; - if ($string === '0') return '0'; - if (strlen($string) === 1) return false; + if ($string === '') { + return false; + } + if ($string === '0') { + return '0'; + } + if (strlen($string) === 1) { + return false; + } $length = HTMLPurifier_Length::make($string); - if (!$length->isValid()) return false; + if (!$length->isValid()) { + return false; + } if ($this->min) { $c = $length->compareTo($this->min); - if ($c === false) return false; - if ($c < 0) return false; + if ($c === false) { + return false; + } + if ($c < 0) { + return false; + } } if ($this->max) { $c = $length->compareTo($this->max); - if ($c === false) return false; - if ($c > 0) return false; + if ($c === false) { + return false; + } + if ($c > 0) { + return false; + } } - return $length->toString(); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/ListStyle.php b/library/HTMLPurifier/AttrDef/CSS/ListStyle.php index 4406868c..e74d4265 100644 --- a/library/HTMLPurifier/AttrDef/CSS/ListStyle.php +++ b/library/HTMLPurifier/AttrDef/CSS/ListStyle.php @@ -8,46 +8,72 @@ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef { /** - * Local copy of component validators. + * Local copy of validators. + * @type HTMLPurifier_AttrDef[] * @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl. */ protected $info; - public function __construct($config) { + /** + * @param HTMLPurifier_Config $config + */ + public function __construct($config) + { $def = $config->getCSSDefinition(); - $this->info['list-style-type'] = $def->info['list-style-type']; + $this->info['list-style-type'] = $def->info['list-style-type']; $this->info['list-style-position'] = $def->info['list-style-position']; $this->info['list-style-image'] = $def->info['list-style-image']; } - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { // regular pre-processing $string = $this->parseCDATA($string); - if ($string === '') return false; + if ($string === '') { + return false; + } // assumes URI doesn't have spaces in it $bits = explode(' ', strtolower($string)); // bits to process $caught = array(); - $caught['type'] = false; + $caught['type'] = false; $caught['position'] = false; - $caught['image'] = false; + $caught['image'] = false; $i = 0; // number of catches $none = false; foreach ($bits as $bit) { - if ($i >= 3) return; // optimization bit - if ($bit === '') continue; + if ($i >= 3) { + return; + } // optimization bit + if ($bit === '') { + continue; + } foreach ($caught as $key => $status) { - if ($status !== false) continue; + if ($status !== false) { + continue; + } $r = $this->info['list-style-' . $key]->validate($bit, $config, $context); - if ($r === false) continue; + if ($r === false) { + continue; + } if ($r === 'none') { - if ($none) continue; - else $none = true; - if ($key == 'image') continue; + if ($none) { + continue; + } else { + $none = true; + } + if ($key == 'image') { + continue; + } } $caught[$key] = $r; $i++; @@ -55,24 +81,32 @@ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef } } - if (!$i) return false; + if (!$i) { + return false; + } $ret = array(); // construct type - if ($caught['type']) $ret[] = $caught['type']; + if ($caught['type']) { + $ret[] = $caught['type']; + } // construct image - if ($caught['image']) $ret[] = $caught['image']; + if ($caught['image']) { + $ret[] = $caught['image']; + } // construct position - if ($caught['position']) $ret[] = $caught['position']; + if ($caught['position']) { + $ret[] = $caught['position']; + } - if (empty($ret)) return false; + if (empty($ret)) { + return false; + } return implode(' ', $ret); - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Multiple.php b/library/HTMLPurifier/AttrDef/CSS/Multiple.php index 4d62a40d..9f266cdd 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Multiple.php +++ b/library/HTMLPurifier/AttrDef/CSS/Multiple.php @@ -13,9 +13,9 @@ */ class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef { - /** * Instance of component definition to defer validation to. + * @type HTMLPurifier_AttrDef * @todo Make protected */ public $single; @@ -27,32 +27,45 @@ class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef public $max; /** - * @param $single HTMLPurifier_AttrDef to multiply - * @param $max Max number of values allowed (usually four) + * @param HTMLPurifier_AttrDef $single HTMLPurifier_AttrDef to multiply + * @param int $max Max number of values allowed (usually four) */ - public function __construct($single, $max = 4) { + public function __construct($single, $max = 4) + { $this->single = $single; $this->max = $max; } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = $this->parseCDATA($string); - if ($string === '') return false; + if ($string === '') { + return false; + } $parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n $length = count($parts); $final = ''; for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) { - if (ctype_space($parts[$i])) continue; + if (ctype_space($parts[$i])) { + continue; + } $result = $this->single->validate($parts[$i], $config, $context); if ($result !== false) { $final .= $result . ' '; $num++; } } - if ($final === '') return false; + if ($final === '') { + return false; + } return rtrim($final); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Number.php b/library/HTMLPurifier/AttrDef/CSS/Number.php index 3f99e12e..8edc159e 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Number.php +++ b/library/HTMLPurifier/AttrDef/CSS/Number.php @@ -7,32 +7,44 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef { /** - * Bool indicating whether or not only positive values allowed. + * Indicates whether or not only positive values are allowed. + * @type bool */ protected $non_negative = false; /** - * @param $non_negative Bool indicating whether negatives are forbidden + * @param bool $non_negative indicates whether negatives are forbidden */ - public function __construct($non_negative = false) { + public function __construct($non_negative = false) + { $this->non_negative = $non_negative; } /** + * @param string $number + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string|bool * @warning Some contexts do not pass $config, $context. These * variables should not be used without checking HTMLPurifier_Length */ - public function validate($number, $config, $context) { - + public function validate($number, $config, $context) + { $number = $this->parseCDATA($number); - if ($number === '') return false; - if ($number === '0') return '0'; + if ($number === '') { + return false; + } + if ($number === '0') { + return '0'; + } $sign = ''; switch ($number[0]) { case '-': - if ($this->non_negative) return false; + if ($this->non_negative) { + return false; + } $sign = '-'; case '+': $number = substr($number, 1); @@ -44,14 +56,20 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef } // Period is the only non-numeric character allowed - if (strpos($number, '.') === false) return false; + if (strpos($number, '.') === false) { + return false; + } list($left, $right) = explode('.', $number, 2); - if ($left === '' && $right === '') return false; - if ($left !== '' && !ctype_digit($left)) return false; + if ($left === '' && $right === '') { + return false; + } + if ($left !== '' && !ctype_digit($left)) { + return false; + } - $left = ltrim($left, '0'); + $left = ltrim($left, '0'); $right = rtrim($right, '0'); if ($right === '') { @@ -59,11 +77,8 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef } elseif (!ctype_digit($right)) { return false; } - return $sign . $left . '.' . $right; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/Percentage.php b/library/HTMLPurifier/AttrDef/CSS/Percentage.php index c34b8fc3..f0f25c50 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Percentage.php +++ b/library/HTMLPurifier/AttrDef/CSS/Percentage.php @@ -7,34 +7,48 @@ class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef { /** - * Instance of HTMLPurifier_AttrDef_CSS_Number to defer number validation + * Instance to defer number validation to. + * @type HTMLPurifier_AttrDef_CSS_Number */ protected $number_def; /** - * @param Bool indicating whether to forbid negative values + * @param bool $non_negative Whether to forbid negative values */ - public function __construct($non_negative = false) { + public function __construct($non_negative = false) + { $this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative); } - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = $this->parseCDATA($string); - if ($string === '') return false; + if ($string === '') { + return false; + } $length = strlen($string); - if ($length === 1) return false; - if ($string[$length - 1] !== '%') return false; + if ($length === 1) { + return false; + } + if ($string[$length - 1] !== '%') { + return false; + } $number = substr($string, 0, $length - 1); $number = $this->number_def->validate($number, $config, $context); - if ($number === false) return false; + if ($number === false) { + return false; + } return "$number%"; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/TextDecoration.php b/library/HTMLPurifier/AttrDef/CSS/TextDecoration.php index 772c922d..5fd4b7f7 100644 --- a/library/HTMLPurifier/AttrDef/CSS/TextDecoration.php +++ b/library/HTMLPurifier/AttrDef/CSS/TextDecoration.php @@ -8,8 +8,14 @@ class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef { - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { static $allowed_values = array( 'line-through' => true, 'overline' => true, @@ -18,7 +24,9 @@ class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef $string = strtolower($this->parseCDATA($string)); - if ($string === 'none') return $string; + if ($string === 'none') { + return $string; + } $parts = explode(' ', $string); $final = ''; @@ -28,11 +36,11 @@ class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef } } $final = rtrim($final); - if ($final === '') return false; + if ($final === '') { + return false; + } return $final; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/CSS/URI.php b/library/HTMLPurifier/AttrDef/CSS/URI.php index c2f767e5..f9434230 100644 --- a/library/HTMLPurifier/AttrDef/CSS/URI.php +++ b/library/HTMLPurifier/AttrDef/CSS/URI.php @@ -12,25 +12,39 @@ class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI { - public function __construct() { + public function __construct() + { parent::__construct(true); // always embedded } - public function validate($uri_string, $config, $context) { + /** + * @param string $uri_string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($uri_string, $config, $context) + { // parse the URI out of the string and then pass it onto // the parent object $uri_string = $this->parseCDATA($uri_string); - if (strpos($uri_string, 'url(') !== 0) return false; + if (strpos($uri_string, 'url(') !== 0) { + return false; + } $uri_string = substr($uri_string, 4); $new_length = strlen($uri_string) - 1; - if ($uri_string[$new_length] != ')') return false; + if ($uri_string[$new_length] != ')') { + return false; + } $uri = trim(substr($uri_string, 0, $new_length)); if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) { $quote = $uri[0]; $new_length = strlen($uri) - 1; - if ($uri[$new_length] !== $quote) return false; + if ($uri[$new_length] !== $quote) { + return false; + } $uri = substr($uri, 1, $new_length - 1); } @@ -38,7 +52,9 @@ class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI $result = parent::validate($uri, $config, $context); - if ($result === false) return false; + if ($result === false) { + return false; + } // extra sanity check; should have been done by URI $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result); @@ -51,11 +67,8 @@ class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI // an innerHTML cycle, so a very unlucky query parameter could // then change the meaning of the URL. Unfortunately, there's // not much we can do about that... - return "url(\"$result\")"; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/Clone.php b/library/HTMLPurifier/AttrDef/Clone.php index ce68dbd5..6698a00c 100644 --- a/library/HTMLPurifier/AttrDef/Clone.php +++ b/library/HTMLPurifier/AttrDef/Clone.php @@ -7,22 +7,38 @@ class HTMLPurifier_AttrDef_Clone extends HTMLPurifier_AttrDef { /** - * What we're cloning + * What we're cloning. + * @type HTMLPurifier_AttrDef */ protected $clone; - public function __construct($clone) { + /** + * @param HTMLPurifier_AttrDef $clone + */ + public function __construct($clone) + { $this->clone = $clone; } - public function validate($v, $config, $context) { + /** + * @param string $v + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($v, $config, $context) + { return $this->clone->validate($v, $config, $context); } - public function make($string) { + /** + * @param string $string + * @return HTMLPurifier_AttrDef + */ + public function make($string) + { return clone $this->clone; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/Enum.php b/library/HTMLPurifier/AttrDef/Enum.php index 5d603ebc..8abda7f6 100644 --- a/library/HTMLPurifier/AttrDef/Enum.php +++ b/library/HTMLPurifier/AttrDef/Enum.php @@ -12,9 +12,10 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef /** * Lookup table of valid values. + * @type array * @todo Make protected */ - public $valid_values = array(); + public $valid_values = array(); /** * Bool indicating whether or not enumeration is case sensitive. @@ -23,17 +24,23 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef protected $case_sensitive = false; // values according to W3C spec /** - * @param $valid_values List of valid values - * @param $case_sensitive Bool indicating whether or not case sensitive + * @param array $valid_values List of valid values + * @param bool $case_sensitive Whether or not case sensitive */ - public function __construct( - $valid_values = array(), $case_sensitive = false - ) { + public function __construct($valid_values = array(), $case_sensitive = false) + { $this->valid_values = array_flip($valid_values); $this->case_sensitive = $case_sensitive; } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = trim($string); if (!$this->case_sensitive) { // we may want to do full case-insensitive libraries @@ -45,11 +52,13 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef } /** - * @param $string In form of comma-delimited list of case-insensitive + * @param string $string In form of comma-delimited list of case-insensitive * valid values. Example: "foo,bar,baz". Prepend "s:" to make * case sensitive + * @return HTMLPurifier_AttrDef_Enum */ - public function make($string) { + public function make($string) + { if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') { $string = substr($string, 2); $sensitive = true; @@ -59,7 +68,6 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef $values = explode(',', $string); return new HTMLPurifier_AttrDef_Enum($values, $sensitive); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/Bool.php b/library/HTMLPurifier/AttrDef/HTML/Bool.php index e06987eb..036a240e 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Bool.php +++ b/library/HTMLPurifier/AttrDef/HTML/Bool.php @@ -6,23 +6,46 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef { + /** + * @type bool + */ protected $name; + + /** + * @type bool + */ public $minimized = true; - public function __construct($name = false) {$this->name = $name;} + /** + * @param bool $name + */ + public function __construct($name = false) + { + $this->name = $name; + } - public function validate($string, $config, $context) { - if (empty($string)) return false; + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + if (empty($string)) { + return false; + } return $this->name; } /** - * @param $string Name of attribute + * @param string $string Name of attribute + * @return HTMLPurifier_AttrDef_HTML_Bool */ - public function make($string) { + public function make($string) + { return new HTMLPurifier_AttrDef_HTML_Bool($string); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/Class.php b/library/HTMLPurifier/AttrDef/HTML/Class.php index 370068d9..d5013488 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Class.php +++ b/library/HTMLPurifier/AttrDef/HTML/Class.php @@ -5,7 +5,14 @@ */ class HTMLPurifier_AttrDef_HTML_Class extends HTMLPurifier_AttrDef_HTML_Nmtokens { - protected function split($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + protected function split($string, $config, $context) + { // really, this twiddle should be lazy loaded $name = $config->getDefinition('HTML')->doctype->name; if ($name == "XHTML 1.1" || $name == "XHTML 2.0") { @@ -14,13 +21,20 @@ class HTMLPurifier_AttrDef_HTML_Class extends HTMLPurifier_AttrDef_HTML_Nmtokens return preg_split('/\s+/', $string); } } - protected function filter($tokens, $config, $context) { + + /** + * @param array $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + protected function filter($tokens, $config, $context) + { $allowed = $config->get('Attr.AllowedClasses'); $forbidden = $config->get('Attr.ForbiddenClasses'); $ret = array(); foreach ($tokens as $token) { - if ( - ($allowed === null || isset($allowed[$token])) && + if (($allowed === null || isset($allowed[$token])) && !isset($forbidden[$token]) && // We need this O(n) check because of PHP's array // implementation that casts -0 to 0. diff --git a/library/HTMLPurifier/AttrDef/HTML/Color.php b/library/HTMLPurifier/AttrDef/HTML/Color.php dissimilarity index 61% index e02abb07..946ebb78 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Color.php +++ b/library/HTMLPurifier/AttrDef/HTML/Color.php @@ -1,33 +1,51 @@ -get('Core.ColorKeywords'); - - $string = trim($string); - - if (empty($string)) return false; - $lower = strtolower($string); - if (isset($colors[$lower])) return $colors[$lower]; - if ($string[0] === '#') $hex = substr($string, 1); - else $hex = $string; - - $length = strlen($hex); - if ($length !== 3 && $length !== 6) return false; - if (!ctype_xdigit($hex)) return false; - if ($length === 3) $hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2]; - - return "#$hex"; - - } - -} - -// vim: et sw=4 sts=4 +get('Core.ColorKeywords'); + } + + $string = trim($string); + + if (empty($string)) { + return false; + } + $lower = strtolower($string); + if (isset($colors[$lower])) { + return $colors[$lower]; + } + if ($string[0] === '#') { + $hex = substr($string, 1); + } else { + $hex = $string; + } + + $length = strlen($hex); + if ($length !== 3 && $length !== 6) { + return false; + } + if (!ctype_xdigit($hex)) { + return false; + } + if ($length === 3) { + $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; + } + return "#$hex"; + } +} + +// vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php b/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php index ae6ea7c0..d79ba12b 100644 --- a/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php +++ b/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php @@ -6,16 +6,33 @@ class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum { + /** + * @type array + */ public $valid_values = false; // uninitialized value + + /** + * @type bool + */ protected $case_sensitive = false; - public function __construct() {} + public function __construct() + { + } - public function validate($string, $config, $context) { - if ($this->valid_values === false) $this->valid_values = $config->get('Attr.AllowedFrameTargets'); + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + if ($this->valid_values === false) { + $this->valid_values = $config->get('Attr.AllowedFrameTargets'); + } return parent::validate($string, $config, $context); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/ID.php b/library/HTMLPurifier/AttrDef/HTML/ID.php index 0015fa1e..3d86efb4 100644 --- a/library/HTMLPurifier/AttrDef/HTML/ID.php +++ b/library/HTMLPurifier/AttrDef/HTML/ID.php @@ -18,34 +18,56 @@ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef /** * Determines whether or not we're validating an ID in a CSS * selector context. + * @type bool */ protected $selector; - public function __construct($selector = false) { + /** + * @param bool $selector + */ + public function __construct($selector = false) + { $this->selector = $selector; } - public function validate($id, $config, $context) { - - if (!$this->selector && !$config->get('Attr.EnableID')) return false; + /** + * @param string $id + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($id, $config, $context) + { + if (!$this->selector && !$config->get('Attr.EnableID')) { + return false; + } $id = trim($id); // trim it first - if ($id === '') return false; + if ($id === '') { + return false; + } $prefix = $config->get('Attr.IDPrefix'); if ($prefix !== '') { $prefix .= $config->get('Attr.IDPrefixLocal'); // prevent re-appending the prefix - if (strpos($id, $prefix) !== 0) $id = $prefix . $id; + if (strpos($id, $prefix) !== 0) { + $id = $prefix . $id; + } } elseif ($config->get('Attr.IDPrefixLocal') !== '') { - trigger_error('%Attr.IDPrefixLocal cannot be used unless '. - '%Attr.IDPrefix is set', E_USER_WARNING); + trigger_error( + '%Attr.IDPrefixLocal cannot be used unless ' . + '%Attr.IDPrefix is set', + E_USER_WARNING + ); } if (!$this->selector) { $id_accumulator =& $context->get('IDAccumulator'); - if (isset($id_accumulator->ids[$id])) return false; + if (isset($id_accumulator->ids[$id])) { + return false; + } } // we purposely avoid using regex, hopefully this is faster @@ -53,11 +75,14 @@ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef if (ctype_alpha($id)) { $result = true; } else { - if (!ctype_alpha(@$id[0])) return false; - $trim = trim( // primitive style of regexps, I suppose + if (!ctype_alpha(@$id[0])) { + return false; + } + // primitive style of regexps, I suppose + $trim = trim( $id, 'A..Za..z0..9:-._' - ); + ); $result = ($trim === ''); } @@ -66,15 +91,15 @@ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef return false; } - if (!$this->selector && $result) $id_accumulator->add($id); + if (!$this->selector && $result) { + $id_accumulator->add($id); + } // if no change was made to the ID, return the result // else, return the new id if stripping whitespace made it // valid, or return false. return $result ? $id : false; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/Length.php b/library/HTMLPurifier/AttrDef/HTML/Length.php index a242f9c2..1c4006fb 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Length.php +++ b/library/HTMLPurifier/AttrDef/HTML/Length.php @@ -10,32 +10,47 @@ class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels { - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = trim($string); - if ($string === '') return false; + if ($string === '') { + return false; + } $parent_result = parent::validate($string, $config, $context); - if ($parent_result !== false) return $parent_result; + if ($parent_result !== false) { + return $parent_result; + } $length = strlen($string); $last_char = $string[$length - 1]; - if ($last_char !== '%') return false; + if ($last_char !== '%') { + return false; + } $points = substr($string, 0, $length - 1); - if (!is_numeric($points)) return false; - - $points = (int) $points; + if (!is_numeric($points)) { + return false; + } - if ($points < 0) return '0%'; - if ($points > 100) return '100%'; - - return ((string) $points) . '%'; + $points = (int)$points; + if ($points < 0) { + return '0%'; + } + if ($points > 100) { + return '100%'; + } + return ((string)$points) . '%'; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php b/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php index 76d25ed0..63fa04c1 100644 --- a/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php +++ b/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php @@ -9,26 +9,44 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef { - /** Name config attribute to pull. */ + /** + * Name config attribute to pull. + * @type string + */ protected $name; - public function __construct($name) { + /** + * @param string $name + */ + public function __construct($name) + { $configLookup = array( 'rel' => 'AllowedRel', 'rev' => 'AllowedRev' ); if (!isset($configLookup[$name])) { - trigger_error('Unrecognized attribute name for link '. - 'relationship.', E_USER_ERROR); + trigger_error( + 'Unrecognized attribute name for link ' . + 'relationship.', + E_USER_ERROR + ); return; } $this->name = $configLookup[$name]; } - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $allowed = $config->get('Attr.' . $this->name); - if (empty($allowed)) return false; + if (empty($allowed)) { + return false; + } $string = $this->parseCDATA($string); $parts = explode(' ', $string); @@ -37,17 +55,18 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef $ret_lookup = array(); foreach ($parts as $part) { $part = strtolower(trim($part)); - if (!isset($allowed[$part])) continue; + if (!isset($allowed[$part])) { + continue; + } $ret_lookup[$part] = true; } - if (empty($ret_lookup)) return false; + if (empty($ret_lookup)) { + return false; + } $string = implode(' ', array_keys($ret_lookup)); - return $string; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/MultiLength.php b/library/HTMLPurifier/AttrDef/HTML/MultiLength.php index c72fc76e..bbb20f2f 100644 --- a/library/HTMLPurifier/AttrDef/HTML/MultiLength.php +++ b/library/HTMLPurifier/AttrDef/HTML/MultiLength.php @@ -9,33 +9,52 @@ class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length { - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = trim($string); - if ($string === '') return false; + if ($string === '') { + return false; + } $parent_result = parent::validate($string, $config, $context); - if ($parent_result !== false) return $parent_result; + if ($parent_result !== false) { + return $parent_result; + } $length = strlen($string); $last_char = $string[$length - 1]; - if ($last_char !== '*') return false; + if ($last_char !== '*') { + return false; + } $int = substr($string, 0, $length - 1); - if ($int == '') return '*'; - if (!is_numeric($int)) return false; - - $int = (int) $int; - - if ($int < 0) return false; - if ($int == 0) return '0'; - if ($int == 1) return '*'; - return ((string) $int) . '*'; - + if ($int == '') { + return '*'; + } + if (!is_numeric($int)) { + return false; + } + + $int = (int)$int; + if ($int < 0) { + return false; + } + if ($int == 0) { + return '0'; + } + if ($int == 1) { + return '*'; + } + return ((string)$int) . '*'; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php b/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php index aa34120b..f79683b4 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php +++ b/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php @@ -6,24 +6,38 @@ class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef { - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = trim($string); // early abort: '' and '0' (strings that convert to false) are invalid - if (!$string) return false; + if (!$string) { + return false; + } $tokens = $this->split($string, $config, $context); $tokens = $this->filter($tokens, $config, $context); - if (empty($tokens)) return false; + if (empty($tokens)) { + return false; + } return implode(' ', $tokens); - } /** * Splits a space separated list of tokens into its constituent parts. + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array */ - protected function split($string, $config, $context) { + protected function split($string, $config, $context) + { // OPTIMIZABLE! // do the preg_match, capture all subpatterns for reformulation @@ -31,9 +45,9 @@ class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef // escaping because I don't know how to do that with regexps // and plus it would complicate optimization efforts (you never // see that anyway). - $pattern = '/(?:(?<=\s)|\A)'. // look behind for space or string start - '((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)'. - '(?:(?=\s)|\z)/'; // look ahead for space or string end + $pattern = '/(?:(?<=\s)|\A)' . // look behind for space or string start + '((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)' . + '(?:(?=\s)|\z)/'; // look ahead for space or string end preg_match_all($pattern, $string, $matches); return $matches[1]; } @@ -42,11 +56,15 @@ class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef * Template method for removing certain tokens based on arbitrary criteria. * @note If we wanted to be really functional, we'd do an array_filter * with a callback. But... we're not. + * @param array $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array */ - protected function filter($tokens, $config, $context) { + protected function filter($tokens, $config, $context) + { return $tokens; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/HTML/Pixels.php b/library/HTMLPurifier/AttrDef/HTML/Pixels.php index 4cb2c1b8..a1d019e0 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Pixels.php +++ b/library/HTMLPurifier/AttrDef/HTML/Pixels.php @@ -6,43 +6,71 @@ class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef { + /** + * @type int + */ protected $max; - public function __construct($max = null) { + /** + * @param int $max + */ + public function __construct($max = null) + { $this->max = $max; } - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = trim($string); - if ($string === '0') return $string; - if ($string === '') return false; + if ($string === '0') { + return $string; + } + if ($string === '') { + return false; + } $length = strlen($string); if (substr($string, $length - 2) == 'px') { $string = substr($string, 0, $length - 2); } - if (!is_numeric($string)) return false; - $int = (int) $string; + if (!is_numeric($string)) { + return false; + } + $int = (int)$string; - if ($int < 0) return '0'; + if ($int < 0) { + return '0'; + } // upper-bound value, extremely high values can // crash operating systems, see // WARNING, above link WILL crash you if you're using Windows - if ($this->max !== null && $int > $this->max) return (string) $this->max; - - return (string) $int; - + if ($this->max !== null && $int > $this->max) { + return (string)$this->max; + } + return (string)$int; } - public function make($string) { - if ($string === '') $max = null; - else $max = (int) $string; + /** + * @param string $string + * @return HTMLPurifier_AttrDef + */ + public function make($string) + { + if ($string === '') { + $max = null; + } else { + $max = (int)$string; + } $class = get_class($this); return new $class($max); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/Integer.php b/library/HTMLPurifier/AttrDef/Integer.php index d59738d2..400e707d 100644 --- a/library/HTMLPurifier/AttrDef/Integer.php +++ b/library/HTMLPurifier/AttrDef/Integer.php @@ -11,17 +11,20 @@ class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef { /** - * Bool indicating whether or not negative values are allowed + * Whether or not negative values are allowed. + * @type bool */ protected $negative = true; /** - * Bool indicating whether or not zero is allowed + * Whether or not zero is allowed. + * @type bool */ protected $zero = true; /** - * Bool indicating whether or not positive values are allowed + * Whether or not positive values are allowed. + * @type bool */ protected $positive = true; @@ -30,44 +33,59 @@ class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef * @param $zero Bool indicating whether or not zero is allowed * @param $positive Bool indicating whether or not positive values are allowed */ - public function __construct( - $negative = true, $zero = true, $positive = true - ) { + public function __construct($negative = true, $zero = true, $positive = true) + { $this->negative = $negative; - $this->zero = $zero; + $this->zero = $zero; $this->positive = $positive; } - public function validate($integer, $config, $context) { - + /** + * @param string $integer + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($integer, $config, $context) + { $integer = $this->parseCDATA($integer); - if ($integer === '') return false; + if ($integer === '') { + return false; + } // we could possibly simply typecast it to integer, but there are // certain fringe cases that must not return an integer. // clip leading sign - if ( $this->negative && $integer[0] === '-' ) { + if ($this->negative && $integer[0] === '-') { $digits = substr($integer, 1); - if ($digits === '0') $integer = '0'; // rm minus sign for zero - } elseif( $this->positive && $integer[0] === '+' ) { + if ($digits === '0') { + $integer = '0'; + } // rm minus sign for zero + } elseif ($this->positive && $integer[0] === '+') { $digits = $integer = substr($integer, 1); // rm unnecessary plus } else { $digits = $integer; } // test if it's numeric - if (!ctype_digit($digits)) return false; + if (!ctype_digit($digits)) { + return false; + } // perform scope tests - if (!$this->zero && $integer == 0) return false; - if (!$this->positive && $integer > 0) return false; - if (!$this->negative && $integer < 0) return false; + if (!$this->zero && $integer == 0) { + return false; + } + if (!$this->positive && $integer > 0) { + return false; + } + if (!$this->negative && $integer < 0) { + return false; + } return $integer; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/Lang.php b/library/HTMLPurifier/AttrDef/Lang.php index 10e6da56..2a55cea6 100644 --- a/library/HTMLPurifier/AttrDef/Lang.php +++ b/library/HTMLPurifier/AttrDef/Lang.php @@ -7,15 +7,25 @@ class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef { - public function validate($string, $config, $context) { - + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $string = trim($string); - if (!$string) return false; + if (!$string) { + return false; + } $subtags = explode('-', $string); $num_subtags = count($subtags); - if ($num_subtags == 0) return false; // sanity check + if ($num_subtags == 0) { // sanity check + return false; + } // process primary subtag : $subtags[0] $length = strlen($subtags[0]); @@ -23,15 +33,15 @@ class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef case 0: return false; case 1: - if (! ($subtags[0] == 'x' || $subtags[0] == 'i') ) { + if (!($subtags[0] == 'x' || $subtags[0] == 'i')) { return false; } break; case 2: case 3: - if (! ctype_alpha($subtags[0]) ) { + if (!ctype_alpha($subtags[0])) { return false; - } elseif (! ctype_lower($subtags[0]) ) { + } elseif (!ctype_lower($subtags[0])) { $subtags[0] = strtolower($subtags[0]); } break; @@ -40,17 +50,23 @@ class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef } $new_string = $subtags[0]; - if ($num_subtags == 1) return $new_string; + if ($num_subtags == 1) { + return $new_string; + } // process second subtag : $subtags[1] $length = strlen($subtags[1]); if ($length == 0 || ($length == 1 && $subtags[1] != 'x') || $length > 8 || !ctype_alnum($subtags[1])) { return $new_string; } - if (!ctype_lower($subtags[1])) $subtags[1] = strtolower($subtags[1]); + if (!ctype_lower($subtags[1])) { + $subtags[1] = strtolower($subtags[1]); + } $new_string .= '-' . $subtags[1]; - if ($num_subtags == 2) return $new_string; + if ($num_subtags == 2) { + return $new_string; + } // process all other subtags, index 2 and up for ($i = 2; $i < $num_subtags; $i++) { @@ -63,11 +79,8 @@ class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef } $new_string .= '-' . $subtags[$i]; } - return $new_string; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/Switch.php b/library/HTMLPurifier/AttrDef/Switch.php index c9e3ed19..c7eb3199 100644 --- a/library/HTMLPurifier/AttrDef/Switch.php +++ b/library/HTMLPurifier/AttrDef/Switch.php @@ -6,21 +6,41 @@ class HTMLPurifier_AttrDef_Switch { + /** + * @type string + */ protected $tag; - protected $withTag, $withoutTag; + + /** + * @type HTMLPurifier_AttrDef + */ + protected $withTag; + + /** + * @type HTMLPurifier_AttrDef + */ + protected $withoutTag; /** * @param string $tag Tag name to switch upon * @param HTMLPurifier_AttrDef $with_tag Call if token matches tag * @param HTMLPurifier_AttrDef $without_tag Call if token doesn't match, or there is no token */ - public function __construct($tag, $with_tag, $without_tag) { + public function __construct($tag, $with_tag, $without_tag) + { $this->tag = $tag; $this->withTag = $with_tag; $this->withoutTag = $without_tag; } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $token = $context->get('CurrentToken', true); if (!$token || $token->name !== $this->tag) { return $this->withoutTag->validate($string, $config, $context); @@ -28,7 +48,6 @@ class HTMLPurifier_AttrDef_Switch return $this->withTag->validate($string, $config, $context); } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/Text.php b/library/HTMLPurifier/AttrDef/Text.php index c6216cc5..4553a4ea 100644 --- a/library/HTMLPurifier/AttrDef/Text.php +++ b/library/HTMLPurifier/AttrDef/Text.php @@ -6,10 +6,16 @@ class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef { - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { return $this->parseCDATA($string); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/URI.php b/library/HTMLPurifier/AttrDef/URI.php index c2b68467..c1cd8977 100644 --- a/library/HTMLPurifier/AttrDef/URI.php +++ b/library/HTMLPurifier/AttrDef/URI.php @@ -7,31 +7,54 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef { + /** + * @type HTMLPurifier_URIParser + */ protected $parser; + + /** + * @type bool + */ protected $embedsResource; /** - * @param $embeds_resource_resource Does the URI here result in an extra HTTP request? + * @param bool $embeds_resource Does the URI here result in an extra HTTP request? */ - public function __construct($embeds_resource = false) { + public function __construct($embeds_resource = false) + { $this->parser = new HTMLPurifier_URIParser(); - $this->embedsResource = (bool) $embeds_resource; + $this->embedsResource = (bool)$embeds_resource; } - public function make($string) { + /** + * @param string $string + * @return HTMLPurifier_AttrDef_URI + */ + public function make($string) + { $embeds = ($string === 'embedded'); return new HTMLPurifier_AttrDef_URI($embeds); } - public function validate($uri, $config, $context) { - - if ($config->get('URI.Disable')) return false; + /** + * @param string $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($uri, $config, $context) + { + if ($config->get('URI.Disable')) { + return false; + } $uri = $this->parseCDATA($uri); // parse the URI $uri = $this->parser->parse($uri); - if ($uri === false) return false; + if ($uri === false) { + return false; + } // add embedded flag to context for validators $context->register('EmbeddedURI', $this->embedsResource); @@ -41,23 +64,35 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef // generic validation $result = $uri->validate($config, $context); - if (!$result) break; + if (!$result) { + break; + } // chained filtering $uri_def = $config->getDefinition('URI'); $result = $uri_def->filter($uri, $config, $context); - if (!$result) break; + if (!$result) { + break; + } // scheme-specific validation $scheme_obj = $uri->getSchemeObj($config, $context); - if (!$scheme_obj) break; - if ($this->embedsResource && !$scheme_obj->browsable) break; + if (!$scheme_obj) { + break; + } + if ($this->embedsResource && !$scheme_obj->browsable) { + break; + } $result = $scheme_obj->validate($uri, $config, $context); - if (!$result) break; + if (!$result) { + break; + } // Post chained filtering $result = $uri_def->postFilter($uri, $config, $context); - if (!$result) break; + if (!$result) { + break; + } // survived gauntlet $ok = true; @@ -65,13 +100,12 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef } while (false); $context->destroy('EmbeddedURI'); - if (!$ok) return false; - + if (!$ok) { + return false; + } // back to string return $uri->toString(); - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/URI/Email.php b/library/HTMLPurifier/AttrDef/URI/Email.php index bfee9d16..daf32b76 100644 --- a/library/HTMLPurifier/AttrDef/URI/Email.php +++ b/library/HTMLPurifier/AttrDef/URI/Email.php @@ -5,8 +5,11 @@ abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef /** * Unpacks a mailbox into its display-name and address + * @param string $string + * @return mixed */ - function unpack($string) { + public function unpack($string) + { // needs to be implemented } diff --git a/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php b/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php index 94c715ab..52c0d596 100644 --- a/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php +++ b/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php @@ -7,15 +7,23 @@ class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email { - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { // no support for named mailboxes i.e. "Bob " // that needs more percent encoding to be done - if ($string == '') return false; + if ($string == '') { + return false; + } $string = trim($string); $result = preg_match('/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string); return $result ? $string : false; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/URI/Host.php b/library/HTMLPurifier/AttrDef/URI/Host.php index b3d45dc6..e7df800b 100644 --- a/library/HTMLPurifier/AttrDef/URI/Host.php +++ b/library/HTMLPurifier/AttrDef/URI/Host.php @@ -7,21 +7,31 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef { /** - * Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator + * IPv4 sub-validator. + * @type HTMLPurifier_AttrDef_URI_IPv4 */ protected $ipv4; /** - * Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator + * IPv6 sub-validator. + * @type HTMLPurifier_AttrDef_URI_IPv6 */ protected $ipv6; - public function __construct() { + public function __construct() + { $this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4(); $this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6(); } - public function validate($string, $config, $context) { + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { $length = strlen($string); // empty hostname is OK; it's usually semantically equivalent: // the default host as defined by a URI scheme is used: @@ -29,18 +39,24 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef // If the URI scheme defines a default for host, then that // default applies when the host subcomponent is undefined // or when the registered name is empty (zero length). - if ($string === '') return ''; - if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') { + if ($string === '') { + return ''; + } + if ($length > 1 && $string[0] === '[' && $string[$length - 1] === ']') { //IPv6 $ip = substr($string, 1, $length - 2); $valid = $this->ipv6->validate($ip, $config, $context); - if ($valid === false) return false; - return '['. $valid . ']'; + if ($valid === false) { + return false; + } + return '[' . $valid . ']'; } // need to do checks on unusual encodings too $ipv4 = $this->ipv4->validate($string, $config, $context); - if ($ipv4 !== false) return $ipv4; + if ($ipv4 !== false) { + return $ipv4; + } // A regular domain name. @@ -65,9 +81,9 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef $an = '[a-z0-9]'; // alphanum $and = "[a-z0-9-$underscore]"; // alphanum | "-" // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum - $domainlabel = "$an($and*$an)?"; + $domainlabel = "$an($and*$an)?"; // toplabel = alpha | alpha *( alphanum | "-" ) alphanum - $toplabel = "$a($and*$an)?"; + $toplabel = "$a($and*$an)?"; // hostname = *( domainlabel "." ) toplabel [ "." ] if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) { return $string; @@ -105,10 +121,8 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef // XXX error reporting } } - return false; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/URI/IPv4.php b/library/HTMLPurifier/AttrDef/URI/IPv4.php index ec4cf591..30ac16c9 100644 --- a/library/HTMLPurifier/AttrDef/URI/IPv4.php +++ b/library/HTMLPurifier/AttrDef/URI/IPv4.php @@ -8,32 +8,38 @@ class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef { /** - * IPv4 regex, protected so that IPv6 can reuse it + * IPv4 regex, protected so that IPv6 can reuse it. + * @type string */ protected $ip4; - public function validate($aIP, $config, $context) { - - if (!$this->ip4) $this->_loadRegex(); - - if (preg_match('#^' . $this->ip4 . '$#s', $aIP)) - { - return $aIP; + /** + * @param string $aIP + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($aIP, $config, $context) + { + if (!$this->ip4) { + $this->_loadRegex(); } + if (preg_match('#^' . $this->ip4 . '$#s', $aIP)) { + return $aIP; + } return false; - } /** * Lazy load function to prevent regex from being stuffed in * cache. */ - protected function _loadRegex() { + protected function _loadRegex() + { $oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255 $this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})"; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrDef/URI/IPv6.php b/library/HTMLPurifier/AttrDef/URI/IPv6.php dissimilarity index 66% index 9454e9be..f243793e 100644 --- a/library/HTMLPurifier/AttrDef/URI/IPv6.php +++ b/library/HTMLPurifier/AttrDef/URI/IPv6.php @@ -1,99 +1,89 @@ -ip4) $this->_loadRegex(); - - $original = $aIP; - - $hex = '[0-9a-fA-F]'; - $blk = '(?:' . $hex . '{1,4})'; - $pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128 - - // prefix check - if (strpos($aIP, '/') !== false) - { - if (preg_match('#' . $pre . '$#s', $aIP, $find)) - { - $aIP = substr($aIP, 0, 0-strlen($find[0])); - unset($find); - } - else - { - return false; - } - } - - // IPv4-compatiblity check - if (preg_match('#(?<=:'.')' . $this->ip4 . '$#s', $aIP, $find)) - { - $aIP = substr($aIP, 0, 0-strlen($find[0])); - $ip = explode('.', $find[0]); - $ip = array_map('dechex', $ip); - $aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3]; - unset($find, $ip); - } - - // compression check - $aIP = explode('::', $aIP); - $c = count($aIP); - if ($c > 2) - { - return false; - } - elseif ($c == 2) - { - list($first, $second) = $aIP; - $first = explode(':', $first); - $second = explode(':', $second); - - if (count($first) + count($second) > 8) - { - return false; - } - - while(count($first) < 8) - { - array_push($first, '0'); - } - - array_splice($first, 8 - count($second), 8, $second); - $aIP = $first; - unset($first,$second); - } - else - { - $aIP = explode(':', $aIP[0]); - } - $c = count($aIP); - - if ($c != 8) - { - return false; - } - - // All the pieces should be 16-bit hex strings. Are they? - foreach ($aIP as $piece) - { - if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece))) - { - return false; - } - } - - return $original; - - } - -} - -// vim: et sw=4 sts=4 +ip4) { + $this->_loadRegex(); + } + + $original = $aIP; + + $hex = '[0-9a-fA-F]'; + $blk = '(?:' . $hex . '{1,4})'; + $pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128 + + // prefix check + if (strpos($aIP, '/') !== false) { + if (preg_match('#' . $pre . '$#s', $aIP, $find)) { + $aIP = substr($aIP, 0, 0 - strlen($find[0])); + unset($find); + } else { + return false; + } + } + + // IPv4-compatiblity check + if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) { + $aIP = substr($aIP, 0, 0 - strlen($find[0])); + $ip = explode('.', $find[0]); + $ip = array_map('dechex', $ip); + $aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3]; + unset($find, $ip); + } + + // compression check + $aIP = explode('::', $aIP); + $c = count($aIP); + if ($c > 2) { + return false; + } elseif ($c == 2) { + list($first, $second) = $aIP; + $first = explode(':', $first); + $second = explode(':', $second); + + if (count($first) + count($second) > 8) { + return false; + } + + while (count($first) < 8) { + array_push($first, '0'); + } + + array_splice($first, 8 - count($second), 8, $second); + $aIP = $first; + unset($first, $second); + } else { + $aIP = explode(':', $aIP[0]); + } + $c = count($aIP); + + if ($c != 8) { + return false; + } + + // All the pieces should be 16-bit hex strings. Are they? + foreach ($aIP as $piece) { + if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece))) { + return false; + } + } + return $original; + } +} + +// vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform.php b/library/HTMLPurifier/AttrTransform.php index e61d3e01..b428331f 100644 --- a/library/HTMLPurifier/AttrTransform.php +++ b/library/HTMLPurifier/AttrTransform.php @@ -20,37 +20,41 @@ abstract class HTMLPurifier_AttrTransform /** * Abstract: makes changes to the attributes dependent on multiple values. * - * @param $attr Assoc array of attributes, usually from + * @param array $attr Assoc array of attributes, usually from * HTMLPurifier_Token_Tag::$attr - * @param $config Mandatory HTMLPurifier_Config object. - * @param $context Mandatory HTMLPurifier_Context object - * @returns Processed attribute array. + * @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object. + * @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object + * @return array Processed attribute array. */ abstract public function transform($attr, $config, $context); /** * Prepends CSS properties to the style attribute, creating the * attribute if it doesn't exist. - * @param $attr Attribute array to process (passed by reference) - * @param $css CSS to prepend + * @param array &$attr Attribute array to process (passed by reference) + * @param string $css CSS to prepend */ - public function prependCSS(&$attr, $css) { + public function prependCSS(&$attr, $css) + { $attr['style'] = isset($attr['style']) ? $attr['style'] : ''; $attr['style'] = $css . $attr['style']; } /** * Retrieves and removes an attribute - * @param $attr Attribute array to process (passed by reference) - * @param $key Key of attribute to confiscate + * @param array &$attr Attribute array to process (passed by reference) + * @param mixed $key Key of attribute to confiscate + * @return mixed */ - public function confiscateAttr(&$attr, $key) { - if (!isset($attr[$key])) return null; + public function confiscateAttr(&$attr, $key) + { + if (!isset($attr[$key])) { + return null; + } $value = $attr[$key]; unset($attr[$key]); return $value; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Background.php b/library/HTMLPurifier/AttrTransform/Background.php index 0e1ff24a..2f72869a 100644 --- a/library/HTMLPurifier/AttrTransform/Background.php +++ b/library/HTMLPurifier/AttrTransform/Background.php @@ -3,21 +3,26 @@ /** * Pre-transform that changes proprietary background attribute to CSS. */ -class HTMLPurifier_AttrTransform_Background extends HTMLPurifier_AttrTransform { - - public function transform($attr, $config, $context) { - - if (!isset($attr['background'])) return $attr; +class HTMLPurifier_AttrTransform_Background extends HTMLPurifier_AttrTransform +{ + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['background'])) { + return $attr; + } $background = $this->confiscateAttr($attr, 'background'); // some validation should happen here $this->prependCSS($attr, "background-image:url($background);"); - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/BdoDir.php b/library/HTMLPurifier/AttrTransform/BdoDir.php index 4d1a0566..d66c04a5 100644 --- a/library/HTMLPurifier/AttrTransform/BdoDir.php +++ b/library/HTMLPurifier/AttrTransform/BdoDir.php @@ -8,12 +8,20 @@ class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform { - public function transform($attr, $config, $context) { - if (isset($attr['dir'])) return $attr; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (isset($attr['dir'])) { + return $attr; + } $attr['dir'] = $config->get('Attr.DefaultTextDir'); return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/BgColor.php b/library/HTMLPurifier/AttrTransform/BgColor.php index ad3916bb..0f51fd2c 100644 --- a/library/HTMLPurifier/AttrTransform/BgColor.php +++ b/library/HTMLPurifier/AttrTransform/BgColor.php @@ -3,21 +3,26 @@ /** * Pre-transform that changes deprecated bgcolor attribute to CSS. */ -class HTMLPurifier_AttrTransform_BgColor extends HTMLPurifier_AttrTransform { - - public function transform($attr, $config, $context) { - - if (!isset($attr['bgcolor'])) return $attr; +class HTMLPurifier_AttrTransform_BgColor extends HTMLPurifier_AttrTransform +{ + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['bgcolor'])) { + return $attr; + } $bgcolor = $this->confiscateAttr($attr, 'bgcolor'); // some validation should happen here $this->prependCSS($attr, "background-color:$bgcolor;"); - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/BoolToCSS.php b/library/HTMLPurifier/AttrTransform/BoolToCSS.php index 51159b67..f25cd019 100644 --- a/library/HTMLPurifier/AttrTransform/BoolToCSS.php +++ b/library/HTMLPurifier/AttrTransform/BoolToCSS.php @@ -3,34 +3,45 @@ /** * Pre-transform that changes converts a boolean attribute to fixed CSS */ -class HTMLPurifier_AttrTransform_BoolToCSS extends HTMLPurifier_AttrTransform { - +class HTMLPurifier_AttrTransform_BoolToCSS extends HTMLPurifier_AttrTransform +{ /** - * Name of boolean attribute that is trigger + * Name of boolean attribute that is trigger. + * @type string */ protected $attr; /** - * CSS declarations to add to style, needs trailing semicolon + * CSS declarations to add to style, needs trailing semicolon. + * @type string */ protected $css; /** - * @param $attr string attribute name to convert from - * @param $css string CSS declarations to add to style (needs semicolon) + * @param string $attr attribute name to convert from + * @param string $css CSS declarations to add to style (needs semicolon) */ - public function __construct($attr, $css) { + public function __construct($attr, $css) + { $this->attr = $attr; - $this->css = $css; + $this->css = $css; } - public function transform($attr, $config, $context) { - if (!isset($attr[$this->attr])) return $attr; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->attr])) { + return $attr; + } unset($attr[$this->attr]); $this->prependCSS($attr, $this->css); return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Border.php b/library/HTMLPurifier/AttrTransform/Border.php index 476b0b07..057dc017 100644 --- a/library/HTMLPurifier/AttrTransform/Border.php +++ b/library/HTMLPurifier/AttrTransform/Border.php @@ -3,16 +3,24 @@ /** * Pre-transform that changes deprecated border attribute to CSS. */ -class HTMLPurifier_AttrTransform_Border extends HTMLPurifier_AttrTransform { - - public function transform($attr, $config, $context) { - if (!isset($attr['border'])) return $attr; +class HTMLPurifier_AttrTransform_Border extends HTMLPurifier_AttrTransform +{ + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['border'])) { + return $attr; + } $border_width = $this->confiscateAttr($attr, 'border'); // some validation should happen here $this->prependCSS($attr, "border:{$border_width}px solid;"); return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/EnumToCSS.php b/library/HTMLPurifier/AttrTransform/EnumToCSS.php index 2a5b4514..7ccd0e3f 100644 --- a/library/HTMLPurifier/AttrTransform/EnumToCSS.php +++ b/library/HTMLPurifier/AttrTransform/EnumToCSS.php @@ -4,55 +4,65 @@ * Generic pre-transform that converts an attribute with a fixed number of * values (enumerated) to CSS. */ -class HTMLPurifier_AttrTransform_EnumToCSS extends HTMLPurifier_AttrTransform { - +class HTMLPurifier_AttrTransform_EnumToCSS extends HTMLPurifier_AttrTransform +{ /** - * Name of attribute to transform from + * Name of attribute to transform from. + * @type string */ protected $attr; /** - * Lookup array of attribute values to CSS + * Lookup array of attribute values to CSS. + * @type array */ protected $enumToCSS = array(); /** - * Case sensitivity of the matching + * Case sensitivity of the matching. + * @type bool * @warning Currently can only be guaranteed to work with ASCII * values. */ protected $caseSensitive = false; /** - * @param $attr String attribute name to transform from - * @param $enumToCSS Lookup array of attribute values to CSS - * @param $case_sensitive Boolean case sensitivity indicator, default false + * @param string $attr Attribute name to transform from + * @param array $enum_to_css Lookup array of attribute values to CSS + * @param bool $case_sensitive Case sensitivity indicator, default false */ - public function __construct($attr, $enum_to_css, $case_sensitive = false) { + public function __construct($attr, $enum_to_css, $case_sensitive = false) + { $this->attr = $attr; $this->enumToCSS = $enum_to_css; - $this->caseSensitive = (bool) $case_sensitive; + $this->caseSensitive = (bool)$case_sensitive; } - public function transform($attr, $config, $context) { - - if (!isset($attr[$this->attr])) return $attr; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->attr])) { + return $attr; + } $value = trim($attr[$this->attr]); unset($attr[$this->attr]); - if (!$this->caseSensitive) $value = strtolower($value); + if (!$this->caseSensitive) { + $value = strtolower($value); + } if (!isset($this->enumToCSS[$value])) { return $attr; } - $this->prependCSS($attr, $this->enumToCSS[$value]); - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/ImgRequired.php b/library/HTMLPurifier/AttrTransform/ImgRequired.php index 7f0e4b7a..7df6cb3e 100644 --- a/library/HTMLPurifier/AttrTransform/ImgRequired.php +++ b/library/HTMLPurifier/AttrTransform/ImgRequired.php @@ -11,11 +11,19 @@ class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform { - public function transform($attr, $config, $context) { - + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { $src = true; if (!isset($attr['src'])) { - if ($config->get('Core.RemoveInvalidImg')) return $attr; + if ($config->get('Core.RemoveInvalidImg')) { + return $attr; + } $attr['src'] = $config->get('Attr.DefaultInvalidImage'); $src = false; } @@ -25,7 +33,7 @@ class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform $alt = $config->get('Attr.DefaultImageAlt'); if ($alt === null) { // truncate if the alt is too long - $attr['alt'] = substr(basename($attr['src']),0,40); + $attr['alt'] = substr(basename($attr['src']), 0, 40); } else { $attr['alt'] = $alt; } @@ -33,11 +41,8 @@ class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform $attr['alt'] = $config->get('Attr.DefaultInvalidImageAlt'); } } - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/ImgSpace.php b/library/HTMLPurifier/AttrTransform/ImgSpace.php index fd84c10c..350b3358 100644 --- a/library/HTMLPurifier/AttrTransform/ImgSpace.php +++ b/library/HTMLPurifier/AttrTransform/ImgSpace.php @@ -3,42 +3,59 @@ /** * Pre-transform that changes deprecated hspace and vspace attributes to CSS */ -class HTMLPurifier_AttrTransform_ImgSpace extends HTMLPurifier_AttrTransform { - +class HTMLPurifier_AttrTransform_ImgSpace extends HTMLPurifier_AttrTransform +{ + /** + * @type string + */ protected $attr; + + /** + * @type array + */ protected $css = array( 'hspace' => array('left', 'right'), 'vspace' => array('top', 'bottom') ); - public function __construct($attr) { + /** + * @param string $attr + */ + public function __construct($attr) + { $this->attr = $attr; if (!isset($this->css[$attr])) { trigger_error(htmlspecialchars($attr) . ' is not valid space attribute'); } } - public function transform($attr, $config, $context) { - - if (!isset($attr[$this->attr])) return $attr; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->attr])) { + return $attr; + } $width = $this->confiscateAttr($attr, $this->attr); // some validation could happen here - if (!isset($this->css[$this->attr])) return $attr; + if (!isset($this->css[$this->attr])) { + return $attr; + } $style = ''; foreach ($this->css[$this->attr] as $suffix) { $property = "margin-$suffix"; $style .= "$property:{$width}px;"; } - $this->prependCSS($attr, $style); - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Input.php b/library/HTMLPurifier/AttrTransform/Input.php index 16829552..3ab47ed8 100644 --- a/library/HTMLPurifier/AttrTransform/Input.php +++ b/library/HTMLPurifier/AttrTransform/Input.php @@ -4,17 +4,31 @@ * Performs miscellaneous cross attribute validation and filtering for * input elements. This is meant to be a post-transform. */ -class HTMLPurifier_AttrTransform_Input extends HTMLPurifier_AttrTransform { - +class HTMLPurifier_AttrTransform_Input extends HTMLPurifier_AttrTransform +{ + /** + * @type HTMLPurifier_AttrDef_HTML_Pixels + */ protected $pixels; - public function __construct() { + public function __construct() + { $this->pixels = new HTMLPurifier_AttrDef_HTML_Pixels(); } - public function transform($attr, $config, $context) { - if (!isset($attr['type'])) $t = 'text'; - else $t = strtolower($attr['type']); + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['type'])) { + $t = 'text'; + } else { + $t = strtolower($attr['type']); + } if (isset($attr['checked']) && $t !== 'radio' && $t !== 'checkbox') { unset($attr['checked']); } @@ -23,8 +37,11 @@ class HTMLPurifier_AttrTransform_Input extends HTMLPurifier_AttrTransform { } if (isset($attr['size']) && $t !== 'text' && $t !== 'password') { $result = $this->pixels->validate($attr['size'], $config, $context); - if ($result === false) unset($attr['size']); - else $attr['size'] = $result; + if ($result === false) { + unset($attr['size']); + } else { + $attr['size'] = $result; + } } if (isset($attr['src']) && $t !== 'image') { unset($attr['src']); @@ -34,7 +51,6 @@ class HTMLPurifier_AttrTransform_Input extends HTMLPurifier_AttrTransform { } return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Lang.php b/library/HTMLPurifier/AttrTransform/Lang.php index 5869e7f8..5b0aff0e 100644 --- a/library/HTMLPurifier/AttrTransform/Lang.php +++ b/library/HTMLPurifier/AttrTransform/Lang.php @@ -8,9 +8,15 @@ class HTMLPurifier_AttrTransform_Lang extends HTMLPurifier_AttrTransform { - public function transform($attr, $config, $context) { - - $lang = isset($attr['lang']) ? $attr['lang'] : false; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + $lang = isset($attr['lang']) ? $attr['lang'] : false; $xml_lang = isset($attr['xml:lang']) ? $attr['xml:lang'] : false; if ($lang !== false && $xml_lang === false) { @@ -18,11 +24,8 @@ class HTMLPurifier_AttrTransform_Lang extends HTMLPurifier_AttrTransform } elseif ($xml_lang !== false) { $attr['lang'] = $xml_lang; } - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Length.php b/library/HTMLPurifier/AttrTransform/Length.php index ea2f3047..853f3354 100644 --- a/library/HTMLPurifier/AttrTransform/Length.php +++ b/library/HTMLPurifier/AttrTransform/Length.php @@ -6,22 +6,40 @@ class HTMLPurifier_AttrTransform_Length extends HTMLPurifier_AttrTransform { + /** + * @type string + */ protected $name; + + /** + * @type string + */ protected $cssName; - public function __construct($name, $css_name = null) { + public function __construct($name, $css_name = null) + { $this->name = $name; $this->cssName = $css_name ? $css_name : $name; } - public function transform($attr, $config, $context) { - if (!isset($attr[$this->name])) return $attr; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->name])) { + return $attr; + } $length = $this->confiscateAttr($attr, $this->name); - if(ctype_digit($length)) $length .= 'px'; + if (ctype_digit($length)) { + $length .= 'px'; + } $this->prependCSS($attr, $this->cssName . ":$length;"); return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Name.php b/library/HTMLPurifier/AttrTransform/Name.php index 15315bc7..63cce683 100644 --- a/library/HTMLPurifier/AttrTransform/Name.php +++ b/library/HTMLPurifier/AttrTransform/Name.php @@ -6,16 +6,28 @@ class HTMLPurifier_AttrTransform_Name extends HTMLPurifier_AttrTransform { - public function transform($attr, $config, $context) { + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { // Abort early if we're using relaxed definition of name - if ($config->get('HTML.Attr.Name.UseCDATA')) return $attr; - if (!isset($attr['name'])) return $attr; + if ($config->get('HTML.Attr.Name.UseCDATA')) { + return $attr; + } + if (!isset($attr['name'])) { + return $attr; + } $id = $this->confiscateAttr($attr, 'name'); - if ( isset($attr['id'])) return $attr; + if (isset($attr['id'])) { + return $attr; + } $attr['id'] = $id; return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/NameSync.php b/library/HTMLPurifier/AttrTransform/NameSync.php index a95638c1..36079b78 100644 --- a/library/HTMLPurifier/AttrTransform/NameSync.php +++ b/library/HTMLPurifier/AttrTransform/NameSync.php @@ -8,20 +8,34 @@ class HTMLPurifier_AttrTransform_NameSync extends HTMLPurifier_AttrTransform { - public function __construct() { + public function __construct() + { $this->idDef = new HTMLPurifier_AttrDef_HTML_ID(); } - public function transform($attr, $config, $context) { - if (!isset($attr['name'])) return $attr; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['name'])) { + return $attr; + } $name = $attr['name']; - if (isset($attr['id']) && $attr['id'] === $name) return $attr; + if (isset($attr['id']) && $attr['id'] === $name) { + return $attr; + } $result = $this->idDef->validate($name, $config, $context); - if ($result === false) unset($attr['name']); - else $attr['name'] = $result; + if ($result === false) { + unset($attr['name']); + } else { + $attr['name'] = $result; + } return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Nofollow.php b/library/HTMLPurifier/AttrTransform/Nofollow.php index e699c79a..1057ebee 100644 --- a/library/HTMLPurifier/AttrTransform/Nofollow.php +++ b/library/HTMLPurifier/AttrTransform/Nofollow.php @@ -8,14 +8,24 @@ */ class HTMLPurifier_AttrTransform_Nofollow extends HTMLPurifier_AttrTransform { + /** + * @type HTMLPurifier_URIParser + */ private $parser; - public function __construct() { + public function __construct() + { $this->parser = new HTMLPurifier_URIParser(); } - public function transform($attr, $config, $context) { - + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { if (!isset($attr['href'])) { return $attr; } @@ -35,11 +45,8 @@ class HTMLPurifier_AttrTransform_Nofollow extends HTMLPurifier_AttrTransform $attr['rel'] = 'nofollow'; } } - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/SafeEmbed.php b/library/HTMLPurifier/AttrTransform/SafeEmbed.php index 4da44998..231c81a3 100644 --- a/library/HTMLPurifier/AttrTransform/SafeEmbed.php +++ b/library/HTMLPurifier/AttrTransform/SafeEmbed.php @@ -2,9 +2,19 @@ class HTMLPurifier_AttrTransform_SafeEmbed extends HTMLPurifier_AttrTransform { + /** + * @type string + */ public $name = "SafeEmbed"; - public function transform($attr, $config, $context) { + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { $attr['allowscriptaccess'] = 'never'; $attr['allownetworking'] = 'internal'; $attr['type'] = 'application/x-shockwave-flash'; diff --git a/library/HTMLPurifier/AttrTransform/SafeObject.php b/library/HTMLPurifier/AttrTransform/SafeObject.php index 1ed74898..d1f3a4d2 100644 --- a/library/HTMLPurifier/AttrTransform/SafeObject.php +++ b/library/HTMLPurifier/AttrTransform/SafeObject.php @@ -5,10 +5,22 @@ */ class HTMLPurifier_AttrTransform_SafeObject extends HTMLPurifier_AttrTransform { + /** + * @type string + */ public $name = "SafeObject"; - function transform($attr, $config, $context) { - if (!isset($attr['type'])) $attr['type'] = 'application/x-shockwave-flash'; + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['type'])) { + $attr['type'] = 'application/x-shockwave-flash'; + } return $attr; } } diff --git a/library/HTMLPurifier/AttrTransform/SafeParam.php b/library/HTMLPurifier/AttrTransform/SafeParam.php index bd86a745..1143b4b4 100644 --- a/library/HTMLPurifier/AttrTransform/SafeParam.php +++ b/library/HTMLPurifier/AttrTransform/SafeParam.php @@ -14,15 +14,30 @@ */ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform { + /** + * @type string + */ public $name = "SafeParam"; + + /** + * @type HTMLPurifier_AttrDef_URI + */ private $uri; - public function __construct() { + public function __construct() + { $this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded $this->wmode = new HTMLPurifier_AttrDef_Enum(array('window', 'opaque', 'transparent')); } - public function transform($attr, $config, $context) { + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { // If we add support for other objects, we'll need to alter the // transforms. switch ($attr['name']) { diff --git a/library/HTMLPurifier/AttrTransform/ScriptRequired.php b/library/HTMLPurifier/AttrTransform/ScriptRequired.php index 4499050a..b7057bbf 100644 --- a/library/HTMLPurifier/AttrTransform/ScriptRequired.php +++ b/library/HTMLPurifier/AttrTransform/ScriptRequired.php @@ -5,7 +5,14 @@ */ class HTMLPurifier_AttrTransform_ScriptRequired extends HTMLPurifier_AttrTransform { - public function transform($attr, $config, $context) { + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { if (!isset($attr['type'])) { $attr['type'] = 'text/javascript'; } diff --git a/library/HTMLPurifier/AttrTransform/TargetBlank.php b/library/HTMLPurifier/AttrTransform/TargetBlank.php index deba8b40..dd63ea89 100644 --- a/library/HTMLPurifier/AttrTransform/TargetBlank.php +++ b/library/HTMLPurifier/AttrTransform/TargetBlank.php @@ -9,14 +9,24 @@ */ class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform { + /** + * @type HTMLPurifier_URIParser + */ private $parser; - public function __construct() { + public function __construct() + { $this->parser = new HTMLPurifier_URIParser(); } - public function transform($attr, $config, $context) { - + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { if (!isset($attr['href'])) { return $attr; } @@ -28,11 +38,8 @@ class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform if ($scheme->browsable && !$url->isBenign($config, $context)) { $attr['target'] = '_blank'; } - return $attr; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTransform/Textarea.php b/library/HTMLPurifier/AttrTransform/Textarea.php index 81ac3488..6a9f33a0 100644 --- a/library/HTMLPurifier/AttrTransform/Textarea.php +++ b/library/HTMLPurifier/AttrTransform/Textarea.php @@ -5,14 +5,23 @@ */ class HTMLPurifier_AttrTransform_Textarea extends HTMLPurifier_AttrTransform { - - public function transform($attr, $config, $context) { + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { // Calculated from Firefox - if (!isset($attr['cols'])) $attr['cols'] = '22'; - if (!isset($attr['rows'])) $attr['rows'] = '3'; + if (!isset($attr['cols'])) { + $attr['cols'] = '22'; + } + if (!isset($attr['rows'])) { + $attr['rows'] = '3'; + } return $attr; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/AttrTypes.php b/library/HTMLPurifier/AttrTypes.php index 6f985ff9..3b70520b 100644 --- a/library/HTMLPurifier/AttrTypes.php +++ b/library/HTMLPurifier/AttrTypes.php @@ -6,7 +6,8 @@ class HTMLPurifier_AttrTypes { /** - * Lookup array of attribute string identifiers to concrete implementations + * Lookup array of attribute string identifiers to concrete implementations. + * @type HTMLPurifier_AttrDef[] */ protected $info = array(); @@ -14,7 +15,8 @@ class HTMLPurifier_AttrTypes * Constructs the info array, supplying default implementations for attribute * types. */ - public function __construct() { + public function __construct() + { // XXX This is kind of poor, since we don't actually /clone/ // instances; instead, we use the supplied make() attribute. So, // the underlying class must know how to deal with arguments. @@ -54,36 +56,39 @@ class HTMLPurifier_AttrTypes $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true); } - private static function makeEnum($in) { + private static function makeEnum($in) + { return new HTMLPurifier_AttrDef_Clone(new HTMLPurifier_AttrDef_Enum(explode(',', $in))); } /** * Retrieves a type - * @param $type String type name - * @return Object AttrDef for type + * @param string $type String type name + * @return HTMLPurifier_AttrDef Object AttrDef for type */ - public function get($type) { - + public function get($type) + { // determine if there is any extra info tacked on - if (strpos($type, '#') !== false) list($type, $string) = explode('#', $type, 2); - else $string = ''; + if (strpos($type, '#') !== false) { + list($type, $string) = explode('#', $type, 2); + } else { + $string = ''; + } if (!isset($this->info[$type])) { trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR); return; } - return $this->info[$type]->make($string); - } /** * Sets a new implementation for a type - * @param $type String type name - * @param $impl Object AttrDef for type + * @param string $type String type name + * @param HTMLPurifier_AttrDef $impl Object AttrDef for type */ - public function set($type, $impl) { + public function set($type, $impl) + { $this->info[$type] = $impl; } } diff --git a/library/HTMLPurifier/AttrValidator.php b/library/HTMLPurifier/AttrValidator.php index 829a0f8f..18311bc3 100644 --- a/library/HTMLPurifier/AttrValidator.php +++ b/library/HTMLPurifier/AttrValidator.php @@ -11,15 +11,16 @@ class HTMLPurifier_AttrValidator /** * Validates the attributes of a token, returning a modified token * that has valid tokens - * @param $token Reference to token to validate. We require a reference + * @param HTMLPurifier_Token $token Reference to token to validate. We require a reference * because the operation this class performs on the token are * not atomic, so the context CurrentToken to be updated * throughout - * @param $config Instance of HTMLPurifier_Config - * @param $context Instance of HTMLPurifier_Context + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config + * @param HTMLPurifier_Context $context Instance of HTMLPurifier_Context + * @return HTMLPurifier_Token */ - public function validateToken(&$token, &$config, $context) { - + public function validateToken(&$token, &$config, $context) + { $definition = $config->getHTMLDefinition(); $e =& $context->get('ErrorCollector', true); @@ -32,12 +33,15 @@ class HTMLPurifier_AttrValidator // initialize CurrentToken if necessary $current_token =& $context->get('CurrentToken', true); - if (!$current_token) $context->register('CurrentToken', $token); + if (!$current_token) { + $context->register('CurrentToken', $token); + } - if ( - !$token instanceof HTMLPurifier_Token_Start && + if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty - ) return $token; + ) { + return $token; + } // create alias to global definition array, see also $defs // DEFINITION CALL @@ -51,7 +55,9 @@ class HTMLPurifier_AttrValidator foreach ($definition->info_attr_transform_pre as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { - if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } } } @@ -60,7 +66,9 @@ class HTMLPurifier_AttrValidator foreach ($definition->info[$token->name]->attr_transform_pre as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { - if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } } } @@ -77,7 +85,7 @@ class HTMLPurifier_AttrValidator foreach ($attr as $attr_key => $value) { // call the definition - if ( isset($defs[$attr_key]) ) { + if (isset($defs[$attr_key])) { // there is a local definition defined if ($defs[$attr_key] === false) { // We've explicitly been told not to allow this element. @@ -89,15 +97,19 @@ class HTMLPurifier_AttrValidator } else { // validate according to the element's definition $result = $defs[$attr_key]->validate( - $value, $config, $context - ); + $value, + $config, + $context + ); } - } elseif ( isset($d_defs[$attr_key]) ) { + } elseif (isset($d_defs[$attr_key])) { // there is a global definition defined, validate according // to the global definition $result = $d_defs[$attr_key]->validate( - $value, $config, $context - ); + $value, + $config, + $context + ); } else { // system never heard of the attribute? DELETE! $result = false; @@ -107,7 +119,9 @@ class HTMLPurifier_AttrValidator if ($result === false || $result === null) { // this is a generic error message that should replaced // with more specific ones when possible - if ($e) $e->send(E_ERROR, 'AttrValidator: Attribute removed'); + if ($e) { + $e->send(E_ERROR, 'AttrValidator: Attribute removed'); + } // remove the attribute unset($attr[$attr_key]); @@ -137,7 +151,9 @@ class HTMLPurifier_AttrValidator foreach ($definition->info_attr_transform_post as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { - if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } } } @@ -145,14 +161,18 @@ class HTMLPurifier_AttrValidator foreach ($definition->info[$token->name]->attr_transform_post as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { - if ($attr != $o) $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } } } $token->attr = $attr; // destroy CurrentToken if we made it ourselves - if (!$current_token) $context->destroy('CurrentToken'); + if (!$current_token) { + $context->destroy('CurrentToken'); + } } diff --git a/library/HTMLPurifier/Bootstrap.php b/library/HTMLPurifier/Bootstrap.php index ae503320..707122bb 100644 --- a/library/HTMLPurifier/Bootstrap.php +++ b/library/HTMLPurifier/Bootstrap.php @@ -32,11 +32,15 @@ class HTMLPurifier_Bootstrap /** * Autoload function for HTML Purifier - * @param $class Class to load + * @param string $class Class to load + * @return bool */ - public static function autoload($class) { + public static function autoload($class) + { $file = HTMLPurifier_Bootstrap::getPath($class); - if (!$file) return false; + if (!$file) { + return false; + } // Technically speaking, it should be ok and more efficient to // just do 'require', but Antonio Parraga reports that with // Zend extensions such as Zend debugger and APC, this invariant @@ -48,9 +52,14 @@ class HTMLPurifier_Bootstrap /** * Returns the path for a specific class. + * @param string $class Class path to get + * @return string */ - public static function getPath($class) { - if (strncmp('HTMLPurifier', $class, 12) !== 0) return false; + public static function getPath($class) + { + if (strncmp('HTMLPurifier', $class, 12) !== 0) { + return false; + } // Custom implementations if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) { $code = str_replace('_', '-', substr($class, 22)); @@ -58,16 +67,19 @@ class HTMLPurifier_Bootstrap } else { $file = str_replace('_', '/', $class) . '.php'; } - if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) return false; + if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) { + return false; + } return $file; } /** * "Pre-registers" our autoloader on the SPL stack. */ - public static function registerAutoload() { + public static function registerAutoload() + { $autoload = array('HTMLPurifier_Bootstrap', 'autoload'); - if ( ($funcs = spl_autoload_functions()) === false ) { + if (($funcs = spl_autoload_functions()) === false) { spl_autoload_register($autoload); } elseif (function_exists('spl_autoload_unregister')) { if (version_compare(PHP_VERSION, '5.3.0', '>=')) { @@ -83,27 +95,30 @@ class HTMLPurifier_Bootstrap // places where we need to error out $reflector = new ReflectionMethod($func[0], $func[1]); if (!$reflector->isStatic()) { - throw new Exception(' - HTML Purifier autoloader registrar is not compatible + throw new Exception( + 'HTML Purifier autoloader registrar is not compatible with non-static object methods due to PHP Bug #44144; Please do not use HTMLPurifier.autoload.php (or any file that includes this file); instead, place the code: spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\')) - after your own autoloaders. - '); + after your own autoloaders.' + ); } // Suprisingly, spl_autoload_register supports the // Class::staticMethod callback format, although call_user_func doesn't - if ($compat) $func = implode('::', $func); + if ($compat) { + $func = implode('::', $func); + } } spl_autoload_unregister($func); } spl_autoload_register($autoload); - foreach ($funcs as $func) spl_autoload_register($func); + foreach ($funcs as $func) { + spl_autoload_register($func); + } } } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/CSSDefinition.php b/library/HTMLPurifier/CSSDefinition.php index 8c4c3127..0acdee2d 100644 --- a/library/HTMLPurifier/CSSDefinition.php +++ b/library/HTMLPurifier/CSSDefinition.php @@ -11,35 +11,59 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition /** * Assoc array of attribute name to definition object. + * @type HTMLPurifier_AttrDef[] */ public $info = array(); /** * Constructs the info array. The meat of this class. + * @param HTMLPurifier_Config $config */ - protected function doSetup($config) { - + protected function doSetup($config) + { $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( - array('left', 'right', 'center', 'justify'), false); + array('left', 'right', 'center', 'justify'), + false + ); $border_style = - $this->info['border-bottom-style'] = - $this->info['border-right-style'] = - $this->info['border-left-style'] = - $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( - array('none', 'hidden', 'dotted', 'dashed', 'solid', 'double', - 'groove', 'ridge', 'inset', 'outset'), false); + $this->info['border-bottom-style'] = + $this->info['border-right-style'] = + $this->info['border-left-style'] = + $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( + array( + 'none', + 'hidden', + 'dotted', + 'dashed', + 'solid', + 'double', + 'groove', + 'ridge', + 'inset', + 'outset' + ), + false + ); $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); $this->info['clear'] = new HTMLPurifier_AttrDef_Enum( - array('none', 'left', 'right', 'both'), false); + array('none', 'left', 'right', 'both'), + false + ); $this->info['float'] = new HTMLPurifier_AttrDef_Enum( - array('none', 'left', 'right'), false); + array('none', 'left', 'right'), + false + ); $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( - array('normal', 'italic', 'oblique'), false); + array('normal', 'italic', 'oblique'), + false + ); $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( - array('normal', 'small-caps'), false); + array('normal', 'small-caps'), + false + ); $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( array( @@ -49,16 +73,31 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition ); $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( - array('inside', 'outside'), false); + array('inside', 'outside'), + false + ); $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( - array('disc', 'circle', 'square', 'decimal', 'lower-roman', - 'upper-roman', 'lower-alpha', 'upper-alpha', 'none'), false); + array( + 'disc', + 'circle', + 'square', + 'decimal', + 'lower-roman', + 'upper-roman', + 'lower-alpha', + 'upper-alpha', + 'none' + ), + false + ); $this->info['list-style-image'] = $uri_or_none; $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( - array('capitalize', 'uppercase', 'lowercase', 'none'), false); + array('capitalize', 'uppercase', 'lowercase', 'none'), + false + ); $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['background-image'] = $uri_or_none; @@ -71,104 +110,137 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); $border_color = - $this->info['border-top-color'] = - $this->info['border-bottom-color'] = - $this->info['border-left-color'] = - $this->info['border-right-color'] = - $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Enum(array('transparent')), - new HTMLPurifier_AttrDef_CSS_Color() - )); + $this->info['border-top-color'] = + $this->info['border-bottom-color'] = + $this->info['border-left-color'] = + $this->info['border-right-color'] = + $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('transparent')), + new HTMLPurifier_AttrDef_CSS_Color() + ) + ); $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color); $border_width = - $this->info['border-top-width'] = - $this->info['border-bottom-width'] = - $this->info['border-left-width'] = - $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')), - new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative - )); + $this->info['border-top-width'] = + $this->info['border-bottom-width'] = + $this->info['border-left-width'] = + $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')), + new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative + ) + ); $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); - $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Enum(array('normal')), - new HTMLPurifier_AttrDef_CSS_Length() - )); - - $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Enum(array('normal')), - new HTMLPurifier_AttrDef_CSS_Length() - )); - - $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Enum(array('xx-small', 'x-small', - 'small', 'medium', 'large', 'x-large', 'xx-large', - 'larger', 'smaller')), - new HTMLPurifier_AttrDef_CSS_Percentage(), - new HTMLPurifier_AttrDef_CSS_Length() - )); - - $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Enum(array('normal')), - new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives - new HTMLPurifier_AttrDef_CSS_Length('0'), - new HTMLPurifier_AttrDef_CSS_Percentage(true) - )); + $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Length() + ) + ); + + $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Length() + ) + ); + + $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum( + array( + 'xx-small', + 'x-small', + 'small', + 'medium', + 'large', + 'x-large', + 'xx-large', + 'larger', + 'smaller' + ) + ), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_CSS_Length() + ) + ); + + $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + ) + ); $margin = - $this->info['margin-top'] = - $this->info['margin-bottom'] = - $this->info['margin-left'] = - $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage(), - new HTMLPurifier_AttrDef_Enum(array('auto')) - )); + $this->info['margin-top'] = + $this->info['margin-bottom'] = + $this->info['margin-left'] = + $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(array('auto')) + ) + ); $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); // non-negative $padding = - $this->info['padding-top'] = - $this->info['padding-bottom'] = - $this->info['padding-left'] = - $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length('0'), - new HTMLPurifier_AttrDef_CSS_Percentage(true) - )); + $this->info['padding-top'] = + $this->info['padding-bottom'] = + $this->info['padding-left'] = + $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + ) + ); $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); - $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage() - )); + $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + ) + ); - $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length('0'), - new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('auto')) - )); + $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true), + new HTMLPurifier_AttrDef_Enum(array('auto')) + ) + ); $max = $config->get('CSS.MaxImgLength'); $this->info['width'] = $this->info['height'] = $max === null ? - $trusted_wh : - new HTMLPurifier_AttrDef_Switch('img', - // For img tags: - new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length('0', $max), - new HTMLPurifier_AttrDef_Enum(array('auto')) - )), - // For everyone else: - $trusted_wh - ); + $trusted_wh : + new HTMLPurifier_AttrDef_Switch( + 'img', + // For img tags: + new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length('0', $max), + new HTMLPurifier_AttrDef_Enum(array('auto')) + ) + ), + // For everyone else: + $trusted_wh + ); $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); @@ -176,8 +248,23 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition // this could use specialized code $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( - array('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', - '400', '500', '600', '700', '800', '900'), false); + array( + 'normal', + 'bold', + 'bolder', + 'lighter', + '100', + '200', + '300', + '400', + '500', + '600', + '700', + '800', + '900' + ), + false + ); // MUST be called after other font properties, as it references // a CSSDefinition object @@ -190,27 +277,44 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition $this->info['border-left'] = $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); - $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(array( - 'collapse', 'separate')); + $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( + array('collapse', 'separate') + ); - $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(array( - 'top', 'bottom')); + $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( + array('top', 'bottom') + ); - $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(array( - 'auto', 'fixed')); + $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( + array('auto', 'fixed') + ); - $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Enum(array('baseline', 'sub', 'super', - 'top', 'text-top', 'middle', 'bottom', 'text-bottom')), - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage() - )); + $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum( + array( + 'baseline', + 'sub', + 'super', + 'top', + 'text-top', + 'middle', + 'bottom', + 'text-bottom' + ) + ), + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + ) + ); $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); // These CSS properties don't work on many browsers, but we live // in THE FUTURE! - $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line')); + $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( + array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line') + ); if ($config->get('CSS.Proprietary')) { $this->doSetupProprietary($config); @@ -233,76 +337,119 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition $this->setupConfigStuff($config); } - protected function doSetupProprietary($config) { + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupProprietary($config) + { // Internet Explorer only scrollbar colors - $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); - $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color(); - $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); - $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color(); - $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color(); - $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); // technically not proprietary, but CSS3, and no one supports it - $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); - $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); - $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); // only opacity, for now $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter(); // more CSS3 $this->info['page-break-after'] = - $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum(array('auto','always','avoid','left','right')); - $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto','avoid')); + $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( + array( + 'auto', + 'always', + 'avoid', + 'left', + 'right' + ) + ); + $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid')); } - protected function doSetupTricky($config) { - $this->info['display'] = new HTMLPurifier_AttrDef_Enum(array( - 'inline', 'block', 'list-item', 'run-in', 'compact', - 'marker', 'table', 'inline-block', 'inline-table', 'table-row-group', - 'table-header-group', 'table-footer-group', 'table-row', - 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none' - )); - $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(array( - 'visible', 'hidden', 'collapse' - )); + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupTricky($config) + { + $this->info['display'] = new HTMLPurifier_AttrDef_Enum( + array( + 'inline', + 'block', + 'list-item', + 'run-in', + 'compact', + 'marker', + 'table', + 'inline-block', + 'inline-table', + 'table-row-group', + 'table-header-group', + 'table-footer-group', + 'table-row', + 'table-column-group', + 'table-column', + 'table-cell', + 'table-caption', + 'none' + ) + ); + $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( + array('visible', 'hidden', 'collapse') + ); $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll')); } - protected function doSetupTrusted($config) { - $this->info['position'] = new HTMLPurifier_AttrDef_Enum(array( - 'static', 'relative', 'absolute', 'fixed' - )); + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupTrusted($config) + { + $this->info['position'] = new HTMLPurifier_AttrDef_Enum( + array('static', 'relative', 'absolute', 'fixed') + ); $this->info['top'] = $this->info['left'] = $this->info['right'] = - $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length(), - new HTMLPurifier_AttrDef_CSS_Percentage(), - new HTMLPurifier_AttrDef_Enum(array('auto')), - )); - $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_Integer(), - new HTMLPurifier_AttrDef_Enum(array('auto')), - )); + $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(array('auto')), + ) + ); + $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Integer(), + new HTMLPurifier_AttrDef_Enum(array('auto')), + ) + ); } /** * Performs extra config-based processing. Based off of * HTMLPurifier_HTMLDefinition. + * @param HTMLPurifier_Config $config * @todo Refactor duplicate elements into common class (probably using * composition, not inheritance). */ - protected function setupConfigStuff($config) { - + protected function setupConfigStuff($config) + { // setup allowed elements - $support = "(for information on implementing this, see the ". - "support forums) "; + $support = "(for information on implementing this, see the " . + "support forums) "; $allowed_properties = $config->get('CSS.AllowedProperties'); if ($allowed_properties !== null) { foreach ($this->info as $name => $d) { - if(!isset($allowed_properties[$name])) unset($this->info[$name]); + if (!isset($allowed_properties[$name])) { + unset($this->info[$name]); + } unset($allowed_properties[$name]); } // emit errors @@ -321,7 +468,6 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition } } } - } } diff --git a/library/HTMLPurifier/ChildDef.php b/library/HTMLPurifier/ChildDef.php index c5d5216d..2c0f1647 100644 --- a/library/HTMLPurifier/ChildDef.php +++ b/library/HTMLPurifier/ChildDef.php @@ -8,39 +8,43 @@ abstract class HTMLPurifier_ChildDef /** * Type of child definition, usually right-most part of class name lowercase. * Used occasionally in terms of context. + * @type string */ public $type; /** - * Bool that indicates whether or not an empty array of children is okay + * Indicates whether or not an empty array of children is okay. * * This is necessary for redundant checking when changes affecting * a child node may cause a parent node to now be disallowed. + * @type bool */ public $allow_empty; /** - * Lookup array of all elements that this definition could possibly allow + * Lookup array of all elements that this definition could possibly allow. + * @type array */ public $elements = array(); /** * Get lookup of tag names that should not close this element automatically. * All other elements will do so. + * @param HTMLPurifier_Config $config HTMLPurifier_Config object + * @return array */ - public function getAllowedElements($config) { + public function getAllowedElements($config) + { return $this->elements; } /** * Validates nodes according to definition and returns modification. * - * @param $tokens_of_children Array of HTMLPurifier_Token - * @param $config HTMLPurifier_Config object - * @param $context HTMLPurifier_Context object - * @return bool true to leave nodes as is - * @return bool false to remove parent node - * @return array of replacement child tokens + * @param HTMLPurifier_Token[] $tokens_of_children Array of HTMLPurifier_Token + * @param HTMLPurifier_Config $config HTMLPurifier_Config object + * @param HTMLPurifier_Context $context HTMLPurifier_Context object + * @return bool|array true to leave nodes as is, false to remove parent node, array of replacement child tokens */ abstract public function validateChildren($tokens_of_children, $config, $context); } diff --git a/library/HTMLPurifier/ChildDef/Chameleon.php b/library/HTMLPurifier/ChildDef/Chameleon.php index 15c364ee..f7508739 100644 --- a/library/HTMLPurifier/ChildDef/Chameleon.php +++ b/library/HTMLPurifier/ChildDef/Chameleon.php @@ -14,33 +14,52 @@ class HTMLPurifier_ChildDef_Chameleon extends HTMLPurifier_ChildDef /** * Instance of the definition object to use when inline. Usually stricter. + * @type HTMLPurifier_ChildDef_Optional */ public $inline; /** * Instance of the definition object to use when block. + * @type HTMLPurifier_ChildDef_Optional */ public $block; + /** + * @type string + */ public $type = 'chameleon'; /** - * @param $inline List of elements to allow when inline. - * @param $block List of elements to allow when block. + * @param array $inline List of elements to allow when inline. + * @param array $block List of elements to allow when block. */ - public function __construct($inline, $block) { + public function __construct($inline, $block) + { $this->inline = new HTMLPurifier_ChildDef_Optional($inline); - $this->block = new HTMLPurifier_ChildDef_Optional($block); + $this->block = new HTMLPurifier_ChildDef_Optional($block); $this->elements = $this->block->elements; } - public function validateChildren($tokens_of_children, $config, $context) { + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function validateChildren($tokens_of_children, $config, $context) + { if ($context->get('IsInline') === false) { return $this->block->validateChildren( - $tokens_of_children, $config, $context); + $tokens_of_children, + $config, + $context + ); } else { return $this->inline->validateChildren( - $tokens_of_children, $config, $context); + $tokens_of_children, + $config, + $context + ); } } } diff --git a/library/HTMLPurifier/ChildDef/Custom.php b/library/HTMLPurifier/ChildDef/Custom.php index b68047b4..06193dc2 100644 --- a/library/HTMLPurifier/ChildDef/Custom.php +++ b/library/HTMLPurifier/ChildDef/Custom.php @@ -8,28 +8,42 @@ */ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef { + /** + * @type string + */ public $type = 'custom'; + + /** + * @type bool + */ public $allow_empty = false; + /** - * Allowed child pattern as defined by the DTD + * Allowed child pattern as defined by the DTD. + * @type string */ public $dtd_regex; + /** - * PCRE regex derived from $dtd_regex - * @private + * PCRE regex derived from $dtd_regex. + * @type string */ private $_pcre_regex; + /** * @param $dtd_regex Allowed child pattern from the DTD */ - public function __construct($dtd_regex) { + public function __construct($dtd_regex) + { $this->dtd_regex = $dtd_regex; $this->_compileRegex(); } + /** * Compiles the PCRE regex from a DTD regex ($dtd_regex to $_pcre_regex) */ - protected function _compileRegex() { + protected function _compileRegex() + { $raw = str_replace(' ', '', $this->dtd_regex); if ($raw{0} != '(') { $raw = "($raw)"; @@ -57,11 +71,21 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef $this->_pcre_regex = $reg; } - public function validateChildren($tokens_of_children, $config, $context) { + + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function validateChildren($tokens_of_children, $config, $context) + { $list_of_children = ''; $nesting = 0; // depth into the nest foreach ($tokens_of_children as $token) { - if (!empty($token->is_whitespace)) continue; + if (!empty($token->is_whitespace)) { + continue; + } $is_child = ($nesting == 0); // direct @@ -79,11 +103,10 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef $list_of_children = ',' . rtrim($list_of_children, ','); $okay = preg_match( - '/^,?'.$this->_pcre_regex.'$/', + '/^,?' . $this->_pcre_regex . '$/', $list_of_children ); - - return (bool) $okay; + return (bool)$okay; } } diff --git a/library/HTMLPurifier/ChildDef/Empty.php b/library/HTMLPurifier/ChildDef/Empty.php index 13171f66..a6e0ea55 100644 --- a/library/HTMLPurifier/ChildDef/Empty.php +++ b/library/HTMLPurifier/ChildDef/Empty.php @@ -9,10 +9,28 @@ */ class HTMLPurifier_ChildDef_Empty extends HTMLPurifier_ChildDef { + /** + * @type bool + */ public $allow_empty = true; + + /** + * @type string + */ public $type = 'empty'; - public function __construct() {} - public function validateChildren($tokens_of_children, $config, $context) { + + public function __construct() + { + } + + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($tokens_of_children, $config, $context) + { return array(); } } diff --git a/library/HTMLPurifier/ChildDef/List.php b/library/HTMLPurifier/ChildDef/List.php index cdaa2893..c9b021b5 100644 --- a/library/HTMLPurifier/ChildDef/List.php +++ b/library/HTMLPurifier/ChildDef/List.php @@ -5,16 +5,32 @@ */ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef { + /** + * @type string + */ public $type = 'list'; + /** + * @type array + */ // lying a little bit, so that we can handle ul and ol ourselves // XXX: This whole business with 'wrap' is all a bit unsatisfactory public $elements = array('li' => true, 'ul' => true, 'ol' => true); - public function validateChildren($tokens_of_children, $config, $context) { + + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($tokens_of_children, $config, $context) + { // Flag for subclasses $this->whitespace = false; // if there are no tokens, delete parent node - if (empty($tokens_of_children)) return false; + if (empty($tokens_of_children)) { + return false; + } // the new set of children $result = array(); @@ -62,7 +78,7 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef $result[] = new HTMLPurifier_Token_Start('li'); } else { // backtrack until found - while(true) { + while (true) { $t = array_pop($result); if ($t instanceof HTMLPurifier_Token_End) { // XXX actually, these invariants could very plausibly be violated @@ -84,7 +100,10 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef break; } else { if (!$t->is_whitespace) { - trigger_error("Only whitespace present invariant violated in List ChildDef", E_USER_ERROR); + trigger_error( + "Only whitespace present invariant violated in List ChildDef", + E_USER_ERROR + ); return false; } } @@ -108,11 +127,15 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef if ($need_close_li) { $result[] = new HTMLPurifier_Token_End('li'); } - if (empty($result)) return false; + if (empty($result)) { + return false; + } if ($all_whitespace) { return false; } - if ($tokens_of_children == $result) return true; + if ($tokens_of_children == $result) { + return true; + } return $result; } } diff --git a/library/HTMLPurifier/ChildDef/Optional.php b/library/HTMLPurifier/ChildDef/Optional.php index 32bcb989..49dad0d1 100644 --- a/library/HTMLPurifier/ChildDef/Optional.php +++ b/library/HTMLPurifier/ChildDef/Optional.php @@ -9,15 +9,34 @@ */ class HTMLPurifier_ChildDef_Optional extends HTMLPurifier_ChildDef_Required { + /** + * @type bool + */ public $allow_empty = true; + + /** + * @type string + */ public $type = 'optional'; - public function validateChildren($tokens_of_children, $config, $context) { + + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($tokens_of_children, $config, $context) + { $result = parent::validateChildren($tokens_of_children, $config, $context); // we assume that $tokens_of_children is not modified if ($result === false) { - if (empty($tokens_of_children)) return true; - elseif ($this->whitespace) return $tokens_of_children; - else return array(); + if (empty($tokens_of_children)) { + return true; + } elseif ($this->whitespace) { + return $tokens_of_children; + } else { + return array(); + } } return $result; } diff --git a/library/HTMLPurifier/ChildDef/Required.php b/library/HTMLPurifier/ChildDef/Required.php index 4889f249..eaa85d4a 100644 --- a/library/HTMLPurifier/ChildDef/Required.php +++ b/library/HTMLPurifier/ChildDef/Required.php @@ -7,17 +7,21 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef { /** * Lookup table of allowed elements. - * @public + * @type array */ public $elements = array(); + /** * Whether or not the last passed node was all whitespace. + * @type bool */ protected $whitespace = false; + /** - * @param $elements List of allowed element names (lowercase). + * @param array|string $elements List of allowed element names (lowercase). */ - public function __construct($elements) { + public function __construct($elements) + { if (is_string($elements)) { $elements = str_replace(' ', '', $elements); $elements = explode('|', $elements); @@ -27,19 +31,39 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef $elements = array_flip($elements); foreach ($elements as $i => $x) { $elements[$i] = true; - if (empty($i)) unset($elements[$i]); // remove blank + if (empty($i)) { + unset($elements[$i]); + } // remove blank } } $this->elements = $elements; } + + /** + * @type bool + */ public $allow_empty = false; + + /** + * @type string + */ public $type = 'required'; - public function validateChildren($tokens_of_children, $config, $context) { + + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($tokens_of_children, $config, $context) + { // Flag for subclasses $this->whitespace = false; // if there are no tokens, delete parent node - if (empty($tokens_of_children)) return false; + if (empty($tokens_of_children)) { + return false; + } // the new set of children $result = array(); @@ -104,12 +128,16 @@ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef // drop silently } } - if (empty($result)) return false; + if (empty($result)) { + return false; + } if ($all_whitespace) { $this->whitespace = true; return false; } - if ($tokens_of_children == $result) return true; + if ($tokens_of_children == $result) { + return true; + } return $result; } } diff --git a/library/HTMLPurifier/ChildDef/StrictBlockquote.php b/library/HTMLPurifier/ChildDef/StrictBlockquote.php index dfae8a6e..89831a71 100644 --- a/library/HTMLPurifier/ChildDef/StrictBlockquote.php +++ b/library/HTMLPurifier/ChildDef/StrictBlockquote.php @@ -5,23 +5,51 @@ */ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Required { + /** + * @type array + */ protected $real_elements; + + /** + * @type array + */ protected $fake_elements; + + /** + * @type bool + */ public $allow_empty = true; + + /** + * @type string + */ public $type = 'strictblockquote'; + + /** + * @type bool + */ protected $init = false; /** + * @param HTMLPurifier_Config $config + * @return array * @note We don't want MakeWellFormed to auto-close inline elements since * they might be allowed. */ - public function getAllowedElements($config) { + public function getAllowedElements($config) + { $this->init($config); return $this->fake_elements; } - public function validateChildren($tokens_of_children, $config, $context) { - + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($tokens_of_children, $config, $context) + { $this->init($config); // trick the parent class into thinking it allows more @@ -29,12 +57,16 @@ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Requi $result = parent::validateChildren($tokens_of_children, $config, $context); $this->elements = $this->real_elements; - if ($result === false) return array(); - if ($result === true) $result = $tokens_of_children; + if ($result === false) { + return array(); + } + if ($result === true) { + $result = $tokens_of_children; + } $def = $config->getHTMLDefinition(); $block_wrap_start = new HTMLPurifier_Token_Start($def->info_block_wrapper); - $block_wrap_end = new HTMLPurifier_Token_End( $def->info_block_wrapper); + $block_wrap_end = new HTMLPurifier_Token_End($def->info_block_wrapper); $is_inline = false; $depth = 0; $ret = array(); @@ -45,13 +77,11 @@ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Requi // ifs are nested for readability if (!$is_inline) { if (!$depth) { - if ( - ($token instanceof HTMLPurifier_Token_Text && !$token->is_whitespace) || - (!$token instanceof HTMLPurifier_Token_Text && !isset($this->elements[$token->name])) - ) { + if (($token instanceof HTMLPurifier_Token_Text && !$token->is_whitespace) || + (!$token instanceof HTMLPurifier_Token_Text && !isset($this->elements[$token->name]))) { $is_inline = true; $ret[] = $block_wrap_start; - } + } } } else { if (!$depth) { @@ -66,14 +96,24 @@ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Requi } } $ret[] = $token; - if ($token instanceof HTMLPurifier_Token_Start) $depth++; - if ($token instanceof HTMLPurifier_Token_End) $depth--; + if ($token instanceof HTMLPurifier_Token_Start) { + $depth++; + } + if ($token instanceof HTMLPurifier_Token_End) { + $depth--; + } + } + if ($is_inline) { + $ret[] = $block_wrap_end; } - if ($is_inline) $ret[] = $block_wrap_end; return $ret; } - private function init($config) { + /** + * @param HTMLPurifier_Config $config + */ + private function init($config) + { if (!$this->init) { $def = $config->getHTMLDefinition(); // allow all inline elements diff --git a/library/HTMLPurifier/ChildDef/Table.php b/library/HTMLPurifier/ChildDef/Table.php index 26d184d2..cd1de1d4 100644 --- a/library/HTMLPurifier/ChildDef/Table.php +++ b/library/HTMLPurifier/ChildDef/Table.php @@ -31,13 +31,44 @@ */ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef { + /** + * @type bool + */ public $allow_empty = false; + + /** + * @type string + */ public $type = 'table'; - public $elements = array('tr' => true, 'tbody' => true, 'thead' => true, - 'tfoot' => true, 'caption' => true, 'colgroup' => true, 'col' => true); - public function __construct() {} - public function validateChildren($tokens_of_children, $config, $context) { - if (empty($tokens_of_children)) return false; + + /** + * @type array + */ + public $elements = array( + 'tr' => true, + 'tbody' => true, + 'thead' => true, + 'tfoot' => true, + 'caption' => true, + 'colgroup' => true, + 'col' => true + ); + + public function __construct() + { + } + + /** + * @param array $tokens_of_children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($tokens_of_children, $config, $context) + { + if (empty($tokens_of_children)) { + return false; + } // this ensures that the loop gets run one last time before closing // up. It's a little bit of a hack, but it works! Just make sure you @@ -46,23 +77,23 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef // only one of these elements is allowed in a table $caption = false; - $thead = false; - $tfoot = false; + $thead = false; + $tfoot = false; // as many of these as you want - $cols = array(); + $cols = array(); $content = array(); $nesting = 0; // current depth so we can determine nodes $is_collecting = false; // are we globbing together tokens to package - // into one of the collectors? + // into one of the collectors? $collection = array(); // collected nodes // INVARIANT: if $is_collecting, then !empty($collection) // The converse does NOT hold, see [WHITESPACE] $tag_index = 0; // the first node might be whitespace, - // so this tells us where the start tag is + // so this tells us where the start tag is $tbody_mode = false; // if true, then we need to wrap any stray - // s with a . + // s with a . foreach ($tokens_of_children as $token) { $is_child = ($nesting == 0); @@ -88,7 +119,9 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef $content[] = $collection; break; case 'caption': - if ($caption !== false) break; + if ($caption !== false) { + break; + } $caption = $collection; break; case 'thead': @@ -116,11 +149,11 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef // doesn't float an extra tfoot to the // bottom like it does for the first one. $collection[$tag_index]->name = 'tbody'; - $collection[count($collection)-1]->name = 'tbody'; + $collection[count($collection) - 1]->name = 'tbody'; $content[] = $collection; } break; - case 'colgroup': + case 'colgroup': $cols[] = $collection; break; } @@ -134,7 +167,9 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef } // terminate - if ($token === false) break; + if ($token === false) { + break; + } if ($is_child) { // determine what we're dealing with @@ -147,7 +182,7 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef $tag_index = 0; continue; } - switch($token->name) { + switch ($token->name) { case 'caption': case 'colgroup': case 'thead': @@ -172,7 +207,9 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef } } - if (empty($content)) return false; + if (empty($content)) { + return false; + } // INVARIANT: all members of content are non-empty. This can // be shown by observing when things are pushed onto content: // they are only ever pushed when is_collecting is true, and @@ -180,10 +217,20 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef // that collections are non-empty when is_collecting is true. $ret = array(); - if ($caption !== false) $ret = array_merge($ret, $caption); - if ($cols !== false) foreach ($cols as $token_array) $ret = array_merge($ret, $token_array); - if ($thead !== false) $ret = array_merge($ret, $thead); - if ($tfoot !== false) $ret = array_merge($ret, $tfoot); + if ($caption !== false) { + $ret = array_merge($ret, $caption); + } + if ($cols !== false) { + foreach ($cols as $token_array) { + $ret = array_merge($ret, $token_array); + } + } + if ($thead !== false) { + $ret = array_merge($ret, $thead); + } + if ($tfoot !== false) { + $ret = array_merge($ret, $tfoot); + } if ($tbody_mode) { // a little tricky, since the start of the collection may be @@ -228,7 +275,7 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef } } - if (!empty($collection) && $is_collecting == false){ + if (!empty($collection) && $is_collecting == false) { // grab the trailing space $ret = array_merge($ret, $collection); } diff --git a/library/HTMLPurifier/Config.php b/library/HTMLPurifier/Config.php index c5db8de9..4b2f439e 100644 --- a/library/HTMLPurifier/Config.php +++ b/library/HTMLPurifier/Config.php @@ -19,79 +19,89 @@ class HTMLPurifier_Config /** * HTML Purifier's version + * @type string */ public $version = '4.5.0'; /** - * @var bool indicator whether or not to automatically finalize - * the object if a read operation is done + * Whether or not to automatically finalize + * the object if a read operation is done. + * @type bool */ public $autoFinalize = true; // protected member variables /** - * Namespace indexed array of serials for specific namespaces (see - * getSerial() for more info). + * Namespace indexed array of serials for specific namespaces. + * @see getSerial() for more info. + * @type string[] */ protected $serials = array(); /** - * Serial for entire configuration object + * Serial for entire configuration object. + * @type string */ protected $serial; /** - * Parser for variables + * Parser for variables. + * @type HTMLPurifier_VarParser_Flexible */ protected $parser = null; /** - * Reference HTMLPurifier_ConfigSchema for value checking + * Reference HTMLPurifier_ConfigSchema for value checking. + * @type HTMLPurifier_ConfigSchema * @note This is public for introspective purposes. Please don't * abuse! */ public $def; /** - * @var HTMLPurifier_Definition[] Indexed array of definitions + * Indexed array of definitions. + * @type HTMLPurifier_Definition[] */ protected $definitions; /** - * Bool indicator whether or not config is finalized + * Whether or not config is finalized. + * @type bool */ protected $finalized = false; /** * Property list containing configuration directives. + * @type array */ protected $plist; /** - * Whether or not a set is taking place due to an - * alias lookup. + * Whether or not a set is taking place due to an alias lookup. + * @type bool */ private $aliasMode; /** - * Set to false if you do not want line and file numbers in errors + * Set to false if you do not want line and file numbers in errors. * (useful when unit testing). This will also compress some errors * and exceptions. + * @type bool */ public $chatty = true; /** * Current lock; only gets to this namespace are allowed. + * @type string */ private $lock; /** * Constructor - * - * @param HTMLPurifier_ConfigSchema $definition ConfigSchema that defines + * @param HTMLPurifier_ConfigSchema $definition ConfigSchema that defines * what directives are allowed. - * @param mixed $parent + * @param HTMLPurifier_PropertyList $parent */ public function __construct($definition, $parent = null) { @@ -103,13 +113,11 @@ class HTMLPurifier_Config /** * Convenience constructor that creates a config object based on a mixed var - * * @param mixed $config Variable that defines the state of the config * object. Can be: a HTMLPurifier_Config() object, * an array of directives based on loadArray(), * or a string filename of an ini file. * @param HTMLPurifier_ConfigSchema $schema Schema object - * * @return HTMLPurifier_Config Configured object */ public static function create($config, $schema = null) @@ -125,17 +133,13 @@ class HTMLPurifier_Config } if (is_string($config)) { $ret->loadIni($config); - } - elseif (is_array($config)) $ret->loadArray($config); + } elseif (is_array($config)) $ret->loadArray($config); return $ret; } /** * Creates a new config object that inherits from a previous one. - * - * @param HTMLPurifier_Config $config Configuration object to inherit - * from. - * + * @param HTMLPurifier_Config $config Configuration object to inherit from. * @return HTMLPurifier_Config object with $config as its parent. */ public static function inherit(HTMLPurifier_Config $config) @@ -195,7 +199,9 @@ class HTMLPurifier_Config if ($ns !== $this->lock) { $this->triggerError( 'Cannot get value of namespace ' . $ns . ' when lock for ' . - $this->lock . ' is active, this probably indicates a Definition setup method is accessing directives that are not within its namespace', + $this->lock . + ' is active, this probably indicates a Definition setup method ' . + 'is accessing directives that are not within its namespace', E_USER_ERROR ); return; @@ -384,7 +390,9 @@ class HTMLPurifier_Config private function _listify($lookup) { $list = array(); - foreach ($lookup as $name => $b) $list[] = $name; + foreach ($lookup as $name => $b) { + $list[] = $name; + } return implode(', ', $list); } @@ -400,7 +408,7 @@ class HTMLPurifier_Config * maybeGetRawHTMLDefinition, which is more explicitly * named, instead. * - * @return mixed + * @return HTMLPurifier_HTMLDefinition */ public function getHTMLDefinition($raw = false, $optimized = false) { @@ -419,7 +427,7 @@ class HTMLPurifier_Config * maybeGetRawCSSDefinition, which is more explicitly * named, instead. * - * @return mixed + * @return HTMLPurifier_CSSDefinition */ public function getCSSDefinition($raw = false, $optimized = false) { @@ -438,7 +446,7 @@ class HTMLPurifier_Config * maybeGetRawURIDefinition, which is more explicitly * named, instead. * - * @return mixed + * @return HTMLPurifier_URIDefinition */ public function getURIDefinition($raw = false, $optimized = false) { @@ -460,7 +468,7 @@ class HTMLPurifier_Config * maybe semantics is the "right thing to do." * * @throws HTMLPurifier_Exception - * @return mixed + * @return HTMLPurifier_Definition */ public function getDefinition($type, $raw = false, $optimized = false) { @@ -542,8 +550,12 @@ class HTMLPurifier_Config } if ($def->optimized !== $optimized) { $msg = $optimized ? "optimized" : "unoptimized"; - $extra = $this->chatty ? " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)" : ""; - throw new HTMLPurifier_Exception("Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra); + $extra = $this->chatty ? + " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)" + : ""; + throw new HTMLPurifier_Exception( + "Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra + ); } } // check if definition was in memory @@ -576,7 +588,17 @@ class HTMLPurifier_Config if (!$optimized) { if (!is_null($this->get($type . '.DefinitionID'))) { if ($this->chatty) { - $this->triggerError("Due to a documentation error in previous version of HTML Purifier, your definitions are not being cached. If this is OK, you can remove the %$type.DefinitionRev and %$type.DefinitionID declaration. Otherwise, modify your code to use maybeGetRawDefinition, and test if the returned value is null before making any edits (if it is null, that means that a cached version is available, and no raw operations are necessary). See Customize for more details", E_USER_WARNING); + $this->triggerError( + 'Due to a documentation error in previous version of HTML Purifier, your ' . + 'definitions are not being cached. If this is OK, you can remove the ' . + '%$type.DefinitionRev and %$type.DefinitionID declaration. Otherwise, ' . + 'modify your code to use maybeGetRawDefinition, and test if the returned ' . + 'value is null before making any edits (if it is null, that means that a ' . + 'cached version is available, and no raw operations are necessary). See ' . + '' . + 'Customize for more details', + E_USER_WARNING + ); } else { $this->triggerError( "Useless DefinitionID declaration", diff --git a/library/HTMLPurifier/ConfigSchema.php b/library/HTMLPurifier/ConfigSchema.php index fadf7a58..bfbb0f92 100644 --- a/library/HTMLPurifier/ConfigSchema.php +++ b/library/HTMLPurifier/ConfigSchema.php @@ -3,21 +3,24 @@ /** * Configuration definition, defines directives and their defaults. */ -class HTMLPurifier_ConfigSchema { - +class HTMLPurifier_ConfigSchema +{ /** * Defaults of the directives and namespaces. + * @type array * @note This shares the exact same structure as HTMLPurifier_Config::$conf */ public $defaults = array(); /** * The default property list. Do not edit this property list. + * @type array */ public $defaultPlist; /** - * Definition of the directives. The structure of this is: + * Definition of the directives. + * The structure of this is: * * array( * 'Namespace' => array( @@ -44,22 +47,27 @@ class HTMLPurifier_ConfigSchema { * This class is friendly with HTMLPurifier_Config. If you need introspection * about the schema, you're better of using the ConfigSchema_Interchange, * which uses more memory but has much richer information. + * @type array */ public $info = array(); /** * Application-wide singleton + * @type HTMLPurifier_ConfigSchema */ - static protected $singleton; + protected static $singleton; - public function __construct() { + public function __construct() + { $this->defaultPlist = new HTMLPurifier_PropertyList(); } /** * Unserializes the default ConfigSchema. + * @return HTMLPurifier_ConfigSchema */ - public static function makeFromSerial() { + public static function makeFromSerial() + { $contents = file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'); $r = unserialize($contents); if (!$r) { @@ -71,8 +79,11 @@ class HTMLPurifier_ConfigSchema { /** * Retrieves an instance of the application-wide configuration definition. + * @param HTMLPurifier_ConfigSchema $prototype + * @return HTMLPurifier_ConfigSchema */ - public static function instance($prototype = null) { + public static function instance($prototype = null) + { if ($prototype !== null) { HTMLPurifier_ConfigSchema::$singleton = $prototype; } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) { @@ -86,17 +97,19 @@ class HTMLPurifier_ConfigSchema { * @warning Will fail of directive's namespace is defined. * @warning This method's signature is slightly different from the legacy * define() static method! Beware! - * @param $namespace Namespace the directive is in - * @param $name Key of directive - * @param $default Default value of directive - * @param $type Allowed type of the directive. See + * @param string $key Name of directive + * @param mixed $default Default value of directive + * @param string $type Allowed type of the directive. See * HTMLPurifier_DirectiveDef::$type for allowed values - * @param $allow_null Whether or not to allow null values + * @param bool $allow_null Whether or not to allow null values */ - public function add($key, $default, $type, $allow_null) { + public function add($key, $default, $type, $allow_null) + { $obj = new stdclass(); $obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type]; - if ($allow_null) $obj->allow_null = true; + if ($allow_null) { + $obj->allow_null = true; + } $this->info[$key] = $obj; $this->defaults[$key] = $default; $this->defaultPlist->set($key, $default); @@ -107,11 +120,11 @@ class HTMLPurifier_ConfigSchema { * * Directive value aliases are convenient for developers because it lets * them set a directive to several values and get the same result. - * @param $namespace Directive's namespace - * @param $name Name of Directive - * @param $aliases Hash of aliased values to the real alias + * @param string $key Name of Directive + * @param array $aliases Hash of aliased values to the real alias */ - public function addValueAliases($key, $aliases) { + public function addValueAliases($key, $aliases) + { if (!isset($this->info[$key]->aliases)) { $this->info[$key]->aliases = array(); } @@ -124,22 +137,21 @@ class HTMLPurifier_ConfigSchema { * Defines a set of allowed values for a directive. * @warning This is slightly different from the corresponding static * method definition. - * @param $namespace Namespace of directive - * @param $name Name of directive - * @param $allowed Lookup array of allowed values + * @param string $key Name of directive + * @param array $allowed Lookup array of allowed values */ - public function addAllowedValues($key, $allowed) { + public function addAllowedValues($key, $allowed) + { $this->info[$key]->allowed = $allowed; } /** * Defines a directive alias for backwards compatibility - * @param $namespace - * @param $name Directive that will be aliased - * @param $new_namespace - * @param $new_name Directive that the alias will be to + * @param string $key Directive that will be aliased + * @param string $new_key Directive that the alias will be to */ - public function addAlias($key, $new_key) { + public function addAlias($key, $new_key) + { $obj = new stdclass; $obj->key = $new_key; $obj->isAlias = true; @@ -149,7 +161,8 @@ class HTMLPurifier_ConfigSchema { /** * Replaces any stdclass that only has the type property with type integer. */ - public function postProcess() { + public function postProcess() + { foreach ($this->info as $key => $v) { if (count((array) $v) == 1) { $this->info[$key] = $v->type; @@ -158,7 +171,6 @@ class HTMLPurifier_ConfigSchema { } } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php b/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php index c05668a7..d5906cd4 100644 --- a/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php +++ b/library/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php @@ -7,7 +7,12 @@ class HTMLPurifier_ConfigSchema_Builder_ConfigSchema { - public function build($interchange) { + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @return HTMLPurifier_ConfigSchema + */ + public function build($interchange) + { $schema = new HTMLPurifier_ConfigSchema(); foreach ($interchange->directives as $d) { $schema->add( @@ -38,7 +43,6 @@ class HTMLPurifier_ConfigSchema_Builder_ConfigSchema $schema->postProcess(); return $schema; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/Builder/Xml.php b/library/HTMLPurifier/ConfigSchema/Builder/Xml.php index 244561a3..5fa56f7d 100644 --- a/library/HTMLPurifier/ConfigSchema/Builder/Xml.php +++ b/library/HTMLPurifier/ConfigSchema/Builder/Xml.php @@ -7,10 +7,21 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter { + /** + * @type HTMLPurifier_ConfigSchema_Interchange + */ protected $interchange; + + /** + * @type string + */ private $namespace; - protected function writeHTMLDiv($html) { + /** + * @param string $html + */ + protected function writeHTMLDiv($html) + { $this->startElement('div'); $purifier = HTMLPurifier::getInstance(); @@ -21,12 +32,23 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter $this->endElement(); // div } - protected function export($var) { - if ($var === array()) return 'array()'; + /** + * @param mixed $var + * @return string + */ + protected function export($var) + { + if ($var === array()) { + return 'array()'; + } return var_export($var, true); } - public function build($interchange) { + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + */ + public function build($interchange) + { // global access, only use as last resort $this->interchange = $interchange; @@ -39,19 +61,26 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter $this->buildDirective($directive); } - if ($this->namespace) $this->endElement(); // namespace + if ($this->namespace) { + $this->endElement(); + } // namespace $this->endElement(); // configdoc $this->flush(); } - public function buildDirective($directive) { - + /** + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive + */ + public function buildDirective($directive) + { // Kludge, although I suppose having a notion of a "root namespace" // certainly makes things look nicer when documentation is built. // Depends on things being sorted. if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) { - if ($this->namespace) $this->endElement(); // namespace + if ($this->namespace) { + $this->endElement(); + } // namespace $this->namespace = $directive->id->getRootNamespace(); $this->startElement('namespace'); $this->writeAttribute('id', $this->namespace); @@ -64,43 +93,52 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter $this->writeElement('name', $directive->id->getDirective()); $this->startElement('aliases'); - foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString()); + foreach ($directive->aliases as $alias) { + $this->writeElement('alias', $alias->toString()); + } $this->endElement(); // aliases $this->startElement('constraints'); - if ($directive->version) $this->writeElement('version', $directive->version); - $this->startElement('type'); - if ($directive->typeAllowsNull) $this->writeAttribute('allow-null', 'yes'); - $this->text($directive->type); - $this->endElement(); // type - if ($directive->allowed) { - $this->startElement('allowed'); - foreach ($directive->allowed as $value => $x) $this->writeElement('value', $value); - $this->endElement(); // allowed + if ($directive->version) { + $this->writeElement('version', $directive->version); + } + $this->startElement('type'); + if ($directive->typeAllowsNull) { + $this->writeAttribute('allow-null', 'yes'); + } + $this->text($directive->type); + $this->endElement(); // type + if ($directive->allowed) { + $this->startElement('allowed'); + foreach ($directive->allowed as $value => $x) { + $this->writeElement('value', $value); } - $this->writeElement('default', $this->export($directive->default)); - $this->writeAttribute('xml:space', 'preserve'); - if ($directive->external) { - $this->startElement('external'); - foreach ($directive->external as $project) $this->writeElement('project', $project); - $this->endElement(); + $this->endElement(); // allowed + } + $this->writeElement('default', $this->export($directive->default)); + $this->writeAttribute('xml:space', 'preserve'); + if ($directive->external) { + $this->startElement('external'); + foreach ($directive->external as $project) { + $this->writeElement('project', $project); } + $this->endElement(); + } $this->endElement(); // constraints if ($directive->deprecatedVersion) { $this->startElement('deprecated'); - $this->writeElement('version', $directive->deprecatedVersion); - $this->writeElement('use', $directive->deprecatedUse->toString()); + $this->writeElement('version', $directive->deprecatedVersion); + $this->writeElement('use', $directive->deprecatedUse->toString()); $this->endElement(); // deprecated } $this->startElement('description'); - $this->writeHTMLDiv($directive->description); + $this->writeHTMLDiv($directive->description); $this->endElement(); // description $this->endElement(); // directive } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/Interchange.php b/library/HTMLPurifier/ConfigSchema/Interchange.php index 91a5aa73..0e08ae8f 100644 --- a/library/HTMLPurifier/ConfigSchema/Interchange.php +++ b/library/HTMLPurifier/ConfigSchema/Interchange.php @@ -10,18 +10,23 @@ class HTMLPurifier_ConfigSchema_Interchange /** * Name of the application this schema is describing. + * @type string */ public $name; /** * Array of Directive ID => array(directive info) + * @type HTMLPurifier_ConfigSchema_Interchange_Directive[] */ public $directives = array(); /** * Adds a directive array to $directives + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive + * @throws HTMLPurifier_ConfigSchema_Exception */ - public function addDirective($directive) { + public function addDirective($directive) + { if (isset($this->directives[$i = $directive->id->toString()])) { throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine directive '$i'"); } @@ -32,11 +37,11 @@ class HTMLPurifier_ConfigSchema_Interchange * Convenience function to perform standard validation. Throws exception * on failed validation. */ - public function validate() { + public function validate() + { $validator = new HTMLPurifier_ConfigSchema_Validator(); return $validator->validate($this); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php b/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php index ac8be0d9..127a39a6 100644 --- a/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php +++ b/library/HTMLPurifier/ConfigSchema/Interchange/Directive.php @@ -7,71 +7,83 @@ class HTMLPurifier_ConfigSchema_Interchange_Directive { /** - * ID of directive, instance of HTMLPurifier_ConfigSchema_Interchange_Id. + * ID of directive. + * @type HTMLPurifier_ConfigSchema_Interchange_Id */ public $id; /** - * String type, e.g. 'integer' or 'istring'. + * Type, e.g. 'integer' or 'istring'. + * @type string */ public $type; /** * Default value, e.g. 3 or 'DefaultVal'. + * @type mixed */ public $default; /** * HTML description. + * @type string */ public $description; /** - * Boolean whether or not null is allowed as a value. + * Whether or not null is allowed as a value. + * @type bool */ public $typeAllowsNull = false; /** - * Lookup table of allowed scalar values, e.g. array('allowed' => true). + * Lookup table of allowed scalar values. + * e.g. array('allowed' => true). * Null if all values are allowed. + * @type array */ public $allowed; /** - * List of aliases for the directive, + * List of aliases for the directive. * e.g. array(new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir'))). + * @type HTMLPurifier_ConfigSchema_Interchange_Id[] */ public $aliases = array(); /** * Hash of value aliases, e.g. array('alt' => 'real'). Null if value * aliasing is disabled (necessary for non-scalar types). + * @type array */ public $valueAliases; /** * Version of HTML Purifier the directive was introduced, e.g. '1.3.1'. * Null if the directive has always existed. + * @type string */ public $version; /** - * ID of directive that supercedes this old directive, is an instance - * of HTMLPurifier_ConfigSchema_Interchange_Id. Null if not deprecated. + * ID of directive that supercedes this old directive. + * Null if not deprecated. + * @type HTMLPurifier_ConfigSchema_Interchange_Id */ public $deprecatedUse; /** * Version of HTML Purifier this directive was deprecated. Null if not * deprecated. + * @type string */ public $deprecatedVersion; /** * List of external projects this directive depends on, e.g. array('CSSTidy'). + * @type array */ public $external = array(); - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/Interchange/Id.php b/library/HTMLPurifier/ConfigSchema/Interchange/Id.php index b9b3c6f5..126f09d9 100644 --- a/library/HTMLPurifier/ConfigSchema/Interchange/Id.php +++ b/library/HTMLPurifier/ConfigSchema/Interchange/Id.php @@ -6,32 +6,53 @@ class HTMLPurifier_ConfigSchema_Interchange_Id { + /** + * @type string + */ public $key; - public function __construct($key) { + /** + * @param string $key + */ + public function __construct($key) + { $this->key = $key; } /** + * @return string * @warning This is NOT magic, to ensure that people don't abuse SPL and * cause problems for PHP 5.0 support. */ - public function toString() { + public function toString() + { return $this->key; } - public function getRootNamespace() { + /** + * @return string + */ + public function getRootNamespace() + { return substr($this->key, 0, strpos($this->key, ".")); } - public function getDirective() { + /** + * @return string + */ + public function getDirective() + { return substr($this->key, strpos($this->key, ".") + 1); } - public static function make($id) { + /** + * @param string $id + * @return HTMLPurifier_ConfigSchema_Interchange_Id + */ + public static function make($id) + { return new HTMLPurifier_ConfigSchema_Interchange_Id($id); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php b/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php index 785b72ce..655e6dd1 100644 --- a/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php +++ b/library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php @@ -5,21 +5,39 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder /** * Used for processing DEFAULT, nothing else. + * @type HTMLPurifier_VarParser */ protected $varParser; - public function __construct($varParser = null) { + /** + * @param HTMLPurifier_VarParser $varParser + */ + public function __construct($varParser = null) + { $this->varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native(); } - public static function buildFromDirectory($dir = null) { - $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); + /** + * @param string $dir + * @return HTMLPurifier_ConfigSchema_Interchange + */ + public static function buildFromDirectory($dir = null) + { + $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); $interchange = new HTMLPurifier_ConfigSchema_Interchange(); return $builder->buildDir($interchange, $dir); } - public function buildDir($interchange, $dir = null) { - if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema'; + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param string $dir + * @return HTMLPurifier_ConfigSchema_Interchange + */ + public function buildDir($interchange, $dir = null) + { + if (!$dir) { + $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema'; + } if (file_exists($dir . '/info.ini')) { $info = parse_ini_file($dir . '/info.ini'); $interchange->name = $info['name']; @@ -39,24 +57,30 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder foreach ($files as $file) { $this->buildFile($interchange, $dir . '/' . $file); } - return $interchange; } - public function buildFile($interchange, $file) { + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param string $file + */ + public function buildFile($interchange, $file) + { $parser = new HTMLPurifier_StringHashParser(); $this->build( $interchange, - new HTMLPurifier_StringHash( $parser->parseFile($file) ) + new HTMLPurifier_StringHash($parser->parseFile($file)) ); } /** * Builds an interchange object based on a hash. - * @param $interchange HTMLPurifier_ConfigSchema_Interchange object to build - * @param $hash HTMLPurifier_ConfigSchema_StringHash source data + * @param HTMLPurifier_ConfigSchema_Interchange $interchange HTMLPurifier_ConfigSchema_Interchange object to build + * @param HTMLPurifier_StringHash $hash source data + * @throws HTMLPurifier_ConfigSchema_Exception */ - public function build($interchange, $hash) { + public function build($interchange, $hash) + { if (!$hash instanceof HTMLPurifier_StringHash) { $hash = new HTMLPurifier_StringHash($hash); } @@ -75,7 +99,13 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder $this->_findUnused($hash); } - public function buildDirective($interchange, $hash) { + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param HTMLPurifier_StringHash $hash + * @throws HTMLPurifier_ConfigSchema_Exception + */ + public function buildDirective($interchange, $hash) + { $directive = new HTMLPurifier_ConfigSchema_Interchange_Directive(); // These are required elements: @@ -84,7 +114,9 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder if (isset($hash['TYPE'])) { $type = explode('/', $hash->offsetGet('TYPE')); - if (isset($type[1])) $directive->typeAllowsNull = true; + if (isset($type[1])) { + $directive->typeAllowsNull = true; + } $directive->type = $type[0]; } else { throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined"); @@ -92,7 +124,11 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder if (isset($hash['DEFAULT'])) { try { - $directive->default = $this->varParser->parse($hash->offsetGet('DEFAULT'), $directive->type, $directive->typeAllowsNull); + $directive->default = $this->varParser->parse( + $hash->offsetGet('DEFAULT'), + $directive->type, + $directive->typeAllowsNull + ); } catch (HTMLPurifier_VarParserException $e) { throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'"); } @@ -139,34 +175,45 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder /** * Evaluates an array PHP code string without array() wrapper + * @param string $contents */ - protected function evalArray($contents) { - return eval('return array('. $contents .');'); + protected function evalArray($contents) + { + return eval('return array(' . $contents . ');'); } /** * Converts an array list into a lookup array. + * @param array $array + * @return array */ - protected function lookup($array) { + protected function lookup($array) + { $ret = array(); - foreach ($array as $val) $ret[$val] = true; + foreach ($array as $val) { + $ret[$val] = true; + } return $ret; } /** * Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id * object based on a string Id. + * @param string $id + * @return HTMLPurifier_ConfigSchema_Interchange_Id */ - protected function id($id) { + protected function id($id) + { return HTMLPurifier_ConfigSchema_Interchange_Id::make($id); } /** * Triggers errors for any unused keys passed in the hash; such keys * may indicate typos, missing values, etc. - * @param $hash Instance of ConfigSchema_StringHash to check. + * @param HTMLPurifier_StringHash $hash Hash to check. */ - protected function _findUnused($hash) { + protected function _findUnused($hash) + { $accessed = $hash->getAccessed(); foreach ($hash as $k => $v) { if (!isset($accessed[$k])) { @@ -174,7 +221,6 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder } } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/Validator.php b/library/HTMLPurifier/ConfigSchema/Validator.php index f374f6a0..fb312778 100644 --- a/library/HTMLPurifier/ConfigSchema/Validator.php +++ b/library/HTMLPurifier/ConfigSchema/Validator.php @@ -12,36 +12,48 @@ class HTMLPurifier_ConfigSchema_Validator { /** - * Easy to access global objects. + * @type HTMLPurifier_ConfigSchema_Interchange */ - protected $interchange, $aliases; + protected $interchange; + + /** + * @type array + */ + protected $aliases; /** * Context-stack to provide easy to read error messages. + * @type array */ protected $context = array(); /** - * HTMLPurifier_VarParser to test default's type. + * to test default's type. + * @type HTMLPurifier_VarParser */ protected $parser; - public function __construct() { + public function __construct() + { $this->parser = new HTMLPurifier_VarParser(); } /** - * Validates a fully-formed interchange object. Throws an - * HTMLPurifier_ConfigSchema_Exception if there's a problem. + * Validates a fully-formed interchange object. + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @return bool */ - public function validate($interchange) { + public function validate($interchange) + { $this->interchange = $interchange; $this->aliases = array(); // PHP is a bit lax with integer <=> string conversions in // arrays, so we don't use the identical !== comparison foreach ($interchange->directives as $i => $directive) { $id = $directive->id->toString(); - if ($i != $id) $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'"); + if ($i != $id) { + $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'"); + } $this->validateDirective($directive); } return true; @@ -49,8 +61,10 @@ class HTMLPurifier_ConfigSchema_Validator /** * Validates a HTMLPurifier_ConfigSchema_Interchange_Id object. + * @param HTMLPurifier_ConfigSchema_Interchange_Id $id */ - public function validateId($id) { + public function validateId($id) + { $id_string = $id->toString(); $this->context[] = "id '$id_string'"; if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) { @@ -67,8 +81,10 @@ class HTMLPurifier_ConfigSchema_Validator /** * Validates a HTMLPurifier_ConfigSchema_Interchange_Directive object. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d */ - public function validateDirective($d) { + public function validateDirective($d) + { $id = $d->id->toString(); $this->context[] = "directive '$id'"; $this->validateId($d->id); @@ -108,9 +124,13 @@ class HTMLPurifier_ConfigSchema_Validator /** * Extra validation if $allowed member variable of * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d */ - public function validateDirectiveAllowed($d) { - if (is_null($d->allowed)) return; + public function validateDirectiveAllowed($d) + { + if (is_null($d->allowed)) { + return; + } $this->with($d, 'allowed') ->assertNotEmpty() ->assertIsLookup(); // handled by InterchangeBuilder @@ -119,7 +139,9 @@ class HTMLPurifier_ConfigSchema_Validator } $this->context[] = 'allowed'; foreach ($d->allowed as $val => $x) { - if (!is_string($val)) $this->error("value $val", 'must be a string'); + if (!is_string($val)) { + $this->error("value $val", 'must be a string'); + } } array_pop($this->context); } @@ -127,15 +149,23 @@ class HTMLPurifier_ConfigSchema_Validator /** * Extra validation if $valueAliases member variable of * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d */ - public function validateDirectiveValueAliases($d) { - if (is_null($d->valueAliases)) return; + public function validateDirectiveValueAliases($d) + { + if (is_null($d->valueAliases)) { + return; + } $this->with($d, 'valueAliases') ->assertIsArray(); // handled by InterchangeBuilder $this->context[] = 'valueAliases'; foreach ($d->valueAliases as $alias => $real) { - if (!is_string($alias)) $this->error("alias $alias", 'must be a string'); - if (!is_string($real)) $this->error("alias target $real from alias '$alias'", 'must be a string'); + if (!is_string($alias)) { + $this->error("alias $alias", 'must be a string'); + } + if (!is_string($real)) { + $this->error("alias target $real from alias '$alias'", 'must be a string'); + } if ($alias === $real) { $this->error("alias '$alias'", "must not be an alias to itself"); } @@ -155,8 +185,10 @@ class HTMLPurifier_ConfigSchema_Validator /** * Extra validation if $aliases member variable of * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d */ - public function validateDirectiveAliases($d) { + public function validateDirectiveAliases($d) + { $this->with($d, 'aliases') ->assertIsArray(); // handled by InterchangeBuilder $this->context[] = 'aliases'; @@ -180,27 +212,37 @@ class HTMLPurifier_ConfigSchema_Validator /** * Convenience function for generating HTMLPurifier_ConfigSchema_ValidatorAtom * for validating simple member variables of objects. + * @param $obj + * @param $member + * @return HTMLPurifier_ConfigSchema_ValidatorAtom */ - protected function with($obj, $member) { + protected function with($obj, $member) + { return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member); } /** * Emits an error, providing helpful context. + * @throws HTMLPurifier_ConfigSchema_Exception */ - protected function error($target, $msg) { - if ($target !== false) $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext(); - else $prefix = ucfirst($this->getFormattedContext()); + protected function error($target, $msg) + { + if ($target !== false) { + $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext(); + } else { + $prefix = ucfirst($this->getFormattedContext()); + } throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg)); } /** * Returns a formatted context string. + * @return string */ - protected function getFormattedContext() { + protected function getFormattedContext() + { return implode(' in ', array_reverse($this->context)); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ConfigSchema/ValidatorAtom.php b/library/HTMLPurifier/ConfigSchema/ValidatorAtom.php index b95aea18..c9aa3644 100644 --- a/library/HTMLPurifier/ConfigSchema/ValidatorAtom.php +++ b/library/HTMLPurifier/ConfigSchema/ValidatorAtom.php @@ -8,59 +8,123 @@ */ class HTMLPurifier_ConfigSchema_ValidatorAtom { + /** + * @type string + */ + protected $context; - protected $context, $obj, $member, $contents; + /** + * @type object + */ + protected $obj; - public function __construct($context, $obj, $member) { - $this->context = $context; - $this->obj = $obj; - $this->member = $member; - $this->contents =& $obj->$member; + /** + * @type string + */ + protected $member; + + /** + * @type mixed + */ + protected $contents; + + public function __construct($context, $obj, $member) + { + $this->context = $context; + $this->obj = $obj; + $this->member = $member; + $this->contents =& $obj->$member; } - public function assertIsString() { - if (!is_string($this->contents)) $this->error('must be a string'); + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsString() + { + if (!is_string($this->contents)) { + $this->error('must be a string'); + } return $this; } - public function assertIsBool() { - if (!is_bool($this->contents)) $this->error('must be a boolean'); + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsBool() + { + if (!is_bool($this->contents)) { + $this->error('must be a boolean'); + } return $this; } - public function assertIsArray() { - if (!is_array($this->contents)) $this->error('must be an array'); + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsArray() + { + if (!is_array($this->contents)) { + $this->error('must be an array'); + } return $this; } - public function assertNotNull() { - if ($this->contents === null) $this->error('must not be null'); + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertNotNull() + { + if ($this->contents === null) { + $this->error('must not be null'); + } return $this; } - public function assertAlnum() { + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertAlnum() + { $this->assertIsString(); - if (!ctype_alnum($this->contents)) $this->error('must be alphanumeric'); + if (!ctype_alnum($this->contents)) { + $this->error('must be alphanumeric'); + } return $this; } - public function assertNotEmpty() { - if (empty($this->contents)) $this->error('must not be empty'); + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertNotEmpty() + { + if (empty($this->contents)) { + $this->error('must not be empty'); + } return $this; } - public function assertIsLookup() { + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsLookup() + { $this->assertIsArray(); foreach ($this->contents as $v) { - if ($v !== true) $this->error('must be a lookup array'); + if ($v !== true) { + $this->error('must be a lookup array'); + } } return $this; } - protected function error($msg) { + /** + * @param string $msg + * @throws HTMLPurifier_ConfigSchema_Exception + */ + protected function error($msg) + { throw new HTMLPurifier_ConfigSchema_Exception(ucfirst($this->member) . ' in ' . $this->context . ' ' . $msg); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ContentSets.php b/library/HTMLPurifier/ContentSets.php index 3b6e96f5..543e3f8f 100644 --- a/library/HTMLPurifier/ContentSets.php +++ b/library/HTMLPurifier/ContentSets.php @@ -7,35 +7,42 @@ class HTMLPurifier_ContentSets { /** - * List of content set strings (pipe seperators) indexed by name. + * List of content set strings (pipe separators) indexed by name. + * @type array */ public $info = array(); /** * List of content set lookups (element => true) indexed by name. + * @type array * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets */ public $lookup = array(); /** - * Synchronized list of defined content sets (keys of info) + * Synchronized list of defined content sets (keys of info). + * @type array */ protected $keys = array(); /** - * Synchronized list of defined content values (values of info) + * Synchronized list of defined content values (values of info). + * @type array */ protected $values = array(); /** * Merges in module's content sets, expands identifiers in the content * sets and populates the keys, values and lookup member variables. - * @param $modules List of HTMLPurifier_HTMLModule + * @param HTMLPurifier_HTMLModule[] $modules List of HTMLPurifier_HTMLModule */ - public function __construct($modules) { - if (!is_array($modules)) $modules = array($modules); + public function __construct($modules) + { + if (!is_array($modules)) { + $modules = array($modules); + } // populate content_sets based on module hints // sorry, no way of overloading - foreach ($modules as $module_i => $module) { + foreach ($modules as $module) { foreach ($module->content_sets as $key => $value) { $temp = $this->convertToLookup($value); if (isset($this->lookup[$key])) { @@ -70,11 +77,14 @@ class HTMLPurifier_ContentSets /** * Accepts a definition; generates and assigns a ChildDef for it - * @param $def HTMLPurifier_ElementDef reference - * @param $module Module that defined the ElementDef + * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef reference + * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef */ - public function generateChildDef(&$def, $module) { - if (!empty($def->child)) return; // already done! + public function generateChildDef(&$def, $module) + { + if (!empty($def->child)) { // already done! + return; + } $content_model = $def->content_model; if (is_string($content_model)) { // Assume that $this->keys is alphanumeric @@ -89,7 +99,8 @@ class HTMLPurifier_ContentSets $def->child = $this->getChildDef($def, $module); } - public function generateChildDefCallback($matches) { + public function generateChildDefCallback($matches) + { return $this->info[$matches[0]]; } @@ -98,10 +109,12 @@ class HTMLPurifier_ContentSets * member variables in HTMLPurifier_ElementDef * @note This will also defer to modules for custom HTMLPurifier_ChildDef * subclasses that need content set expansion - * @param $def HTMLPurifier_ElementDef to have ChildDef extracted + * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef to have ChildDef extracted + * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef * @return HTMLPurifier_ChildDef corresponding to ElementDef */ - public function getChildDef($def, $module) { + public function getChildDef($def, $module) + { $value = $def->content_model; if (is_object($value)) { trigger_error( @@ -126,7 +139,9 @@ class HTMLPurifier_ContentSets if ($module->defines_child_def) { // save a func call $return = $module->getChildDef($def); } - if ($return !== false) return $return; + if ($return !== false) { + return $return; + } // error-out trigger_error( 'Could not determine which ChildDef class to instantiate', @@ -138,18 +153,18 @@ class HTMLPurifier_ContentSets /** * Converts a string list of elements separated by pipes into * a lookup array. - * @param $string List of elements - * @return Lookup array of elements + * @param string $string List of elements + * @return array Lookup array of elements */ - protected function convertToLookup($string) { + protected function convertToLookup($string) + { $array = explode('|', str_replace(' ', '', $string)); $ret = array(); - foreach ($array as $i => $k) { + foreach ($array as $k) { $ret[$k] = true; } return $ret; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Context.php b/library/HTMLPurifier/Context.php index 9ddf0c54..8cc443f0 100644 --- a/library/HTMLPurifier/Context.php +++ b/library/HTMLPurifier/Context.php @@ -12,18 +12,22 @@ class HTMLPurifier_Context /** * Private array that stores the references. + * @type array */ private $_storage = array(); /** * Registers a variable into the context. - * @param $name String name - * @param $ref Reference to variable to be registered + * @param string $name String name + * @param mixed $ref Reference to variable to be registered */ - public function register($name, &$ref) { + public function register($name, &$ref) + { if (isset($this->_storage[$name])) { - trigger_error("Name $name produces collision, cannot re-register", - E_USER_ERROR); + trigger_error( + "Name $name produces collision, cannot re-register", + E_USER_ERROR + ); return; } $this->_storage[$name] =& $ref; @@ -31,14 +35,18 @@ class HTMLPurifier_Context /** * Retrieves a variable reference from the context. - * @param $name String name - * @param $ignore_error Boolean whether or not to ignore error + * @param string $name String name + * @param bool $ignore_error Boolean whether or not to ignore error + * @return mixed */ - public function &get($name, $ignore_error = false) { + public function &get($name, $ignore_error = false) + { if (!isset($this->_storage[$name])) { if (!$ignore_error) { - trigger_error("Attempted to retrieve non-existent variable $name", - E_USER_ERROR); + trigger_error( + "Attempted to retrieve non-existent variable $name", + E_USER_ERROR + ); } $var = null; // so we can return by reference return $var; @@ -47,13 +55,16 @@ class HTMLPurifier_Context } /** - * Destorys a variable in the context. - * @param $name String name + * Destroys a variable in the context. + * @param string $name String name */ - public function destroy($name) { + public function destroy($name) + { if (!isset($this->_storage[$name])) { - trigger_error("Attempted to destroy non-existent variable $name", - E_USER_ERROR); + trigger_error( + "Attempted to destroy non-existent variable $name", + E_USER_ERROR + ); return; } unset($this->_storage[$name]); @@ -61,22 +72,24 @@ class HTMLPurifier_Context /** * Checks whether or not the variable exists. - * @param $name String name + * @param string $name String name + * @return bool */ - public function exists($name) { + public function exists($name) + { return isset($this->_storage[$name]); } /** * Loads a series of variables from an associative array - * @param $context_array Assoc array of variables to load + * @param array $context_array Assoc array of variables to load */ - public function loadArray($context_array) { + public function loadArray($context_array) + { foreach ($context_array as $key => $discard) { $this->register($key, $context_array[$key]); } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Definition.php b/library/HTMLPurifier/Definition.php index c7f82eba..bc6d4336 100644 --- a/library/HTMLPurifier/Definition.php +++ b/library/HTMLPurifier/Definition.php @@ -9,6 +9,7 @@ abstract class HTMLPurifier_Definition /** * Has setup() been called yet? + * @type bool */ public $setup = false; @@ -20,31 +21,35 @@ abstract class HTMLPurifier_Definition * is used and any writes to the raw definition object are short * circuited. See enduser-customize.html for the high-level * picture. + * @type bool */ public $optimized = null; /** * What type of definition is it? + * @type string */ public $type; /** * Sets up the definition object into the final form, something * not done by the constructor - * @param $config HTMLPurifier_Config instance + * @param HTMLPurifier_Config $config */ abstract protected function doSetup($config); /** * Setup function that aborts if already setup - * @param $config HTMLPurifier_Config instance + * @param HTMLPurifier_Config $config */ - public function setup($config) { - if ($this->setup) return; + public function setup($config) + { + if ($this->setup) { + return; + } $this->setup = true; $this->doSetup($config); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/DefinitionCache.php b/library/HTMLPurifier/DefinitionCache.php index c6e1e388..67bb5b1e 100644 --- a/library/HTMLPurifier/DefinitionCache.php +++ b/library/HTMLPurifier/DefinitionCache.php @@ -10,22 +10,27 @@ */ abstract class HTMLPurifier_DefinitionCache { - + /** + * @type string + */ public $type; /** - * @param $name Type of definition objects this instance of the + * @param string $type Type of definition objects this instance of the * cache will handle. */ - public function __construct($type) { + public function __construct($type) + { $this->type = $type; } /** * Generates a unique identifier for a particular configuration - * @param Instance of HTMLPurifier_Config + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config + * @return string */ - public function generateKey($config) { + public function generateKey($config) + { return $config->version . ',' . // possibly replace with function calls $config->getBatchSerial($this->type) . ',' . $config->get($this->type . '.DefinitionRev'); @@ -34,30 +39,37 @@ abstract class HTMLPurifier_DefinitionCache /** * Tests whether or not a key is old with respect to the configuration's * version and revision number. - * @param $key Key to test - * @param $config Instance of HTMLPurifier_Config to test against + * @param string $key Key to test + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config to test against + * @return bool */ - public function isOld($key, $config) { - if (substr_count($key, ',') < 2) return true; + public function isOld($key, $config) + { + if (substr_count($key, ',') < 2) { + return true; + } list($version, $hash, $revision) = explode(',', $key, 3); $compare = version_compare($version, $config->version); // version mismatch, is always old - if ($compare != 0) return true; + if ($compare != 0) { + return true; + } // versions match, ids match, check revision number - if ( - $hash == $config->getBatchSerial($this->type) && - $revision < $config->get($this->type . '.DefinitionRev') - ) return true; + if ($hash == $config->getBatchSerial($this->type) && + $revision < $config->get($this->type . '.DefinitionRev')) { + return true; + } return false; } /** * Checks if a definition's type jives with the cache's type * @note Throws an error on failure - * @param $def Definition object to check - * @return Boolean true if good, false if not + * @param HTMLPurifier_Definition $def Definition object to check + * @return bool true if good, false if not */ - public function checkDefType($def) { + public function checkDefType($def) + { if ($def->type !== $this->type) { trigger_error("Cannot use definition of type {$def->type} in cache for {$this->type}"); return false; @@ -67,31 +79,40 @@ abstract class HTMLPurifier_DefinitionCache /** * Adds a definition object to the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config */ abstract public function add($def, $config); /** * Unconditionally saves a definition object to the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config */ abstract public function set($def, $config); /** * Replace an object in the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config */ abstract public function replace($def, $config); /** * Retrieves a definition object from the cache + * @param HTMLPurifier_Config $config */ abstract public function get($config); /** * Removes a definition object to the cache + * @param HTMLPurifier_Config $config */ abstract public function remove($config); /** * Clears all objects from cache + * @param HTMLPurifier_Config $config */ abstract public function flush($config); @@ -100,9 +121,9 @@ abstract class HTMLPurifier_DefinitionCache * @note Be carefuly implementing this method as flush. Flush must * not interfere with other Definition types, and cleanup() * should not be repeatedly called by userland code. + * @param HTMLPurifier_Config $config */ abstract public function cleanup($config); - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/DefinitionCache/Decorator.php b/library/HTMLPurifier/DefinitionCache/Decorator.php index 37db816f..b57a51b6 100644 --- a/library/HTMLPurifier/DefinitionCache/Decorator.php +++ b/library/HTMLPurifier/DefinitionCache/Decorator.php @@ -5,7 +5,7 @@ class HTMLPurifier_DefinitionCache_Decorator extends HTMLPurifier_DefinitionCach /** * Cache object we are decorating - * @var HTMLPurifier_DefinitionCache + * @type HTMLPurifier_DefinitionCache */ public $cache; @@ -15,13 +15,13 @@ class HTMLPurifier_DefinitionCache_Decorator extends HTMLPurifier_DefinitionCach */ public $name; - public function __construct() {} + public function __construct() + { + } /** * Lazy decorator function - * * @param HTMLPurifier_DefinitionCache $cache Reference to cache object to decorate - * * @return HTMLPurifier_DefinitionCache_Decorator */ public function decorate(&$cache) @@ -29,48 +29,80 @@ class HTMLPurifier_DefinitionCache_Decorator extends HTMLPurifier_DefinitionCach $decorator = $this->copy(); // reference is necessary for mocks in PHP 4 $decorator->cache =& $cache; - $decorator->type = $cache->type; + $decorator->type = $cache->type; return $decorator; } /** * Cross-compatible clone substitute + * @return HTMLPurifier_DefinitionCache_Decorator */ public function copy() { return new HTMLPurifier_DefinitionCache_Decorator(); } + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ public function add($def, $config) { return $this->cache->add($def, $config); } + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ public function set($def, $config) { return $this->cache->set($def, $config); } + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ public function replace($def, $config) { return $this->cache->replace($def, $config); } + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ public function get($config) { return $this->cache->get($config); } + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ public function remove($config) { return $this->cache->remove($config); } + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ public function flush($config) { return $this->cache->flush($config); } + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ public function cleanup($config) { return $this->cache->cleanup($config); diff --git a/library/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php b/library/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php index d4cc35c4..4991777c 100644 --- a/library/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php +++ b/library/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php @@ -4,40 +4,75 @@ * Definition cache decorator class that cleans up the cache * whenever there is a cache miss. */ -class HTMLPurifier_DefinitionCache_Decorator_Cleanup extends - HTMLPurifier_DefinitionCache_Decorator +class HTMLPurifier_DefinitionCache_Decorator_Cleanup extends HTMLPurifier_DefinitionCache_Decorator { - + /** + * @type string + */ public $name = 'Cleanup'; - public function copy() { + /** + * @return HTMLPurifier_DefinitionCache_Decorator_Cleanup + */ + public function copy() + { return new HTMLPurifier_DefinitionCache_Decorator_Cleanup(); } - public function add($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function add($def, $config) + { $status = parent::add($def, $config); - if (!$status) parent::cleanup($config); + if (!$status) { + parent::cleanup($config); + } return $status; } - public function set($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function set($def, $config) + { $status = parent::set($def, $config); - if (!$status) parent::cleanup($config); + if (!$status) { + parent::cleanup($config); + } return $status; } - public function replace($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function replace($def, $config) + { $status = parent::replace($def, $config); - if (!$status) parent::cleanup($config); + if (!$status) { + parent::cleanup($config); + } return $status; } - public function get($config) { + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function get($config) + { $ret = parent::get($config); - if (!$ret) parent::cleanup($config); + if (!$ret) { + parent::cleanup($config); + } return $ret; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/DefinitionCache/Decorator/Memory.php b/library/HTMLPurifier/DefinitionCache/Decorator/Memory.php index 18f16d32..d529dce4 100644 --- a/library/HTMLPurifier/DefinitionCache/Decorator/Memory.php +++ b/library/HTMLPurifier/DefinitionCache/Decorator/Memory.php @@ -5,42 +5,81 @@ * to PHP's memory; good for unit tests or circumstances where * there are lots of configuration objects floating around. */ -class HTMLPurifier_DefinitionCache_Decorator_Memory extends - HTMLPurifier_DefinitionCache_Decorator +class HTMLPurifier_DefinitionCache_Decorator_Memory extends HTMLPurifier_DefinitionCache_Decorator { - + /** + * @type array + */ protected $definitions; + + /** + * @type string + */ public $name = 'Memory'; - public function copy() { + /** + * @return HTMLPurifier_DefinitionCache_Decorator_Memory + */ + public function copy() + { return new HTMLPurifier_DefinitionCache_Decorator_Memory(); } - public function add($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function add($def, $config) + { $status = parent::add($def, $config); - if ($status) $this->definitions[$this->generateKey($config)] = $def; + if ($status) { + $this->definitions[$this->generateKey($config)] = $def; + } return $status; } - public function set($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function set($def, $config) + { $status = parent::set($def, $config); - if ($status) $this->definitions[$this->generateKey($config)] = $def; + if ($status) { + $this->definitions[$this->generateKey($config)] = $def; + } return $status; } - public function replace($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function replace($def, $config) + { $status = parent::replace($def, $config); - if ($status) $this->definitions[$this->generateKey($config)] = $def; + if ($status) { + $this->definitions[$this->generateKey($config)] = $def; + } return $status; } - public function get($config) { + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function get($config) + { $key = $this->generateKey($config); - if (isset($this->definitions[$key])) return $this->definitions[$key]; + if (isset($this->definitions[$key])) { + return $this->definitions[$key]; + } $this->definitions[$key] = parent::get($config); return $this->definitions[$key]; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/DefinitionCache/Decorator/Template.php.in b/library/HTMLPurifier/DefinitionCache/Decorator/Template.php.in index 21a8fcfd..b1fec8d3 100644 --- a/library/HTMLPurifier/DefinitionCache/Decorator/Template.php.in +++ b/library/HTMLPurifier/DefinitionCache/Decorator/Template.php.in @@ -5,43 +5,78 @@ require_once 'HTMLPurifier/DefinitionCache/Decorator.php'; /** * Definition cache decorator template. */ -class HTMLPurifier_DefinitionCache_Decorator_Template extends - HTMLPurifier_DefinitionCache_Decorator +class HTMLPurifier_DefinitionCache_Decorator_Template extends HTMLPurifier_DefinitionCache_Decorator { - var $name = 'Template'; // replace this + /** + * @type string + */ + public $name = 'Template'; // replace this - function copy() { + public function copy() + { // replace class name with yours return new HTMLPurifier_DefinitionCache_Decorator_Template(); } // remove methods you don't need - function add($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function add($def, $config) + { return parent::add($def, $config); } - function set($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function set($def, $config) + { return parent::set($def, $config); } - function replace($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function replace($def, $config) + { return parent::replace($def, $config); } - function get($config) { + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function get($config) + { return parent::get($config); } - function flush() { - return parent::flush(); + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function flush($config) + { + return parent::flush($config); } - function cleanup($config) { + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function cleanup($config) + { return parent::cleanup($config); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/DefinitionCache/Null.php b/library/HTMLPurifier/DefinitionCache/Null.php index 41d97e73..d9a75ce2 100644 --- a/library/HTMLPurifier/DefinitionCache/Null.php +++ b/library/HTMLPurifier/DefinitionCache/Null.php @@ -6,34 +6,71 @@ class HTMLPurifier_DefinitionCache_Null extends HTMLPurifier_DefinitionCache { - public function add($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return bool + */ + public function add($def, $config) + { return false; } - public function set($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return bool + */ + public function set($def, $config) + { return false; } - public function replace($def, $config) { + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return bool + */ + public function replace($def, $config) + { return false; } - public function remove($config) { + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function remove($config) + { return false; } - public function get($config) { + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function get($config) + { return false; } - public function flush($config) { + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function flush($config) + { return false; } - public function cleanup($config) { + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function cleanup($config) + { return false; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/DefinitionCache/Serializer.php b/library/HTMLPurifier/DefinitionCache/Serializer.php index 73d5e90a..ecacb88f 100644 --- a/library/HTMLPurifier/DefinitionCache/Serializer.php +++ b/library/HTMLPurifier/DefinitionCache/Serializer.php @@ -1,83 +1,160 @@ checkDefType($def)) return; + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return int|bool + */ + public function add($def, $config) + { + if (!$this->checkDefType($def)) { + return; + } $file = $this->generateFilePath($config); - if (file_exists($file)) return false; - if (!$this->_prepareDir($config)) return false; + if (file_exists($file)) { + return false; + } + if (!$this->_prepareDir($config)) { + return false; + } return $this->_write($file, serialize($def), $config); } - public function set($def, $config) { - if (!$this->checkDefType($def)) return; + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return int|bool + */ + public function set($def, $config) + { + if (!$this->checkDefType($def)) { + return; + } $file = $this->generateFilePath($config); - if (!$this->_prepareDir($config)) return false; + if (!$this->_prepareDir($config)) { + return false; + } return $this->_write($file, serialize($def), $config); } - public function replace($def, $config) { - if (!$this->checkDefType($def)) return; + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return int|bool + */ + public function replace($def, $config) + { + if (!$this->checkDefType($def)) { + return; + } $file = $this->generateFilePath($config); - if (!file_exists($file)) return false; - if (!$this->_prepareDir($config)) return false; + if (!file_exists($file)) { + return false; + } + if (!$this->_prepareDir($config)) { + return false; + } return $this->_write($file, serialize($def), $config); } - public function get($config) { + /** + * @param HTMLPurifier_Config $config + * @return bool|HTMLPurifier_Config + */ + public function get($config) + { $file = $this->generateFilePath($config); - if (!file_exists($file)) return false; + if (!file_exists($file)) { + return false; + } return unserialize(file_get_contents($file)); } - public function remove($config) { + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function remove($config) + { $file = $this->generateFilePath($config); - if (!file_exists($file)) return false; + if (!file_exists($file)) { + return false; + } return unlink($file); } - public function flush($config) { - if (!$this->_prepareDir($config)) return false; + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function flush($config) + { + if (!$this->_prepareDir($config)) { + return false; + } $dir = $this->generateDirectoryPath($config); - $dh = opendir($dir); + $dh = opendir($dir); while (false !== ($filename = readdir($dh))) { - if (empty($filename)) continue; - if ($filename[0] === '.') continue; + if (empty($filename)) { + continue; + } + if ($filename[0] === '.') { + continue; + } unlink($dir . '/' . $filename); } } - public function cleanup($config) { - if (!$this->_prepareDir($config)) return false; + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function cleanup($config) + { + if (!$this->_prepareDir($config)) { + return false; + } $dir = $this->generateDirectoryPath($config); - $dh = opendir($dir); + $dh = opendir($dir); while (false !== ($filename = readdir($dh))) { - if (empty($filename)) continue; - if ($filename[0] === '.') continue; + if (empty($filename)) { + continue; + } + if ($filename[0] === '.') { + continue; + } $key = substr($filename, 0, strlen($filename) - 4); - if ($this->isOld($key, $config)) unlink($dir . '/' . $filename); + if ($this->isOld($key, $config)) { + unlink($dir . '/' . $filename); + } } } /** * Generates the file path to the serial file corresponding to * the configuration and definition name + * @param HTMLPurifier_Config $config + * @return string * @todo Make protected */ - public function generateFilePath($config) { + public function generateFilePath($config) + { $key = $this->generateKey($config); return $this->generateDirectoryPath($config) . '/' . $key . '.ser'; } /** * Generates the path to the directory contain this cache's serial files + * @param HTMLPurifier_Config $config + * @return string * @note No trailing slash * @todo Make protected */ - public function generateDirectoryPath($config) { + public function generateDirectoryPath($config) + { $base = $this->generateBaseDirectoryPath($config); return $base . '/' . $this->type; } @@ -85,9 +162,12 @@ class HTMLPurifier_DefinitionCache_Serializer extends /** * Generates path to base directory that contains all definition type * serials + * @param HTMLPurifier_Config $config + * @return mixed|string * @todo Make protected */ - public function generateBaseDirectoryPath($config) { + public function generateBaseDirectoryPath($config) + { $base = $config->get('Cache.SerializerPath'); $base = is_null($base) ? HTMLPURIFIER_PREFIX . '/HTMLPurifier/DefinitionCache/Serializer' : $base; return $base; @@ -95,12 +175,13 @@ class HTMLPurifier_DefinitionCache_Serializer extends /** * Convenience wrapper function for file_put_contents - * @param $file File name to write to - * @param $data Data to write into file - * @param $config Config object - * @return Number of bytes written if success, or false if failure. + * @param string $file File name to write to + * @param string $data Data to write into file + * @param HTMLPurifier_Config $config + * @return int|bool Number of bytes written if success, or false if failure. */ - private function _write($file, $data, $config) { + private function _write($file, $data, $config) + { $result = file_put_contents($file, $data); if ($result !== false) { // set permissions of the new file (no execute) @@ -116,10 +197,11 @@ class HTMLPurifier_DefinitionCache_Serializer extends /** * Prepares the directory that this type stores the serials in - * @param $config Config object - * @return True if successful + * @param HTMLPurifier_Config $config + * @return bool True if successful */ - private function _prepareDir($config) { + private function _prepareDir($config) + { $directory = $this->generateDirectoryPath($config); $chmod = $config->get('Cache.SerializerPermissions'); if (!$chmod) { @@ -128,9 +210,11 @@ class HTMLPurifier_DefinitionCache_Serializer extends if (!is_dir($directory)) { $base = $this->generateBaseDirectoryPath($config); if (!is_dir($base)) { - trigger_error('Base directory '.$base.' does not exist, + trigger_error( + 'Base directory ' . $base . ' does not exist, please create or change using %Cache.SerializerPath', - E_USER_WARNING); + E_USER_WARNING + ); return false; } elseif (!$this->_testPermissions($base, $chmod)) { return false; @@ -147,18 +231,23 @@ class HTMLPurifier_DefinitionCache_Serializer extends /** * Tests permissions on a directory and throws out friendly * error messages and attempts to chmod it itself if possible - * @param $dir Directory path - * @param $chmod Permissions - * @return True if directory writable + * @param string $dir Directory path + * @param int $chmod Permissions + * @return bool True if directory is writable */ - private function _testPermissions($dir, $chmod) { + private function _testPermissions($dir, $chmod) + { // early abort, if it is writable, everything is hunky-dory - if (is_writable($dir)) return true; + if (is_writable($dir)) { + return true; + } if (!is_dir($dir)) { // generally, you'll want to handle this beforehand // so a more specific error message can be given - trigger_error('Directory '.$dir.' does not exist', - E_USER_WARNING); + trigger_error( + 'Directory ' . $dir . ' does not exist', + E_USER_WARNING + ); return false; } if (function_exists('posix_getuid')) { @@ -166,7 +255,9 @@ class HTMLPurifier_DefinitionCache_Serializer extends if (fileowner($dir) === posix_getuid()) { // we can chmod it ourselves $chmod = $chmod | 0700; - if (chmod($dir, $chmod)) return true; + if (chmod($dir, $chmod)) { + return true; + } } elseif (filegroup($dir) === posix_getgid()) { $chmod = $chmod | 0070; } else { @@ -174,18 +265,21 @@ class HTMLPurifier_DefinitionCache_Serializer extends // need to give global permissions $chmod = $chmod | 0777; } - trigger_error('Directory '.$dir.' not writable, '. + trigger_error( + 'Directory ' . $dir . ' not writable, ' . 'please chmod to ' . decoct($chmod), - E_USER_WARNING); + E_USER_WARNING + ); } else { // generic error message - trigger_error('Directory '.$dir.' not writable, '. + trigger_error( + 'Directory ' . $dir . ' not writable, ' . 'please alter file permissions', - E_USER_WARNING); + E_USER_WARNING + ); } return false; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/DefinitionCacheFactory.php b/library/HTMLPurifier/DefinitionCacheFactory.php index faa12899..fd1cc9be 100644 --- a/library/HTMLPurifier/DefinitionCacheFactory.php +++ b/library/HTMLPurifier/DefinitionCacheFactory.php @@ -5,11 +5,18 @@ */ class HTMLPurifier_DefinitionCacheFactory { - + /** + * @type array + */ protected $caches = array('Serializer' => array()); + + /** + * @type array + */ protected $implementations = array(); + /** - * @var HTMLPurifier_DefinitionCache_Decorator[] + * @type HTMLPurifier_DefinitionCache_Decorator[] */ protected $decorators = array(); @@ -23,7 +30,7 @@ class HTMLPurifier_DefinitionCacheFactory /** * Retrieves an instance of global definition cache factory. - * + * @param HTMLPurifier_DefinitionCacheFactory $prototype * @return HTMLPurifier_DefinitionCacheFactory */ public static function instance($prototype = null) @@ -50,9 +57,9 @@ class HTMLPurifier_DefinitionCacheFactory /** * Factory method that creates a cache object based on configuration - * - * @param string $name Name of definitions handled by cache + * @param string $type Name of definitions handled by cache * @param HTMLPurifier_Config $config Config instance + * @return mixed */ public function create($type, $config) { @@ -63,10 +70,8 @@ class HTMLPurifier_DefinitionCacheFactory if (!empty($this->caches[$method][$type])) { return $this->caches[$method][$type]; } - if ( - isset($this->implementations[$method]) && - class_exists($class = $this->implementations[$method], false) - ) { + if (isset($this->implementations[$method]) && + class_exists($class = $this->implementations[$method], false)) { $cache = new $class($type); } else { if ($method != 'Serializer') { @@ -96,7 +101,6 @@ class HTMLPurifier_DefinitionCacheFactory } $this->decorators[$decorator->name] = $decorator; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Doctype.php b/library/HTMLPurifier/Doctype.php index 1e3c574c..4acd06e5 100644 --- a/library/HTMLPurifier/Doctype.php +++ b/library/HTMLPurifier/Doctype.php @@ -10,42 +10,55 @@ class HTMLPurifier_Doctype { /** * Full name of doctype + * @type string */ public $name; /** * List of standard modules (string identifiers or literal objects) * that this doctype uses + * @type array */ public $modules = array(); /** * List of modules to use for tidying up code + * @type array */ public $tidyModules = array(); /** * Is the language derived from XML (i.e. XHTML)? + * @type bool */ public $xml = true; /** * List of aliases for this doctype + * @type array */ public $aliases = array(); /** * Public DTD identifier + * @type string */ public $dtdPublic; /** * System DTD identifier + * @type string */ public $dtdSystem; - public function __construct($name = null, $xml = true, $modules = array(), - $tidyModules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null + public function __construct( + $name = null, + $xml = true, + $modules = array(), + $tidyModules = array(), + $aliases = array(), + $dtd_public = null, + $dtd_system = null ) { $this->name = $name; $this->xml = $xml; diff --git a/library/HTMLPurifier/DoctypeRegistry.php b/library/HTMLPurifier/DoctypeRegistry.php index 86049e93..acc1d64a 100644 --- a/library/HTMLPurifier/DoctypeRegistry.php +++ b/library/HTMLPurifier/DoctypeRegistry.php @@ -4,12 +4,14 @@ class HTMLPurifier_DoctypeRegistry { /** - * Hash of doctype names to doctype objects + * Hash of doctype names to doctype objects. + * @type array */ protected $doctypes; /** - * Lookup table of aliases to real doctype names + * Lookup table of aliases to real doctype names. + * @type array */ protected $aliases; @@ -17,32 +19,57 @@ class HTMLPurifier_DoctypeRegistry * Registers a doctype to the registry * @note Accepts a fully-formed doctype object, or the * parameters for constructing a doctype object - * @param $doctype Name of doctype or literal doctype object - * @param $modules Modules doctype will load - * @param $modules_for_modes Modules doctype will load for certain modes - * @param $aliases Alias names for doctype - * @return Editable registered doctype + * @param string $doctype Name of doctype or literal doctype object + * @param bool $xml + * @param array $modules Modules doctype will load + * @param array $tidy_modules Modules doctype will load for certain modes + * @param array $aliases Alias names for doctype + * @param string $dtd_public + * @param string $dtd_system + * @return HTMLPurifier_Doctype Editable registered doctype */ - public function register($doctype, $xml = true, $modules = array(), - $tidy_modules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null + public function register( + $doctype, + $xml = true, + $modules = array(), + $tidy_modules = array(), + $aliases = array(), + $dtd_public = null, + $dtd_system = null ) { - if (!is_array($modules)) $modules = array($modules); - if (!is_array($tidy_modules)) $tidy_modules = array($tidy_modules); - if (!is_array($aliases)) $aliases = array($aliases); + if (!is_array($modules)) { + $modules = array($modules); + } + if (!is_array($tidy_modules)) { + $tidy_modules = array($tidy_modules); + } + if (!is_array($aliases)) { + $aliases = array($aliases); + } if (!is_object($doctype)) { $doctype = new HTMLPurifier_Doctype( - $doctype, $xml, $modules, $tidy_modules, $aliases, $dtd_public, $dtd_system + $doctype, + $xml, + $modules, + $tidy_modules, + $aliases, + $dtd_public, + $dtd_system ); } $this->doctypes[$doctype->name] = $doctype; $name = $doctype->name; // hookup aliases foreach ($doctype->aliases as $alias) { - if (isset($this->doctypes[$alias])) continue; + if (isset($this->doctypes[$alias])) { + continue; + } $this->aliases[$alias] = $name; } // remove old aliases - if (isset($this->aliases[$name])) unset($this->aliases[$name]); + if (isset($this->aliases[$name])) { + unset($this->aliases[$name]); + } return $doctype; } @@ -50,11 +77,14 @@ class HTMLPurifier_DoctypeRegistry * Retrieves reference to a doctype of a certain name * @note This function resolves aliases * @note When possible, use the more fully-featured make() - * @param $doctype Name of doctype - * @return Editable doctype object + * @param string $doctype Name of doctype + * @return HTMLPurifier_Doctype Editable doctype object */ - public function get($doctype) { - if (isset($this->aliases[$doctype])) $doctype = $this->aliases[$doctype]; + public function get($doctype) + { + if (isset($this->aliases[$doctype])) { + $doctype = $this->aliases[$doctype]; + } if (!isset($this->doctypes[$doctype])) { trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR); $anon = new HTMLPurifier_Doctype($doctype); @@ -70,20 +100,30 @@ class HTMLPurifier_DoctypeRegistry * can hold on to (this is necessary in order to tell * Generator whether or not the current document is XML * based or not). + * @param HTMLPurifier_Config $config + * @return HTMLPurifier_Doctype */ - public function make($config) { + public function make($config) + { return clone $this->get($this->getDoctypeFromConfig($config)); } /** * Retrieves the doctype from the configuration object + * @param HTMLPurifier_Config $config + * @return string */ - public function getDoctypeFromConfig($config) { + public function getDoctypeFromConfig($config) + { // recommended test $doctype = $config->get('HTML.Doctype'); - if (!empty($doctype)) return $doctype; + if (!empty($doctype)) { + return $doctype; + } $doctype = $config->get('HTML.CustomDoctype'); - if (!empty($doctype)) return $doctype; + if (!empty($doctype)) { + return $doctype; + } // backwards-compatibility if ($config->get('HTML.XHTML')) { $doctype = 'XHTML 1.0'; @@ -97,7 +137,6 @@ class HTMLPurifier_DoctypeRegistry } return $doctype; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ElementDef.php b/library/HTMLPurifier/ElementDef.php index 10f7ab7f..d5311ced 100644 --- a/library/HTMLPurifier/ElementDef.php +++ b/library/HTMLPurifier/ElementDef.php @@ -10,15 +10,16 @@ */ class HTMLPurifier_ElementDef { - /** * Does the definition work by itself, or is it created solely * for the purpose of merging into another definition? + * @type bool */ public $standalone = true; /** - * Associative array of attribute name to HTMLPurifier_AttrDef + * Associative array of attribute name to HTMLPurifier_AttrDef. + * @type array * @note Before being processed by HTMLPurifier_AttrCollections * when modules are finalized during * HTMLPurifier_HTMLDefinition->setup(), this array may also @@ -43,26 +44,30 @@ class HTMLPurifier_ElementDef // nuking. /** - * List of tags HTMLPurifier_AttrTransform to be done before validation + * List of tags HTMLPurifier_AttrTransform to be done before validation. + * @type array */ public $attr_transform_pre = array(); /** - * List of tags HTMLPurifier_AttrTransform to be done after validation + * List of tags HTMLPurifier_AttrTransform to be done after validation. + * @type array */ public $attr_transform_post = array(); /** * HTMLPurifier_ChildDef of this tag. + * @type HTMLPurifier_ChildDef */ public $child; /** - * Abstract string representation of internal ChildDef rules. See - * HTMLPurifier_ContentSets for how this is parsed and then transformed + * Abstract string representation of internal ChildDef rules. + * @see HTMLPurifier_ContentSets for how this is parsed and then transformed * into an HTMLPurifier_ChildDef. * @warning This is a temporary variable that is not available after * being processed by HTMLDefinition + * @type string */ public $content_model; @@ -72,27 +77,29 @@ class HTMLPurifier_ElementDef * @warning This must be lowercase * @warning This is a temporary variable that is not available after * being processed by HTMLDefinition + * @type string */ public $content_model_type; - - /** * Does the element have a content model (#PCDATA | Inline)*? This * is important for chameleon ins and del processing in * HTMLPurifier_ChildDef_Chameleon. Dynamically set: modules don't * have to worry about this one. + * @type bool */ public $descendants_are_inline = false; /** - * List of the names of required attributes this element has. Dynamically - * populated by HTMLPurifier_HTMLDefinition::getElement + * List of the names of required attributes this element has. + * Dynamically populated by HTMLPurifier_HTMLDefinition::getElement() + * @type array */ public $required_attr = array(); /** * Lookup table of tags excluded from all descendants of this tag. + * @type array * @note SGML permits exclusions for all descendants, but this is * not possible with DTDs or XML Schemas. W3C has elected to * use complicated compositions of content_models to simulate @@ -106,6 +113,7 @@ class HTMLPurifier_ElementDef /** * This tag is explicitly auto-closed by the following tags. + * @type array */ public $autoclose = array(); @@ -113,19 +121,22 @@ class HTMLPurifier_ElementDef * If a foreign element is found in this element, test if it is * allowed by this sub-element; if it is, instead of closing the * current element, place it inside this element. + * @type string */ public $wrap; /** * Whether or not this is a formatting element affected by the * "Active Formatting Elements" algorithm. + * @type bool */ public $formatting; /** * Low-level factory constructor for creating new standalone element defs */ - public static function create($content_model, $content_model_type, $attr) { + public static function create($content_model, $content_model_type, $attr) + { $def = new HTMLPurifier_ElementDef(); $def->content_model = $content_model; $def->content_model_type = $content_model_type; @@ -137,11 +148,12 @@ class HTMLPurifier_ElementDef * Merges the values of another element definition into this one. * Values from the new element def take precedence if a value is * not mergeable. + * @param HTMLPurifier_ElementDef $def */ - public function mergeIn($def) { - + public function mergeIn($def) + { // later keys takes precedence - foreach($def->attr as $k => $v) { + foreach ($def->attr as $k => $v) { if ($k === 0) { // merge in the includes // sorry, no way to override an include @@ -151,7 +163,9 @@ class HTMLPurifier_ElementDef continue; } if ($v === false) { - if (isset($this->attr[$k])) unset($this->attr[$k]); + if (isset($this->attr[$k])) { + unset($this->attr[$k]); + } continue; } $this->attr[$k] = $v; @@ -160,19 +174,24 @@ class HTMLPurifier_ElementDef $this->attr_transform_pre = array_merge($this->attr_transform_pre, $def->attr_transform_pre); $this->attr_transform_post = array_merge($this->attr_transform_post, $def->attr_transform_post); - if(!empty($def->content_model)) { + if (!empty($def->content_model)) { $this->content_model = str_replace("#SUPER", $this->content_model, $def->content_model); $this->child = false; } - if(!empty($def->content_model_type)) { + if (!empty($def->content_model_type)) { $this->content_model_type = $def->content_model_type; $this->child = false; } - if(!is_null($def->child)) $this->child = $def->child; - if(!is_null($def->formatting)) $this->formatting = $def->formatting; - if($def->descendants_are_inline) $this->descendants_are_inline = $def->descendants_are_inline; - + if (!is_null($def->child)) { + $this->child = $def->child; + } + if (!is_null($def->formatting)) { + $this->formatting = $def->formatting; + } + if ($def->descendants_are_inline) { + $this->descendants_are_inline = $def->descendants_are_inline; + } } /** @@ -180,16 +199,18 @@ class HTMLPurifier_ElementDef * @param $a1 Array by reference that is merged into * @param $a2 Array that merges into $a1 */ - private function _mergeAssocArray(&$a1, $a2) { + private function _mergeAssocArray(&$a1, $a2) + { foreach ($a2 as $k => $v) { if ($v === false) { - if (isset($a1[$k])) unset($a1[$k]); + if (isset($a1[$k])) { + unset($a1[$k]); + } continue; } $a1[$k] = $v; } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Encoder.php b/library/HTMLPurifier/Encoder.php index 77988a19..fef9b589 100644 --- a/library/HTMLPurifier/Encoder.php +++ b/library/HTMLPurifier/Encoder.php @@ -10,19 +10,27 @@ class HTMLPurifier_Encoder /** * Constructor throws fatal error if you attempt to instantiate class */ - private function __construct() { + private function __construct() + { trigger_error('Cannot instantiate encoder, call methods statically', E_USER_ERROR); } /** * Error-handler that mutes errors, alternative to shut-up operator. */ - public static function muteErrorHandler() {} + public static function muteErrorHandler() + { + } /** * iconv wrapper which mutes errors, but doesn't work around bugs. + * @param string $in Input encoding + * @param string $out Output encoding + * @param string $text The text to convert + * @return string */ - public static function unsafeIconv($in, $out, $text) { + public static function unsafeIconv($in, $out, $text) + { set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler')); $r = iconv($in, $out, $text); restore_error_handler(); @@ -31,8 +39,14 @@ class HTMLPurifier_Encoder /** * iconv wrapper which mutes errors and works around bugs. + * @param string $in Input encoding + * @param string $out Output encoding + * @param string $text The text to convert + * @param int $max_chunk_size + * @return string */ - public static function iconv($in, $out, $text, $max_chunk_size = 8000) { + public static function iconv($in, $out, $text, $max_chunk_size = 8000) + { $code = self::testIconvTruncateBug(); if ($code == self::ICONV_OK) { return self::unsafeIconv($in, $out, $text); @@ -87,6 +101,10 @@ class HTMLPurifier_Encoder * It will parse according to UTF-8 and return a valid UTF8 string, with * non-SGML codepoints excluded. * + * @param string $str The string to clean + * @param bool $force_php + * @return string + * * @note Just for reference, the non-SGML code points are 0 to 31 and * 127 to 159, inclusive. However, we allow code points 9, 10 * and 13, which are the tab, line feed and carriage return @@ -106,14 +124,17 @@ class HTMLPurifier_Encoder * would need that, and I'm probably not going to implement them. * Once again, PHP 6 should solve all our problems. */ - public static function cleanUTF8($str, $force_php = false) { - + public static function cleanUTF8($str, $force_php = false) + { // UTF-8 validity is checked since PHP 4.3.5 // This is an optimization: if the string is already valid UTF-8, no // need to do PHP stuff. 99% of the time, this will be the case. // The regexp matches the XML char production, as well as well as excluding // non-SGML codepoints U+007F to U+009F - if (preg_match('/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', $str)) { + if (preg_match( + '/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', + $str + )) { return $str; } @@ -132,7 +153,7 @@ class HTMLPurifier_Encoder $char = ''; $len = strlen($str); - for($i = 0; $i < $len; $i++) { + for ($i = 0; $i < $len; $i++) { $in = ord($str{$i}); $char .= $str[$i]; // append byte to char if (0 == $mState) { @@ -285,8 +306,9 @@ class HTMLPurifier_Encoder // | 00000000 | 00010000 | 11111111 | 11111111 | Defined upper limit of legal scalar codes // +----------+----------+----------+----------+ - public static function unichr($code) { - if($code > 1114111 or $code < 0 or + public static function unichr($code) + { + if ($code > 1114111 or $code < 0 or ($code >= 55296 and $code <= 57343) ) { // bits are set outside the "valid" range as defined // by UNICODE 4.1.0 @@ -304,7 +326,7 @@ class HTMLPurifier_Encoder $y = (($code & 2047) >> 6) | 192; } else { $y = (($code & 4032) >> 6) | 128; - if($code < 65536) { + if ($code < 65536) { $z = (($code >> 12) & 15) | 224; } else { $z = (($code >> 12) & 63) | 128; @@ -314,15 +336,25 @@ class HTMLPurifier_Encoder } // set up the actual character $ret = ''; - if($w) $ret .= chr($w); - if($z) $ret .= chr($z); - if($y) $ret .= chr($y); + if ($w) { + $ret .= chr($w); + } + if ($z) { + $ret .= chr($z); + } + if ($y) { + $ret .= chr($y); + } $ret .= chr($x); return $ret; } - public static function iconvAvailable() { + /** + * @return bool + */ + public static function iconvAvailable() + { static $iconv = null; if ($iconv === null) { $iconv = function_exists('iconv') && self::testIconvTruncateBug() != self::ICONV_UNUSABLE; @@ -331,13 +363,22 @@ class HTMLPurifier_Encoder } /** - * Converts a string to UTF-8 based on configuration. + * Convert a string to UTF-8 based on configuration. + * @param string $str The string to convert + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string */ - public static function convertToUTF8($str, $config, $context) { + public static function convertToUTF8($str, $config, $context) + { $encoding = $config->get('Core.Encoding'); - if ($encoding === 'utf-8') return $str; + if ($encoding === 'utf-8') { + return $str; + } static $iconv = null; - if ($iconv === null) $iconv = self::iconvAvailable(); + if ($iconv === null) { + $iconv = self::iconvAvailable(); + } if ($iconv && !$config->get('Test.ForceNoIconv')) { // unaffected by bugs, since UTF-8 support all characters $str = self::unsafeIconv($encoding, 'utf-8//IGNORE', $str); @@ -359,29 +400,44 @@ class HTMLPurifier_Encoder if ($bug == self::ICONV_OK) { trigger_error('Encoding not supported, please install iconv', E_USER_ERROR); } else { - trigger_error('You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 and http://sourceware.org/bugzilla/show_bug.cgi?id=13541', E_USER_ERROR); + trigger_error( + 'You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 ' . + 'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541', + E_USER_ERROR + ); } } /** * Converts a string from UTF-8 based on configuration. + * @param string $str The string to convert + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string * @note Currently, this is a lossy conversion, with unexpressable * characters being omitted. */ - public static function convertFromUTF8($str, $config, $context) { + public static function convertFromUTF8($str, $config, $context) + { $encoding = $config->get('Core.Encoding'); if ($escape = $config->get('Core.EscapeNonASCIICharacters')) { $str = self::convertToASCIIDumbLossless($str); } - if ($encoding === 'utf-8') return $str; + if ($encoding === 'utf-8') { + return $str; + } static $iconv = null; - if ($iconv === null) $iconv = self::iconvAvailable(); + if ($iconv === null) { + $iconv = self::iconvAvailable(); + } if ($iconv && !$config->get('Test.ForceNoIconv')) { // Undo our previous fix in convertToUTF8, otherwise iconv will barf $ascii_fix = self::testEncodingSupportsASCII($encoding); if (!$escape && !empty($ascii_fix)) { $clear_fix = array(); - foreach ($ascii_fix as $utf8 => $native) $clear_fix[$utf8] = ''; + foreach ($ascii_fix as $utf8 => $native) { + $clear_fix[$utf8] = ''; + } $str = strtr($str, $clear_fix); } $str = strtr($str, array_flip($ascii_fix)); @@ -401,8 +457,8 @@ class HTMLPurifier_Encoder /** * Lossless (character-wise) conversion of HTML to ASCII - * @param $str UTF-8 string to be converted to ASCII - * @returns ASCII encoded string with non-ASCII character entity-ized + * @param string $str UTF-8 string to be converted to ASCII + * @return string ASCII encoded string with non-ASCII character entity-ized * @warning Adapted from MediaWiki, claiming fair use: this is a common * algorithm. If you disagree with this license fudgery, * implement it yourself. @@ -415,27 +471,28 @@ class HTMLPurifier_Encoder * @note Sort of with cleanUTF8() but it assumes that $str is * well-formed UTF-8 */ - public static function convertToASCIIDumbLossless($str) { + public static function convertToASCIIDumbLossless($str) + { $bytesleft = 0; $result = ''; $working = 0; $len = strlen($str); - for( $i = 0; $i < $len; $i++ ) { - $bytevalue = ord( $str[$i] ); - if( $bytevalue <= 0x7F ) { //0xxx xxxx - $result .= chr( $bytevalue ); + for ($i = 0; $i < $len; $i++) { + $bytevalue = ord($str[$i]); + if ($bytevalue <= 0x7F) { //0xxx xxxx + $result .= chr($bytevalue); $bytesleft = 0; - } elseif( $bytevalue <= 0xBF ) { //10xx xxxx + } elseif ($bytevalue <= 0xBF) { //10xx xxxx $working = $working << 6; $working += ($bytevalue & 0x3F); $bytesleft--; - if( $bytesleft <= 0 ) { + if ($bytesleft <= 0) { $result .= "&#" . $working . ";"; } - } elseif( $bytevalue <= 0xDF ) { //110x xxxx + } elseif ($bytevalue <= 0xDF) { //110x xxxx $working = $bytevalue & 0x1F; $bytesleft = 1; - } elseif( $bytevalue <= 0xEF ) { //1110 xxxx + } elseif ($bytevalue <= 0xEF) { //1110 xxxx $working = $bytevalue & 0x0F; $bytesleft = 2; } else { //1111 0xxx @@ -469,9 +526,10 @@ class HTMLPurifier_Encoder * characters, as long as PHP ignores the error code. If PHP starts * paying attention to the error code, iconv becomes unusable. * - * @returns Error code indicating severity of bug. + * @return int Error code indicating severity of bug. */ - public static function testIconvTruncateBug() { + public static function testIconvTruncateBug() + { static $code = null; if ($code === null) { // better not use iconv, otherwise infinite loop! @@ -481,7 +539,11 @@ class HTMLPurifier_Encoder } elseif (($c = strlen($r)) < 9000) { $code = self::ICONV_TRUNCATES; } elseif ($c > 9000) { - trigger_error('Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: include your iconv version as per phpversion()', E_USER_ERROR); + trigger_error( + 'Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: ' . + 'include your iconv version as per phpversion()', + E_USER_ERROR + ); } else { $code = self::ICONV_OK; } @@ -500,7 +562,8 @@ class HTMLPurifier_Encoder * @return Array of UTF-8 characters to their corresponding ASCII, * which can be used to "undo" any overzealous iconv action. */ - public static function testEncodingSupportsASCII($encoding, $bypass = false) { + public static function testEncodingSupportsASCII($encoding, $bypass = false) + { // All calls to iconv here are unsafe, proof by case analysis: // If ICONV_OK, no difference. // If ICONV_TRUNCATE, all calls involve one character inputs, @@ -508,7 +571,9 @@ class HTMLPurifier_Encoder // If ICONV_UNUSABLE, this call is irrelevant static $encodings = array(); if (!$bypass) { - if (isset($encodings[$encoding])) return $encodings[$encoding]; + if (isset($encodings[$encoding])) { + return $encodings[$encoding]; + } $lenc = strtolower($encoding); switch ($lenc) { case 'shift_jis': @@ -516,15 +581,18 @@ class HTMLPurifier_Encoder case 'johab': return array("\xE2\x82\xA9" => '\\'); } - if (strpos($lenc, 'iso-8859-') === 0) return array(); + if (strpos($lenc, 'iso-8859-') === 0) { + return array(); + } } $ret = array(); - if (self::unsafeIconv('UTF-8', $encoding, 'a') === false) return false; + if (self::unsafeIconv('UTF-8', $encoding, 'a') === false) { + return false; + } for ($i = 0x20; $i <= 0x7E; $i++) { // all printable ASCII chars $c = chr($i); // UTF-8 char $r = self::unsafeIconv('UTF-8', "$encoding//IGNORE", $c); // initial conversion - if ( - $r === '' || + if ($r === '' || // This line is needed for iconv implementations that do not // omit characters that do not exist in the target character set ($r === $c && self::unsafeIconv($encoding, 'UTF-8//IGNORE', $r) !== $c) @@ -538,8 +606,6 @@ class HTMLPurifier_Encoder $encodings[$encoding] = $ret; return $ret; } - - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/EntityLookup.php b/library/HTMLPurifier/EntityLookup.php index b4dfce94..f12ff13a 100644 --- a/library/HTMLPurifier/EntityLookup.php +++ b/library/HTMLPurifier/EntityLookup.php @@ -3,20 +3,23 @@ /** * Object that provides entity lookup table from entity name to character */ -class HTMLPurifier_EntityLookup { - +class HTMLPurifier_EntityLookup +{ /** * Assoc array of entity name to character represented. + * @type array */ public $table; /** * Sets up the entity lookup table from the serialized file contents. + * @param bool $file * @note The serialized contents are versioned, but were generated * using the maintenance script generate_entity_file.php * @warning This is not in constructor to help enforce the Singleton */ - public function setup($file = false) { + public function setup($file = false) + { if (!$file) { $file = HTMLPURIFIER_PREFIX . '/HTMLPurifier/EntityLookup/entities.ser'; } @@ -25,9 +28,11 @@ class HTMLPurifier_EntityLookup { /** * Retrieves sole instance of the object. - * @param Optional prototype of custom lookup table to overload with. + * @param bool|HTMLPurifier_EntityLookup $prototype Optional prototype of custom lookup table to overload with. + * @return HTMLPurifier_EntityLookup */ - public static function instance($prototype = false) { + public static function instance($prototype = false) + { // no references, since PHP doesn't copy unless modified static $instance = null; if ($prototype) { @@ -38,7 +43,6 @@ class HTMLPurifier_EntityLookup { } return $instance; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/EntityParser.php b/library/HTMLPurifier/EntityParser.php index 8c384472..61529dcd 100644 --- a/library/HTMLPurifier/EntityParser.php +++ b/library/HTMLPurifier/EntityParser.php @@ -12,19 +12,21 @@ class HTMLPurifier_EntityParser /** * Reference to entity lookup table. + * @type HTMLPurifier_EntityLookup */ protected $_entity_lookup; /** * Callback regex string for parsing entities. + * @type string */ protected $_substituteEntitiesRegex = -'/&(?:[#]x([a-fA-F0-9]+)|[#]0*(\d+)|([A-Za-z_:][A-Za-z0-9.\-_:]*));?/'; -// 1. hex 2. dec 3. string (XML style) - + '/&(?:[#]x([a-fA-F0-9]+)|[#]0*(\d+)|([A-Za-z_:][A-Za-z0-9.\-_:]*));?/'; + // 1. hex 2. dec 3. string (XML style) /** * Decimal to parsed string conversion table for special entities. + * @type array */ protected $_special_dec2str = array( @@ -37,6 +39,7 @@ class HTMLPurifier_EntityParser /** * Stripped entity names to decimal conversion table for special entities. + * @type array */ protected $_special_ent2dec = array( @@ -51,41 +54,45 @@ class HTMLPurifier_EntityParser * running this whenever you have parsed character is t3h 5uck, we run * it before everything else. * - * @param $string String to have non-special entities parsed. - * @returns Parsed string. + * @param string $string String to have non-special entities parsed. + * @return string Parsed string. */ - public function substituteNonSpecialEntities($string) { + public function substituteNonSpecialEntities($string) + { // it will try to detect missing semicolons, but don't rely on it return preg_replace_callback( $this->_substituteEntitiesRegex, array($this, 'nonSpecialEntityCallback'), $string - ); + ); } /** * Callback function for substituteNonSpecialEntities() that does the work. * - * @param $matches PCRE matches array, with 0 the entire match, and + * @param array $matches PCRE matches array, with 0 the entire match, and * either index 1, 2 or 3 set with a hex value, dec value, * or string (respectively). - * @returns Replacement string. + * @return string Replacement string. */ - protected function nonSpecialEntityCallback($matches) { + protected function nonSpecialEntityCallback($matches) + { // replaces all but big five $entity = $matches[0]; $is_num = (@$matches[0][1] === '#'); if ($is_num) { $is_hex = (@$entity[2] === 'x'); $code = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; - // abort for special characters - if (isset($this->_special_dec2str[$code])) return $entity; - + if (isset($this->_special_dec2str[$code])) { + return $entity; + } return HTMLPurifier_Encoder::unichr($code); } else { - if (isset($this->_special_ent2dec[$matches[3]])) return $entity; + if (isset($this->_special_ent2dec[$matches[3]])) { + return $entity; + } if (!$this->_entity_lookup) { $this->_entity_lookup = HTMLPurifier_EntityLookup::instance(); } @@ -103,14 +110,16 @@ class HTMLPurifier_EntityParser * @notice We try to avoid calling this function because otherwise, it * would have to be called a lot (for every parsed section). * - * @param $string String to have non-special entities parsed. - * @returns Parsed string. + * @param string $string String to have non-special entities parsed. + * @return string Parsed string. */ - public function substituteSpecialEntities($string) { + public function substituteSpecialEntities($string) + { return preg_replace_callback( $this->_substituteEntitiesRegex, array($this, 'specialEntityCallback'), - $string); + $string + ); } /** @@ -118,12 +127,13 @@ class HTMLPurifier_EntityParser * * This callback has same syntax as nonSpecialEntityCallback(). * - * @param $matches PCRE-style matches array, with 0 the entire match, and + * @param array $matches PCRE-style matches array, with 0 the entire match, and * either index 1, 2 or 3 set with a hex value, dec value, * or string (respectively). - * @returns Replacement string. + * @return string Replacement string. */ - protected function specialEntityCallback($matches) { + protected function specialEntityCallback($matches) + { $entity = $matches[0]; $is_num = (@$matches[0][1] === '#'); if ($is_num) { @@ -138,7 +148,6 @@ class HTMLPurifier_EntityParser $entity; } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ErrorCollector.php b/library/HTMLPurifier/ErrorCollector.php index 6713eaf7..d47e3f2e 100644 --- a/library/HTMLPurifier/ErrorCollector.php +++ b/library/HTMLPurifier/ErrorCollector.php @@ -16,16 +16,46 @@ class HTMLPurifier_ErrorCollector const MESSAGE = 2; const CHILDREN = 3; + /** + * @type array + */ protected $errors; + + /** + * @type array + */ protected $_current; + + /** + * @type array + */ protected $_stacks = array(array()); + + /** + * @type HTMLPurifier_Language + */ protected $locale; + + /** + * @type HTMLPurifier_Generator + */ protected $generator; + + /** + * @type HTMLPurifier_Context + */ protected $context; + /** + * @type array + */ protected $lines = array(); - public function __construct($context) { + /** + * @param HTMLPurifier_Context $context + */ + public function __construct($context) + { $this->locale =& $context->get('Locale'); $this->context = $context; $this->_current =& $this->_stacks[0]; @@ -34,13 +64,11 @@ class HTMLPurifier_ErrorCollector /** * Sends an error message to the collector for later use - * @param $severity int Error severity, PHP error style (don't use E_USER_) - * @param $msg string Error message text - * @param $subst1 string First substitution for $msg - * @param $subst2 string ... + * @param int $severity Error severity, PHP error style (don't use E_USER_) + * @param string $msg Error message text */ - public function send($severity, $msg) { - + public function send($severity, $msg) + { $args = array(); if (func_num_args() > 2) { $args = func_get_args(); @@ -50,7 +78,7 @@ class HTMLPurifier_ErrorCollector $token = $this->context->get('CurrentToken', true); $line = $token ? $token->line : $this->context->get('CurrentLine', true); - $col = $token ? $token->col : $this->context->get('CurrentCol', true); + $col = $token ? $token->col : $this->context->get('CurrentCol', true); $attr = $this->context->get('CurrentAttr', true); // perform special substitutions, also add custom parameters @@ -60,7 +88,9 @@ class HTMLPurifier_ErrorCollector } if (!is_null($attr)) { $subst['$CurrentAttr.Name'] = $attr; - if (isset($token->attr[$attr])) $subst['$CurrentAttr.Value'] = $token->attr[$attr]; + if (isset($token->attr[$attr])) { + $subst['$CurrentAttr.Value'] = $token->attr[$attr]; + } } if (empty($args)) { @@ -69,7 +99,9 @@ class HTMLPurifier_ErrorCollector $msg = $this->locale->formatMessage($msg, $args); } - if (!empty($subst)) $msg = strtr($msg, $subst); + if (!empty($subst)) { + $msg = strtr($msg, $subst); + } // (numerically indexed) $error = array( @@ -80,16 +112,15 @@ class HTMLPurifier_ErrorCollector ); $this->_current[] = $error; - // NEW CODE BELOW ... - - $struct = null; // Top-level errors are either: // TOKEN type, if $value is set appropriately, or // "syntax" type, if $value is null $new_struct = new HTMLPurifier_ErrorStruct(); $new_struct->type = HTMLPurifier_ErrorStruct::TOKEN; - if ($token) $new_struct->value = clone $token; + if ($token) { + $new_struct->value = clone $token; + } if (is_int($line) && is_int($col)) { if (isset($this->lines[$line][$col])) { $struct = $this->lines[$line][$col]; @@ -128,30 +159,34 @@ class HTMLPurifier_ErrorCollector /** * Retrieves raw error data for custom formatter to use - * @param List of arrays in format of array(line of error, - * error severity, error message, - * recursive sub-errors array) */ - public function getRaw() { + public function getRaw() + { return $this->errors; } /** * Default HTML formatting implementation for error messages - * @param $config Configuration array, vital for HTML output nature - * @param $errors Errors array to display; used for recursion. + * @param HTMLPurifier_Config $config Configuration, vital for HTML output nature + * @param array $errors Errors array to display; used for recursion. + * @return string */ - public function getHTMLFormatted($config, $errors = null) { + public function getHTMLFormatted($config, $errors = null) + { $ret = array(); $this->generator = new HTMLPurifier_Generator($config, $this->context); - if ($errors === null) $errors = $this->errors; + if ($errors === null) { + $errors = $this->errors; + } // 'At line' message needs to be removed // generation code for new structure goes here. It needs to be recursive. foreach ($this->lines as $line => $col_array) { - if ($line == -1) continue; + if ($line == -1) { + continue; + } foreach ($col_array as $col => $struct) { $this->_renderStruct($ret, $struct, $line, $col); } @@ -168,7 +203,8 @@ class HTMLPurifier_ErrorCollector } - private function _renderStruct(&$ret, $struct, $line = null, $col = null) { + private function _renderStruct(&$ret, $struct, $line = null, $col = null) + { $stack = array($struct); $context_stack = array(array()); while ($current = array_pop($stack)) { @@ -194,7 +230,7 @@ class HTMLPurifier_ErrorCollector //$string .= ''; $ret[] = $string; } - foreach ($current->children as $type => $array) { + foreach ($current->children as $array) { $context[] = $current; $stack = array_merge($stack, array_reverse($array, true)); for ($i = count($array); $i > 0; $i--) { @@ -203,7 +239,6 @@ class HTMLPurifier_ErrorCollector } } } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/ErrorStruct.php b/library/HTMLPurifier/ErrorStruct.php index 9bc8996e..cf869d32 100644 --- a/library/HTMLPurifier/ErrorStruct.php +++ b/library/HTMLPurifier/ErrorStruct.php @@ -19,6 +19,7 @@ class HTMLPurifier_ErrorStruct /** * Type of this struct. + * @type string */ public $type; @@ -28,11 +29,13 @@ class HTMLPurifier_ErrorStruct * - TOKEN: Instance of HTMLPurifier_Token * - ATTR: array('attr-name', 'value') * - CSSPROP: array('prop-name', 'value') + * @type mixed */ public $value; /** * Errors registered for this structure. + * @type array */ public $errors = array(); @@ -40,10 +43,17 @@ class HTMLPurifier_ErrorStruct * Child ErrorStructs that are from this structure. For example, a TOKEN * ErrorStruct would contain ATTR ErrorStructs. This is a multi-dimensional * array in structure: [TYPE]['identifier'] + * @type array */ public $children = array(); - public function getChild($type, $id) { + /** + * @param string $type + * @param string $id + * @return mixed + */ + public function getChild($type, $id) + { if (!isset($this->children[$type][$id])) { $this->children[$type][$id] = new HTMLPurifier_ErrorStruct(); $this->children[$type][$id]->type = $type; @@ -51,10 +61,14 @@ class HTMLPurifier_ErrorStruct return $this->children[$type][$id]; } - public function addError($severity, $message) { + /** + * @param int $severity + * @param string $message + */ + public function addError($severity, $message) + { $this->errors[] = array($severity, $message); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Filter.php b/library/HTMLPurifier/Filter.php index 9a0e7b09..c1f41ee1 100644 --- a/library/HTMLPurifier/Filter.php +++ b/library/HTMLPurifier/Filter.php @@ -23,24 +23,34 @@ class HTMLPurifier_Filter { /** - * Name of the filter for identification purposes + * Name of the filter for identification purposes. + * @type string */ public $name; /** * Pre-processor function, handles HTML before HTML Purifier + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string */ - public function preFilter($html, $config, $context) { + public function preFilter($html, $config, $context) + { return $html; } /** * Post-processor function, handles HTML after HTML Purifier + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string */ - public function postFilter($html, $config, $context) { + public function postFilter($html, $config, $context) + { return $html; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Filter/ExtractStyleBlocks.php b/library/HTMLPurifier/Filter/ExtractStyleBlocks.php index df937ace..08e62c16 100644 --- a/library/HTMLPurifier/Filter/ExtractStyleBlocks.php +++ b/library/HTMLPurifier/Filter/ExtractStyleBlocks.php @@ -4,7 +4,9 @@ // understand how to interpret this filter if it's a static method. // It's all really silly, but if we go this route it might be reasonable // to coalesce all of these methods into one. -function htmlpurifier_filter_extractstyleblocks_muteerrorhandler() {} +function htmlpurifier_filter_extractstyleblocks_muteerrorhandler() +{ +} /** * This filter extracts #isU', array($this, 'styleCallback'), $html); $style_blocks = $this->_styleMatches; $this->_styleMatches = array(); // reset @@ -69,12 +110,14 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter /** * Takes CSS (the stuff found in in a font-family prop). if ($config->get('Filter.ExtractStyleBlocks.Escaping')) { $css = str_replace( - array('<', '>', '&'), + array('<', '>', '&'), array('\3C ', '\3E ', '\26 '), $css ); } return $css; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Filter/YouTube.php b/library/HTMLPurifier/Filter/YouTube.php index 23df221e..411519ad 100644 --- a/library/HTMLPurifier/Filter/YouTube.php +++ b/library/HTMLPurifier/Filter/YouTube.php @@ -3,36 +3,62 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter { + /** + * @type string + */ public $name = 'YouTube'; - public function preFilter($html, $config, $context) { - $pre_regex = '#]+>.+?'. + /** + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function preFilter($html, $config, $context) + { + $pre_regex = '#]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?#s'; $pre_replace = '\1'; return preg_replace($pre_regex, $pre_replace, $html); } - public function postFilter($html, $config, $context) { + /** + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function postFilter($html, $config, $context) + { $post_regex = '#((?:v|cp)/[A-Za-z0-9\-_=]+)#'; return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html); } - protected function armorUrl($url) { + /** + * @param $url + * @return string + */ + protected function armorUrl($url) + { return str_replace('--', '--', $url); } - protected function postFilterCallback($matches) { + /** + * @param array $matches + * @return string + */ + protected function postFilterCallback($matches) + { $url = $this->armorUrl($matches[1]); - return ''. - ''. - ''. - ''; - + return '' . + '' . + '' . + ''; } } diff --git a/library/HTMLPurifier/Generator.php b/library/HTMLPurifier/Generator.php index fee1a5f8..6fb56871 100644 --- a/library/HTMLPurifier/Generator.php +++ b/library/HTMLPurifier/Generator.php @@ -11,52 +11,61 @@ class HTMLPurifier_Generator { /** - * Whether or not generator should produce XML output + * Whether or not generator should produce XML output. + * @type bool */ private $_xhtml = true; /** - * :HACK: Whether or not generator should comment the insides of )#si', - array($this, 'scriptCallback'), $html); + $html = preg_replace_callback( + '#(]*>)(\s*[^<].+?)()#si', + array($this, 'scriptCallback'), + $html + ); } $html = $this->normalize($html, $config, $context); @@ -55,15 +69,15 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer if ($maintain_line_numbers) { $current_line = 1; - $current_col = 0; + $current_col = 0; $length = strlen($html); } else { $current_line = false; - $current_col = false; + $current_col = false; $length = false; } $context->register('CurrentLine', $current_line); - $context->register('CurrentCol', $current_col); + $context->register('CurrentCol', $current_col); $nl = "\n"; // how often to manually recalculate. This will ALWAYS be right, // but it's pretty wasteful. Set to 0 to turn off @@ -77,16 +91,14 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer // for testing synchronization $loops = 0; - while(++$loops) { - + while (++$loops) { // $cursor is either at the start of a token, or inside of // a tag (i.e. there was a < immediately before it), as indicated // by $inside_tag if ($maintain_line_numbers) { - // $rcursor, however, is always at the start of a token. - $rcursor = $cursor - (int) $inside_tag; + $rcursor = $cursor - (int)$inside_tag; // Column number is cheap, so we calculate it every round. // We're interested at the *end* of the newline string, so @@ -96,14 +108,11 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer $current_col = $rcursor - (is_bool($nl_pos) ? 0 : $nl_pos + 1); // recalculate lines - if ( - $synchronize_interval && // synchronization is on - $cursor > 0 && // cursor is further than zero - $loops % $synchronize_interval === 0 // time to synchronize! - ) { + if ($synchronize_interval && // synchronization is on + $cursor > 0 && // cursor is further than zero + $loops % $synchronize_interval === 0) { // time to synchronize! $current_line = 1 + $this->substrCount($html, $nl, 0, $cursor); } - } $position_next_lt = strpos($html, '<', $cursor); @@ -119,35 +128,42 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer if (!$inside_tag && $position_next_lt !== false) { // We are not inside tag and there still is another tag to parse $token = new - HTMLPurifier_Token_Text( - $this->parseData( - substr( - $html, $cursor, $position_next_lt - $cursor - ) + HTMLPurifier_Token_Text( + $this->parseData( + substr( + $html, + $cursor, + $position_next_lt - $cursor ) - ); + ) + ); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor); } $array[] = $token; - $cursor = $position_next_lt + 1; + $cursor = $position_next_lt + 1; $inside_tag = true; continue; } elseif (!$inside_tag) { // We are not inside tag but there are no more tags // If we're already at the end, break - if ($cursor === strlen($html)) break; + if ($cursor === strlen($html)) { + break; + } // Create Text of rest of string $token = new - HTMLPurifier_Token_Text( - $this->parseData( - substr( - $html, $cursor - ) + HTMLPurifier_Token_Text( + $this->parseData( + substr( + $html, + $cursor ) - ); - if ($maintain_line_numbers) $token->rawPosition($current_line, $current_col); + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + } $array[] = $token; break; } elseif ($inside_tag && $position_next_gt !== false) { @@ -171,16 +187,16 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer } // Check if it's a comment - if ( - substr($segment, 0, 3) === '!--' - ) { + if (substr($segment, 0, 3) === '!--') { // re-determine segment length, looking for --> $position_comment_end = strpos($html, '-->', $cursor); if ($position_comment_end === false) { // uh oh, we have a comment that extends to // infinity. Can't be helped: set comment // end position to end of string - if ($e) $e->send(E_WARNING, 'Lexer: Unclosed comment'); + if ($e) { + $e->send(E_WARNING, 'Lexer: Unclosed comment'); + } $position_comment_end = strlen($html); $end = true; } else { @@ -189,11 +205,13 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer $strlen_segment = $position_comment_end - $cursor; $segment = substr($html, $cursor, $strlen_segment); $token = new - HTMLPurifier_Token_Comment( - substr( - $segment, 3, $strlen_segment - 3 - ) - ); + HTMLPurifier_Token_Comment( + substr( + $segment, + 3, + $strlen_segment - 3 + ) + ); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment); @@ -205,7 +223,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer } // Check if it's an end tag - $is_end_tag = (strpos($segment,'/') === 0); + $is_end_tag = (strpos($segment, '/') === 0); if ($is_end_tag) { $type = substr($segment, 1); $token = new HTMLPurifier_Token_End($type); @@ -224,7 +242,9 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer // text and go our merry way if (!ctype_alpha($segment[0])) { // XML: $segment[0] !== '_' && $segment[0] !== ':' - if ($e) $e->send(E_NOTICE, 'Lexer: Unescaped lt'); + if ($e) { + $e->send(E_NOTICE, 'Lexer: Unescaped lt'); + } $token = new HTMLPurifier_Token_Text('<'); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); @@ -239,7 +259,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer // trailing slash. Remember, we could have a tag like
, so // any later token processing scripts must convert improperly // classified EmptyTags from StartTags. - $is_self_closing = (strrpos($segment,'/') === $strlen_segment-1); + $is_self_closing = (strrpos($segment, '/') === $strlen_segment - 1); if ($is_self_closing) { $strlen_segment--; $segment = substr($segment, 0, $strlen_segment); @@ -269,14 +289,16 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer $attribute_string = trim( substr( - $segment, $position_first_space + $segment, + $position_first_space ) ); if ($attribute_string) { $attr = $this->parseAttributeString( - $attribute_string - , $config, $context - ); + $attribute_string, + $config, + $context + ); } else { $attr = array(); } @@ -296,15 +318,19 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer continue; } else { // inside tag, but there's no ending > sign - if ($e) $e->send(E_WARNING, 'Lexer: Missing gt'); + if ($e) { + $e->send(E_WARNING, 'Lexer: Missing gt'); + } $token = new - HTMLPurifier_Token_Text( - '<' . - $this->parseData( - substr($html, $cursor) - ) - ); - if ($maintain_line_numbers) $token->rawPosition($current_line, $current_col); + HTMLPurifier_Token_Text( + '<' . + $this->parseData( + substr($html, $cursor) + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + } // no cursor scroll? Hmm... $array[] = $token; break; @@ -319,8 +345,14 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer /** * PHP 5.0.x compatible substr_count that implements offset and length + * @param string $haystack + * @param string $needle + * @param int $offset + * @param int $length + * @return int */ - protected function substrCount($haystack, $needle, $offset, $length) { + protected function substrCount($haystack, $needle, $offset, $length) + { static $oldVersion; if ($oldVersion === null) { $oldVersion = version_compare(PHP_VERSION, '5.1', '<'); @@ -336,13 +368,18 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer /** * Takes the inside of an HTML tag and makes an assoc array of attributes. * - * @param $string Inside of tag excluding name. - * @returns Assoc array of attributes. + * @param string $string Inside of tag excluding name. + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array Assoc array of attributes. */ - public function parseAttributeString($string, $config, $context) { - $string = (string) $string; // quick typecast + public function parseAttributeString($string, $config, $context) + { + $string = (string)$string; // quick typecast - if ($string == '') return array(); // no attributes + if ($string == '') { + return array(); + } // no attributes $e = false; if ($config->get('Core.CollectErrors')) { @@ -361,42 +398,50 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer list($key, $quoted_value) = explode('=', $string); $quoted_value = trim($quoted_value); if (!$key) { - if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } return array(); } - if (!$quoted_value) return array($key => ''); + if (!$quoted_value) { + return array($key => ''); + } $first_char = @$quoted_value[0]; - $last_char = @$quoted_value[strlen($quoted_value)-1]; + $last_char = @$quoted_value[strlen($quoted_value) - 1]; $same_quote = ($first_char == $last_char); $open_quote = ($first_char == '"' || $first_char == "'"); - if ( $same_quote && $open_quote) { + if ($same_quote && $open_quote) { // well behaved $value = substr($quoted_value, 1, strlen($quoted_value) - 2); } else { // not well behaved if ($open_quote) { - if ($e) $e->send(E_ERROR, 'Lexer: Missing end quote'); + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing end quote'); + } $value = substr($quoted_value, 1); } else { $value = $quoted_value; } } - if ($value === false) $value = ''; + if ($value === false) { + $value = ''; + } return array($key => $this->parseData($value)); } // setup loop environment - $array = array(); // return assoc array of attributes + $array = array(); // return assoc array of attributes $cursor = 0; // current position in string (moves forward) - $size = strlen($string); // size of the string (stays the same) + $size = strlen($string); // size of the string (stays the same) // if we have unquoted attributes, the parser expects a terminating // space, so let's guarantee that there's always a terminating space. $string .= ' '; - while(true) { + while (true) { if ($cursor >= $size) { break; @@ -415,7 +460,9 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer $key = substr($string, $key_begin, $key_end - $key_begin); if (!$key) { - if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } $cursor += strcspn($string, $this->_whitespace, $cursor + 1); // prevent infinite loop continue; // empty key } @@ -467,24 +514,25 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer } $value = substr($string, $value_begin, $value_end - $value_begin); - if ($value === false) $value = ''; + if ($value === false) { + $value = ''; + } $array[$key] = $this->parseData($value); $cursor++; - } else { // boolattr if ($key !== '') { $array[$key] = $key; } else { // purely theoretical - if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } } - } } return $array; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Lexer/PH5P.php b/library/HTMLPurifier/Lexer/PH5P.php index faf00b82..a4587e4c 100644 --- a/library/HTMLPurifier/Lexer/PH5P.php +++ b/library/HTMLPurifier/Lexer/PH5P.php @@ -3,16 +3,23 @@ /** * Experimental HTML5-based parser using Jeroen van der Meer's PH5P library. * Occupies space in the HTML5 pseudo-namespace, which may cause conflicts. - * + * * @note * Recent changes to PHP's DOM extension have resulted in some fatal * error conditions with the original version of PH5P. Pending changes, - * this lexer will punt to DirectLex if DOM throughs an exception. + * this lexer will punt to DirectLex if DOM throws an exception. */ -class HTMLPurifier_Lexer_PH5P extends HTMLPurifier_Lexer_DOMLex { - - public function tokenizeHTML($html, $config, $context) { +class HTMLPurifier_Lexer_PH5P extends HTMLPurifier_Lexer_DOMLex +{ + /** + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] + */ + public function tokenizeHTML($html, $config, $context) + { $new_html = $this->normalize($html, $config, $context); $new_html = $this->wrapHTML($new_html, $config, $context); try { @@ -27,40 +34,42 @@ class HTMLPurifier_Lexer_PH5P extends HTMLPurifier_Lexer_DOMLex { $tokens = array(); $this->tokenizeDOM( $doc->getElementsByTagName('html')->item(0)-> // - getElementsByTagName('body')->item(0)-> // - getElementsByTagName('div')->item(0) //
- , $tokens); + getElementsByTagName('body')->item(0)-> // + getElementsByTagName('div')->item(0) //
+ , + $tokens + ); return $tokens; } - } /* -Copyright 2007 Jeroen van der Meer +Copyright 2007 Jeroen van der Meer -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -class HTML5 { +class HTML5 +{ private $data; private $char; private $EOF; @@ -69,89 +78,418 @@ class HTML5 { private $token; private $content_model; private $escape = false; - private $entities = array('AElig;','AElig','AMP;','AMP','Aacute;','Aacute', - 'Acirc;','Acirc','Agrave;','Agrave','Alpha;','Aring;','Aring','Atilde;', - 'Atilde','Auml;','Auml','Beta;','COPY;','COPY','Ccedil;','Ccedil','Chi;', - 'Dagger;','Delta;','ETH;','ETH','Eacute;','Eacute','Ecirc;','Ecirc','Egrave;', - 'Egrave','Epsilon;','Eta;','Euml;','Euml','GT;','GT','Gamma;','Iacute;', - 'Iacute','Icirc;','Icirc','Igrave;','Igrave','Iota;','Iuml;','Iuml','Kappa;', - 'LT;','LT','Lambda;','Mu;','Ntilde;','Ntilde','Nu;','OElig;','Oacute;', - 'Oacute','Ocirc;','Ocirc','Ograve;','Ograve','Omega;','Omicron;','Oslash;', - 'Oslash','Otilde;','Otilde','Ouml;','Ouml','Phi;','Pi;','Prime;','Psi;', - 'QUOT;','QUOT','REG;','REG','Rho;','Scaron;','Sigma;','THORN;','THORN', - 'TRADE;','Tau;','Theta;','Uacute;','Uacute','Ucirc;','Ucirc','Ugrave;', - 'Ugrave','Upsilon;','Uuml;','Uuml','Xi;','Yacute;','Yacute','Yuml;','Zeta;', - 'aacute;','aacute','acirc;','acirc','acute;','acute','aelig;','aelig', - 'agrave;','agrave','alefsym;','alpha;','amp;','amp','and;','ang;','apos;', - 'aring;','aring','asymp;','atilde;','atilde','auml;','auml','bdquo;','beta;', - 'brvbar;','brvbar','bull;','cap;','ccedil;','ccedil','cedil;','cedil', - 'cent;','cent','chi;','circ;','clubs;','cong;','copy;','copy','crarr;', - 'cup;','curren;','curren','dArr;','dagger;','darr;','deg;','deg','delta;', - 'diams;','divide;','divide','eacute;','eacute','ecirc;','ecirc','egrave;', - 'egrave','empty;','emsp;','ensp;','epsilon;','equiv;','eta;','eth;','eth', - 'euml;','euml','euro;','exist;','fnof;','forall;','frac12;','frac12', - 'frac14;','frac14','frac34;','frac34','frasl;','gamma;','ge;','gt;','gt', - 'hArr;','harr;','hearts;','hellip;','iacute;','iacute','icirc;','icirc', - 'iexcl;','iexcl','igrave;','igrave','image;','infin;','int;','iota;', - 'iquest;','iquest','isin;','iuml;','iuml','kappa;','lArr;','lambda;','lang;', - 'laquo;','laquo','larr;','lceil;','ldquo;','le;','lfloor;','lowast;','loz;', - 'lrm;','lsaquo;','lsquo;','lt;','lt','macr;','macr','mdash;','micro;','micro', - 'middot;','middot','minus;','mu;','nabla;','nbsp;','nbsp','ndash;','ne;', - 'ni;','not;','not','notin;','nsub;','ntilde;','ntilde','nu;','oacute;', - 'oacute','ocirc;','ocirc','oelig;','ograve;','ograve','oline;','omega;', - 'omicron;','oplus;','or;','ordf;','ordf','ordm;','ordm','oslash;','oslash', - 'otilde;','otilde','otimes;','ouml;','ouml','para;','para','part;','permil;', - 'perp;','phi;','pi;','piv;','plusmn;','plusmn','pound;','pound','prime;', - 'prod;','prop;','psi;','quot;','quot','rArr;','radic;','rang;','raquo;', - 'raquo','rarr;','rceil;','rdquo;','real;','reg;','reg','rfloor;','rho;', - 'rlm;','rsaquo;','rsquo;','sbquo;','scaron;','sdot;','sect;','sect','shy;', - 'shy','sigma;','sigmaf;','sim;','spades;','sub;','sube;','sum;','sup1;', - 'sup1','sup2;','sup2','sup3;','sup3','sup;','supe;','szlig;','szlig','tau;', - 'there4;','theta;','thetasym;','thinsp;','thorn;','thorn','tilde;','times;', - 'times','trade;','uArr;','uacute;','uacute','uarr;','ucirc;','ucirc', - 'ugrave;','ugrave','uml;','uml','upsih;','upsilon;','uuml;','uuml','weierp;', - 'xi;','yacute;','yacute','yen;','yen','yuml;','yuml','zeta;','zwj;','zwnj;'); - - const PCDATA = 0; - const RCDATA = 1; - const CDATA = 2; + private $entities = array( + 'AElig;', + 'AElig', + 'AMP;', + 'AMP', + 'Aacute;', + 'Aacute', + 'Acirc;', + 'Acirc', + 'Agrave;', + 'Agrave', + 'Alpha;', + 'Aring;', + 'Aring', + 'Atilde;', + 'Atilde', + 'Auml;', + 'Auml', + 'Beta;', + 'COPY;', + 'COPY', + 'Ccedil;', + 'Ccedil', + 'Chi;', + 'Dagger;', + 'Delta;', + 'ETH;', + 'ETH', + 'Eacute;', + 'Eacute', + 'Ecirc;', + 'Ecirc', + 'Egrave;', + 'Egrave', + 'Epsilon;', + 'Eta;', + 'Euml;', + 'Euml', + 'GT;', + 'GT', + 'Gamma;', + 'Iacute;', + 'Iacute', + 'Icirc;', + 'Icirc', + 'Igrave;', + 'Igrave', + 'Iota;', + 'Iuml;', + 'Iuml', + 'Kappa;', + 'LT;', + 'LT', + 'Lambda;', + 'Mu;', + 'Ntilde;', + 'Ntilde', + 'Nu;', + 'OElig;', + 'Oacute;', + 'Oacute', + 'Ocirc;', + 'Ocirc', + 'Ograve;', + 'Ograve', + 'Omega;', + 'Omicron;', + 'Oslash;', + 'Oslash', + 'Otilde;', + 'Otilde', + 'Ouml;', + 'Ouml', + 'Phi;', + 'Pi;', + 'Prime;', + 'Psi;', + 'QUOT;', + 'QUOT', + 'REG;', + 'REG', + 'Rho;', + 'Scaron;', + 'Sigma;', + 'THORN;', + 'THORN', + 'TRADE;', + 'Tau;', + 'Theta;', + 'Uacute;', + 'Uacute', + 'Ucirc;', + 'Ucirc', + 'Ugrave;', + 'Ugrave', + 'Upsilon;', + 'Uuml;', + 'Uuml', + 'Xi;', + 'Yacute;', + 'Yacute', + 'Yuml;', + 'Zeta;', + 'aacute;', + 'aacute', + 'acirc;', + 'acirc', + 'acute;', + 'acute', + 'aelig;', + 'aelig', + 'agrave;', + 'agrave', + 'alefsym;', + 'alpha;', + 'amp;', + 'amp', + 'and;', + 'ang;', + 'apos;', + 'aring;', + 'aring', + 'asymp;', + 'atilde;', + 'atilde', + 'auml;', + 'auml', + 'bdquo;', + 'beta;', + 'brvbar;', + 'brvbar', + 'bull;', + 'cap;', + 'ccedil;', + 'ccedil', + 'cedil;', + 'cedil', + 'cent;', + 'cent', + 'chi;', + 'circ;', + 'clubs;', + 'cong;', + 'copy;', + 'copy', + 'crarr;', + 'cup;', + 'curren;', + 'curren', + 'dArr;', + 'dagger;', + 'darr;', + 'deg;', + 'deg', + 'delta;', + 'diams;', + 'divide;', + 'divide', + 'eacute;', + 'eacute', + 'ecirc;', + 'ecirc', + 'egrave;', + 'egrave', + 'empty;', + 'emsp;', + 'ensp;', + 'epsilon;', + 'equiv;', + 'eta;', + 'eth;', + 'eth', + 'euml;', + 'euml', + 'euro;', + 'exist;', + 'fnof;', + 'forall;', + 'frac12;', + 'frac12', + 'frac14;', + 'frac14', + 'frac34;', + 'frac34', + 'frasl;', + 'gamma;', + 'ge;', + 'gt;', + 'gt', + 'hArr;', + 'harr;', + 'hearts;', + 'hellip;', + 'iacute;', + 'iacute', + 'icirc;', + 'icirc', + 'iexcl;', + 'iexcl', + 'igrave;', + 'igrave', + 'image;', + 'infin;', + 'int;', + 'iota;', + 'iquest;', + 'iquest', + 'isin;', + 'iuml;', + 'iuml', + 'kappa;', + 'lArr;', + 'lambda;', + 'lang;', + 'laquo;', + 'laquo', + 'larr;', + 'lceil;', + 'ldquo;', + 'le;', + 'lfloor;', + 'lowast;', + 'loz;', + 'lrm;', + 'lsaquo;', + 'lsquo;', + 'lt;', + 'lt', + 'macr;', + 'macr', + 'mdash;', + 'micro;', + 'micro', + 'middot;', + 'middot', + 'minus;', + 'mu;', + 'nabla;', + 'nbsp;', + 'nbsp', + 'ndash;', + 'ne;', + 'ni;', + 'not;', + 'not', + 'notin;', + 'nsub;', + 'ntilde;', + 'ntilde', + 'nu;', + 'oacute;', + 'oacute', + 'ocirc;', + 'ocirc', + 'oelig;', + 'ograve;', + 'ograve', + 'oline;', + 'omega;', + 'omicron;', + 'oplus;', + 'or;', + 'ordf;', + 'ordf', + 'ordm;', + 'ordm', + 'oslash;', + 'oslash', + 'otilde;', + 'otilde', + 'otimes;', + 'ouml;', + 'ouml', + 'para;', + 'para', + 'part;', + 'permil;', + 'perp;', + 'phi;', + 'pi;', + 'piv;', + 'plusmn;', + 'plusmn', + 'pound;', + 'pound', + 'prime;', + 'prod;', + 'prop;', + 'psi;', + 'quot;', + 'quot', + 'rArr;', + 'radic;', + 'rang;', + 'raquo;', + 'raquo', + 'rarr;', + 'rceil;', + 'rdquo;', + 'real;', + 'reg;', + 'reg', + 'rfloor;', + 'rho;', + 'rlm;', + 'rsaquo;', + 'rsquo;', + 'sbquo;', + 'scaron;', + 'sdot;', + 'sect;', + 'sect', + 'shy;', + 'shy', + 'sigma;', + 'sigmaf;', + 'sim;', + 'spades;', + 'sub;', + 'sube;', + 'sum;', + 'sup1;', + 'sup1', + 'sup2;', + 'sup2', + 'sup3;', + 'sup3', + 'sup;', + 'supe;', + 'szlig;', + 'szlig', + 'tau;', + 'there4;', + 'theta;', + 'thetasym;', + 'thinsp;', + 'thorn;', + 'thorn', + 'tilde;', + 'times;', + 'times', + 'trade;', + 'uArr;', + 'uacute;', + 'uacute', + 'uarr;', + 'ucirc;', + 'ucirc', + 'ugrave;', + 'ugrave', + 'uml;', + 'uml', + 'upsih;', + 'upsilon;', + 'uuml;', + 'uuml', + 'weierp;', + 'xi;', + 'yacute;', + 'yacute', + 'yen;', + 'yen', + 'yuml;', + 'yuml', + 'zeta;', + 'zwj;', + 'zwnj;' + ); + + const PCDATA = 0; + const RCDATA = 1; + const CDATA = 2; const PLAINTEXT = 3; - const DOCTYPE = 0; + const DOCTYPE = 0; const STARTTAG = 1; - const ENDTAG = 2; - const COMMENT = 3; + const ENDTAG = 2; + const COMMENT = 3; const CHARACTR = 4; - const EOF = 5; - - public function __construct($data) { + const EOF = 5; + public function __construct($data) + { $this->data = $data; $this->char = -1; - $this->EOF = strlen($data); + $this->EOF = strlen($data); $this->tree = new HTML5TreeConstructer; $this->content_model = self::PCDATA; $this->state = 'data'; - while($this->state !== null) { - $this->{$this->state.'State'}(); + while ($this->state !== null) { + $this->{$this->state . 'State'}(); } } - public function save() { + public function save() + { return $this->tree->save(); } - private function char() { + private function char() + { return ($this->char < $this->EOF) ? $this->data[$this->char] : false; } - private function character($s, $l = 0) { - if($s + $l < $this->EOF) { - if($l === 0) { + private function character($s, $l = 0) + { + if ($s + $l < $this->EOF) { + if ($l === 0) { return $this->data[$s]; } else { return substr($this->data, $s, $l); @@ -159,46 +497,52 @@ class HTML5 { } } - private function characters($char_class, $start) { - return preg_replace('#^(['.$char_class.']+).*#s', '\\1', substr($this->data, $start)); + private function characters($char_class, $start) + { + return preg_replace('#^([' . $char_class . ']+).*#s', '\\1', substr($this->data, $start)); } - private function dataState() { + private function dataState() + { // Consume the next input character $this->char++; $char = $this->char(); - if($char === '&' && ($this->content_model === self::PCDATA || $this->content_model === self::RCDATA)) { + if ($char === '&' && ($this->content_model === self::PCDATA || $this->content_model === self::RCDATA)) { /* U+0026 AMPERSAND (&) When the content model flag is set to one of the PCDATA or RCDATA states: switch to the entity data state. Otherwise: treat it as per the "anything else" entry below. */ $this->state = 'entityData'; - } elseif($char === '-') { + } elseif ($char === '-') { /* If the content model flag is set to either the RCDATA state or the CDATA state, and the escape flag is false, and there are at least three characters before this one in the input stream, and the last four characters in the input stream, including this one, are U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, and U+002D HYPHEN-MINUS (""), set the escape flag to false. */ - if(($this->content_model === self::RCDATA || - $this->content_model === self::CDATA) && $this->escape === true && - $this->character($this->char, 3) === '-->') { + if (($this->content_model === self::RCDATA || + $this->content_model === self::CDATA) && $this->escape === true && + $this->character($this->char, 3) === '-->' + ) { $this->escape = false; } /* In any case, emit the input character as a character token. Stay in the data state. */ - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => $char - )); + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Emit an end-of-file token. */ $this->EOF(); - } elseif($this->content_model === self::PLAINTEXT) { + } elseif ($this->content_model === self::PLAINTEXT) { /* When the content model flag is set to the PLAINTEXT state THIS DIFFERS GREATLY FROM THE SPEC: Get the remaining characters of the text and emit it as a character token. */ - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => substr($this->data, $this->char) - )); + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => substr($this->data, $this->char) + ) + ); $this->EOF(); @@ -250,37 +599,43 @@ class HTML5 { THIS DIFFERS GREATLY FROM THE SPEC: Get as many character that otherwise would also be treated as a character token and emit it as a single character token. Stay in the data state. */ - $len = strcspn($this->data, '<&', $this->char); + $len = strcspn($this->data, '<&', $this->char); $char = substr($this->data, $this->char, $len); $this->char += $len - 1; - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => $char - )); + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); $this->state = 'data'; } } - private function entityDataState() { + private function entityDataState() + { // Attempt to consume an entity. $entity = $this->entity(); // If nothing is returned, emit a U+0026 AMPERSAND character token. // Otherwise, emit the character token that was returned. $char = (!$entity) ? '&' : $entity; - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => $char - )); + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); // Finally, switch to the data state. $this->state = 'data'; } - private function tagOpenState() { - switch($this->content_model) { + private function tagOpenState() + { + switch ($this->content_model) { case self::RCDATA: case self::CDATA: /* If the next input character is a U+002F SOLIDUS (/) character, @@ -288,19 +643,21 @@ class HTML5 { input character is not a U+002F SOLIDUS (/) character, emit a U+003C LESS-THAN SIGN character token and switch to the data state to process the next input character. */ - if($this->character($this->char + 1) === '/') { + if ($this->character($this->char + 1) === '/') { $this->char++; $this->state = 'closeTagOpen'; } else { - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => '<' - )); + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<' + ) + ); $this->state = 'data'; } - break; + break; case self::PCDATA: // If the content model flag is set to the PCDATA state @@ -308,42 +665,44 @@ class HTML5 { $this->char++; $char = $this->char(); - if($char === '!') { + if ($char === '!') { /* U+0021 EXCLAMATION MARK (!) Switch to the markup declaration open state. */ $this->state = 'markupDeclarationOpen'; - } elseif($char === '/') { + } elseif ($char === '/') { /* U+002F SOLIDUS (/) Switch to the close tag open state. */ $this->state = 'closeTagOpen'; - } elseif(preg_match('/^[A-Za-z]$/', $char)) { + } elseif (preg_match('/^[A-Za-z]$/', $char)) { /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z Create a new start tag token, set its tag name to the lowercase version of the input character (add 0x0020 to the character's code point), then switch to the tag name state. (Don't emit the token yet; further details will be filled in before it is emitted.) */ $this->token = array( - 'name' => strtolower($char), - 'type' => self::STARTTAG, - 'attr' => array() + 'name' => strtolower($char), + 'type' => self::STARTTAG, + 'attr' => array() ); $this->state = 'tagName'; - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+003E GREATER-THAN SIGN character token. Switch to the data state. */ - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => '<>' - )); + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<>' + ) + ); $this->state = 'data'; - } elseif($char === '?') { + } elseif ($char === '?') { /* U+003F QUESTION MARK (?) Parse error. Switch to the bogus comment state. */ $this->state = 'bogusComment'; @@ -352,25 +711,31 @@ class HTML5 { /* Anything else Parse error. Emit a U+003C LESS-THAN SIGN character token and reconsume the current input character in the data state. */ - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => '<' - )); + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<' + ) + ); $this->char--; $this->state = 'data'; } - break; + break; } } - private function closeTagOpenState() { + private function closeTagOpenState() + { $next_node = strtolower($this->characters('A-Za-z', $this->char + 1)); $the_same = count($this->tree->stack) > 0 && $next_node === end($this->tree->stack)->nodeName; - if(($this->content_model === self::RCDATA || $this->content_model === self::CDATA) && - (!$the_same || ($the_same && (!preg_match('/[\t\n\x0b\x0c >\/]/', - $this->character($this->char + 1 + strlen($next_node))) || $this->EOF === $this->char)))) { + if (($this->content_model === self::RCDATA || $this->content_model === self::CDATA) && + (!$the_same || ($the_same && (!preg_match( + '/[\t\n\x0b\x0c >\/]/', + $this->character($this->char + 1 + strlen($next_node)) + ) || $this->EOF === $this->char))) + ) { /* If the content model flag is set to the RCDATA or CDATA states then examine the next few characters. If they do not match the tag name of the last start tag token emitted (case insensitively), or if they do but @@ -386,10 +751,12 @@ class HTML5 { ...then there is a parse error. Emit a U+003C LESS-THAN SIGN character token, a U+002F SOLIDUS character token, and switch to the data state to process the next input character. */ - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => 'emitToken( + array( + 'type' => self::CHARACTR, + 'data' => 'state = 'data'; @@ -400,32 +767,34 @@ class HTML5 { $this->char++; $char = $this->char(); - if(preg_match('/^[A-Za-z]$/', $char)) { + if (preg_match('/^[A-Za-z]$/', $char)) { /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z Create a new end tag token, set its tag name to the lowercase version of the input character (add 0x0020 to the character's code point), then switch to the tag name state. (Don't emit the token yet; further details will be filled in before it is emitted.) */ $this->token = array( - 'name' => strtolower($char), - 'type' => self::ENDTAG + 'name' => strtolower($char), + 'type' => self::ENDTAG ); $this->state = 'tagName'; - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Parse error. Switch to the data state. */ $this->state = 'data'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS character token. Reconsume the EOF character in the data state. */ - $this->emitToken(array( - 'type' => self::CHARACTR, - 'data' => 'emitToken( + array( + 'type' => self::CHARACTR, + 'data' => 'char--; $this->state = 'data'; @@ -437,12 +806,13 @@ class HTML5 { } } - private function tagNameState() { + private function tagNameState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { /* U+0009 CHARACTER TABULATION U+000A LINE FEED (LF) U+000B LINE TABULATION @@ -451,13 +821,13 @@ class HTML5 { Switch to the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Emit the current tag token. Switch to the data state. */ $this->emitToken($this->token); $this->state = 'data'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Parse error. Emit the current tag token. Reconsume the EOF character in the data state. */ @@ -466,7 +836,7 @@ class HTML5 { $this->char--; $this->state = 'data'; - } elseif($char === '/') { + } elseif ($char === '/') { /* U+002F SOLIDUS (/) Parse error unless this is a permitted slash. Switch to the before attribute name state. */ @@ -481,12 +851,13 @@ class HTML5 { } } - private function beforeAttributeNameState() { + private function beforeAttributeNameState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { /* U+0009 CHARACTER TABULATION U+000A LINE FEED (LF) U+000B LINE TABULATION @@ -495,19 +866,19 @@ class HTML5 { Stay in the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Emit the current tag token. Switch to the data state. */ $this->emitToken($this->token); $this->state = 'data'; - } elseif($char === '/') { + } elseif ($char === '/') { /* U+002F SOLIDUS (/) Parse error unless this is a permitted slash. Stay in the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Parse error. Emit the current tag token. Reconsume the EOF character in the data state. */ @@ -522,7 +893,7 @@ class HTML5 { name to the current input character, and its value to the empty string. Switch to the attribute name state. */ $this->token['attr'][] = array( - 'name' => strtolower($char), + 'name' => strtolower($char), 'value' => null ); @@ -530,12 +901,13 @@ class HTML5 { } } - private function attributeNameState() { + private function attributeNameState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { /* U+0009 CHARACTER TABULATION U+000A LINE FEED (LF) U+000B LINE TABULATION @@ -544,24 +916,24 @@ class HTML5 { Stay in the before attribute name state. */ $this->state = 'afterAttributeName'; - } elseif($char === '=') { + } elseif ($char === '=') { /* U+003D EQUALS SIGN (=) Switch to the before attribute value state. */ $this->state = 'beforeAttributeValue'; - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Emit the current tag token. Switch to the data state. */ $this->emitToken($this->token); $this->state = 'data'; - } elseif($char === '/' && $this->character($this->char + 1) !== '>') { + } elseif ($char === '/' && $this->character($this->char + 1) !== '>') { /* U+002F SOLIDUS (/) Parse error unless this is a permitted slash. Switch to the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Parse error. Emit the current tag token. Reconsume the EOF character in the data state. */ @@ -581,12 +953,13 @@ class HTML5 { } } - private function afterAttributeNameState() { + private function afterAttributeNameState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { /* U+0009 CHARACTER TABULATION U+000A LINE FEED (LF) U+000B LINE TABULATION @@ -595,24 +968,24 @@ class HTML5 { Stay in the after attribute name state. */ $this->state = 'afterAttributeName'; - } elseif($char === '=') { + } elseif ($char === '=') { /* U+003D EQUALS SIGN (=) Switch to the before attribute value state. */ $this->state = 'beforeAttributeValue'; - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Emit the current tag token. Switch to the data state. */ $this->emitToken($this->token); $this->state = 'data'; - } elseif($char === '/' && $this->character($this->char + 1) !== '>') { + } elseif ($char === '/' && $this->character($this->char + 1) !== '>') { /* U+002F SOLIDUS (/) Parse error unless this is a permitted slash. Switch to the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Parse error. Emit the current tag token. Reconsume the EOF character in the data state. */ @@ -627,7 +1000,7 @@ class HTML5 { name to the current input character, and its value to the empty string. Switch to the attribute name state. */ $this->token['attr'][] = array( - 'name' => strtolower($char), + 'name' => strtolower($char), 'value' => null ); @@ -635,12 +1008,13 @@ class HTML5 { } } - private function beforeAttributeValueState() { + private function beforeAttributeValueState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { /* U+0009 CHARACTER TABULATION U+000A LINE FEED (LF) U+000B LINE TABULATION @@ -649,24 +1023,24 @@ class HTML5 { Stay in the before attribute value state. */ $this->state = 'beforeAttributeValue'; - } elseif($char === '"') { + } elseif ($char === '"') { /* U+0022 QUOTATION MARK (") Switch to the attribute value (double-quoted) state. */ $this->state = 'attributeValueDoubleQuoted'; - } elseif($char === '&') { + } elseif ($char === '&') { /* U+0026 AMPERSAND (&) Switch to the attribute value (unquoted) state and reconsume this input character. */ $this->char--; $this->state = 'attributeValueUnquoted'; - } elseif($char === '\'') { + } elseif ($char === '\'') { /* U+0027 APOSTROPHE (') Switch to the attribute value (single-quoted) state. */ $this->state = 'attributeValueSingleQuoted'; - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Emit the current tag token. Switch to the data state. */ $this->emitToken($this->token); @@ -683,22 +1057,23 @@ class HTML5 { } } - private function attributeValueDoubleQuotedState() { + private function attributeValueDoubleQuotedState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if($char === '"') { + if ($char === '"') { /* U+0022 QUOTATION MARK (") Switch to the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($char === '&') { + } elseif ($char === '&') { /* U+0026 AMPERSAND (&) Switch to the entity in attribute value state. */ $this->entityInAttributeValueState('double'); - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Parse error. Emit the current tag token. Reconsume the character in the data state. */ @@ -718,22 +1093,23 @@ class HTML5 { } } - private function attributeValueSingleQuotedState() { + private function attributeValueSingleQuotedState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if($char === '\'') { + if ($char === '\'') { /* U+0022 QUOTATION MARK (') Switch to the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($char === '&') { + } elseif ($char === '&') { /* U+0026 AMPERSAND (&) Switch to the entity in attribute value state. */ $this->entityInAttributeValueState('single'); - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { /* EOF Parse error. Emit the current tag token. Reconsume the character in the data state. */ @@ -753,12 +1129,13 @@ class HTML5 { } } - private function attributeValueUnquotedState() { + private function attributeValueUnquotedState() + { // Consume the next input character: $this->char++; $char = $this->character($this->char); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { /* U+0009 CHARACTER TABULATION U+000A LINE FEED (LF) U+000B LINE TABULATION @@ -767,12 +1144,12 @@ class HTML5 { Switch to the before attribute name state. */ $this->state = 'beforeAttributeName'; - } elseif($char === '&') { + } elseif ($char === '&') { /* U+0026 AMPERSAND (&) Switch to the entity in attribute value state. */ $this->entityInAttributeValueState(); - } elseif($char === '>') { + } elseif ($char === '>') { /* U+003E GREATER-THAN SIGN (>) Emit the current tag token. Switch to the data state. */ $this->emitToken($this->token); @@ -789,7 +1166,8 @@ class HTML5 { } } - private function entityInAttributeValueState() { + private function entityInAttributeValueState() + { // Attempt to consume an entity. $entity = $this->entity(); @@ -804,7 +1182,8 @@ class HTML5 { $this->token['attr'][$last]['value'] .= $char; } - private function bogusCommentState() { + private function bogusCommentState() + { /* Consume every character up to the first U+003E GREATER-THAN SIGN character (>) or the end of the file (EOF), whichever comes first. Emit a comment token whose data is the concatenation of all the characters @@ -814,10 +1193,12 @@ class HTML5 { end of the file otherwise. (If the comment was started by the end of the file (EOF), the token is empty.) */ $data = $this->characters('^>', $this->char); - $this->emitToken(array( - 'data' => $data, - 'type' => self::COMMENT - )); + $this->emitToken( + array( + 'data' => $data, + 'type' => self::COMMENT + ) + ); $this->char += strlen($data); @@ -825,16 +1206,17 @@ class HTML5 { $this->state = 'data'; /* If the end of the file was reached, reconsume the EOF character. */ - if($this->char === $this->EOF) { + if ($this->char === $this->EOF) { $this->char = $this->EOF - 1; } } - private function markupDeclarationOpenState() { + private function markupDeclarationOpenState() + { /* If the next two characters are both U+002D HYPHEN-MINUS (-) characters, consume those two characters, create a comment token whose data is the empty string, and switch to the comment state. */ - if($this->character($this->char + 1, 2) === '--') { + if ($this->character($this->char + 1, 2) === '--') { $this->char += 2; $this->state = 'comment'; $this->token = array( @@ -842,41 +1224,42 @@ class HTML5 { 'type' => self::COMMENT ); - /* Otherwise if the next seven chacacters are a case-insensitive match - for the word "DOCTYPE", then consume those characters and switch to the - DOCTYPE state. */ - } elseif(strtolower($this->character($this->char + 1, 7)) === 'doctype') { + /* Otherwise if the next seven chacacters are a case-insensitive match + for the word "DOCTYPE", then consume those characters and switch to the + DOCTYPE state. */ + } elseif (strtolower($this->character($this->char + 1, 7)) === 'doctype') { $this->char += 7; $this->state = 'doctype'; - /* Otherwise, is is a parse error. Switch to the bogus comment state. - The next character that is consumed, if any, is the first character - that will be in the comment. */ + /* Otherwise, is is a parse error. Switch to the bogus comment state. + The next character that is consumed, if any, is the first character + that will be in the comment. */ } else { $this->char++; $this->state = 'bogusComment'; } } - private function commentState() { + private function commentState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); /* U+002D HYPHEN-MINUS (-) */ - if($char === '-') { + if ($char === '-') { /* Switch to the comment dash state */ $this->state = 'commentDash'; - /* EOF */ - } elseif($this->char === $this->EOF) { + /* EOF */ + } elseif ($this->char === $this->EOF) { /* Parse error. Emit the comment token. Reconsume the EOF character in the data state. */ $this->emitToken($this->token); $this->char--; $this->state = 'data'; - /* Anything else */ + /* Anything else */ } else { /* Append the input character to the comment token's data. Stay in the comment state. */ @@ -884,62 +1267,65 @@ class HTML5 { } } - private function commentDashState() { + private function commentDashState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); /* U+002D HYPHEN-MINUS (-) */ - if($char === '-') { + if ($char === '-') { /* Switch to the comment end state */ $this->state = 'commentEnd'; - /* EOF */ - } elseif($this->char === $this->EOF) { + /* EOF */ + } elseif ($this->char === $this->EOF) { /* Parse error. Emit the comment token. Reconsume the EOF character in the data state. */ $this->emitToken($this->token); $this->char--; $this->state = 'data'; - /* Anything else */ + /* Anything else */ } else { /* Append a U+002D HYPHEN-MINUS (-) character and the input character to the comment token's data. Switch to the comment state. */ - $this->token['data'] .= '-'.$char; + $this->token['data'] .= '-' . $char; $this->state = 'comment'; } } - private function commentEndState() { + private function commentEndState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); - if($char === '>') { + if ($char === '>') { $this->emitToken($this->token); $this->state = 'data'; - } elseif($char === '-') { + } elseif ($char === '-') { $this->token['data'] .= '-'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { $this->emitToken($this->token); $this->char--; $this->state = 'data'; } else { - $this->token['data'] .= '--'.$char; + $this->token['data'] .= '--' . $char; $this->state = 'comment'; } } - private function doctypeState() { + private function doctypeState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { $this->state = 'beforeDoctypeName'; } else { @@ -948,15 +1334,16 @@ class HTML5 { } } - private function beforeDoctypeNameState() { + private function beforeDoctypeNameState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { // Stay in the before DOCTYPE name state. - } elseif(preg_match('/^[a-z]$/', $char)) { + } elseif (preg_match('/^[a-z]$/', $char)) { $this->token = array( 'name' => strtoupper($char), 'type' => self::DOCTYPE, @@ -965,21 +1352,25 @@ class HTML5 { $this->state = 'doctypeName'; - } elseif($char === '>') { - $this->emitToken(array( - 'name' => null, - 'type' => self::DOCTYPE, - 'error' => true - )); + } elseif ($char === '>') { + $this->emitToken( + array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + ) + ); $this->state = 'data'; - } elseif($this->char === $this->EOF) { - $this->emitToken(array( - 'name' => null, - 'type' => self::DOCTYPE, - 'error' => true - )); + } elseif ($this->char === $this->EOF) { + $this->emitToken( + array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + ) + ); $this->char--; $this->state = 'data'; @@ -995,22 +1386,23 @@ class HTML5 { } } - private function doctypeNameState() { + private function doctypeNameState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { $this->state = 'AfterDoctypeName'; - } elseif($char === '>') { + } elseif ($char === '>') { $this->emitToken($this->token); $this->state = 'data'; - } elseif(preg_match('/^[a-z]$/', $char)) { + } elseif (preg_match('/^[a-z]$/', $char)) { $this->token['name'] .= strtoupper($char); - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { $this->emitToken($this->token); $this->char--; $this->state = 'data'; @@ -1024,19 +1416,20 @@ class HTML5 { : true; } - private function afterDoctypeNameState() { + private function afterDoctypeNameState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); - if(preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { // Stay in the DOCTYPE name state. - } elseif($char === '>') { + } elseif ($char === '>') { $this->emitToken($this->token); $this->state = 'data'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { $this->emitToken($this->token); $this->char--; $this->state = 'data'; @@ -1047,16 +1440,17 @@ class HTML5 { } } - private function bogusDoctypeState() { + private function bogusDoctypeState() + { /* Consume the next input character: */ $this->char++; $char = $this->char(); - if($char === '>') { + if ($char === '>') { $this->emitToken($this->token); $this->state = 'data'; - } elseif($this->char === $this->EOF) { + } elseif ($this->char === $this->EOF) { $this->emitToken($this->token); $this->char--; $this->state = 'data'; @@ -1066,22 +1460,23 @@ class HTML5 { } } - private function entity() { + private function entity() + { $start = $this->char; // This section defines how to consume an entity. This definition is // used when parsing entities in text and in attributes. // The behaviour depends on the identity of the next character (the - // one immediately after the U+0026 AMPERSAND character): + // one immediately after the U+0026 AMPERSAND character): - switch($this->character($this->char + 1)) { + switch ($this->character($this->char + 1)) { // U+0023 NUMBER SIGN (#) case '#': // The behaviour further depends on the character after the // U+0023 NUMBER SIGN: - switch($this->character($this->char + 1)) { + switch ($this->character($this->char + 1)) { // U+0078 LATIN SMALL LETTER X // U+0058 LATIN CAPITAL LETTER X case 'x': @@ -1094,7 +1489,7 @@ class HTML5 { // words, 0-9, A-F, a-f). $char = 1; $char_class = '0-9A-Fa-f'; - break; + break; // Anything else default: @@ -1103,7 +1498,7 @@ class HTML5 { // NINE (i.e. just 0-9). $char = 0; $char_class = '0-9'; - break; + break; } // Consume as many characters as match the range of characters @@ -1114,7 +1509,7 @@ class HTML5 { $cond = strlen($e_name) > 0; // The rest of the parsing happens bellow. - break; + break; // Anything else default: @@ -1124,12 +1519,12 @@ class HTML5 { $e_name = $this->characters('0-9A-Za-z;', $this->char + 1); $len = strlen($e_name); - for($c = 1; $c <= $len; $c++) { + for ($c = 1; $c <= $len; $c++) { $id = substr($e_name, 0, $c); $this->char++; - if(in_array($id, $this->entities)) { - if ($e_name[$c-1] !== ';') { + if (in_array($id, $this->entities)) { + if ($e_name[$c - 1] !== ';') { if ($c < $len && $e_name[$c] == ';') { $this->char++; // consume extra semicolon } @@ -1141,10 +1536,10 @@ class HTML5 { $cond = isset($entity); // The rest of the parsing happens bellow. - break; + break; } - if(!$cond) { + if (!$cond) { // If no match can be made, then this is a parse error. No // characters are consumed, and nothing is returned. $this->char = $start; @@ -1153,81 +1548,157 @@ class HTML5 { // Return a character token for the character corresponding to the // entity name (as given by the second column of the entities table). - return html_entity_decode('&'.$entity.';', ENT_QUOTES, 'UTF-8'); + return html_entity_decode('&' . $entity . ';', ENT_QUOTES, 'UTF-8'); } - private function emitToken($token) { + private function emitToken($token) + { $emit = $this->tree->emitToken($token); - if(is_int($emit)) { + if (is_int($emit)) { $this->content_model = $emit; - } elseif($token['type'] === self::ENDTAG) { + } elseif ($token['type'] === self::ENDTAG) { $this->content_model = self::PCDATA; } } - private function EOF() { + private function EOF() + { $this->state = null; - $this->tree->emitToken(array( - 'type' => self::EOF - )); + $this->tree->emitToken( + array( + 'type' => self::EOF + ) + ); } } -class HTML5TreeConstructer { +class HTML5TreeConstructer +{ public $stack = array(); private $phase; private $mode; private $dom; private $foster_parent = null; - private $a_formatting = array(); + private $a_formatting = array(); private $head_pointer = null; private $form_pointer = null; - private $scoping = array('button','caption','html','marquee','object','table','td','th'); - private $formatting = array('a','b','big','em','font','i','nobr','s','small','strike','strong','tt','u'); - private $special = array('address','area','base','basefont','bgsound', - 'blockquote','body','br','center','col','colgroup','dd','dir','div','dl', - 'dt','embed','fieldset','form','frame','frameset','h1','h2','h3','h4','h5', - 'h6','head','hr','iframe','image','img','input','isindex','li','link', - 'listing','menu','meta','noembed','noframes','noscript','ol','optgroup', - 'option','p','param','plaintext','pre','script','select','spacer','style', - 'tbody','textarea','tfoot','thead','title','tr','ul','wbr'); + private $scoping = array('button', 'caption', 'html', 'marquee', 'object', 'table', 'td', 'th'); + private $formatting = array( + 'a', + 'b', + 'big', + 'em', + 'font', + 'i', + 'nobr', + 's', + 'small', + 'strike', + 'strong', + 'tt', + 'u' + ); + private $special = array( + 'address', + 'area', + 'base', + 'basefont', + 'bgsound', + 'blockquote', + 'body', + 'br', + 'center', + 'col', + 'colgroup', + 'dd', + 'dir', + 'div', + 'dl', + 'dt', + 'embed', + 'fieldset', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'hr', + 'iframe', + 'image', + 'img', + 'input', + 'isindex', + 'li', + 'link', + 'listing', + 'menu', + 'meta', + 'noembed', + 'noframes', + 'noscript', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'plaintext', + 'pre', + 'script', + 'select', + 'spacer', + 'style', + 'tbody', + 'textarea', + 'tfoot', + 'thead', + 'title', + 'tr', + 'ul', + 'wbr' + ); // The different phases. const INIT_PHASE = 0; const ROOT_PHASE = 1; const MAIN_PHASE = 2; - const END_PHASE = 3; + const END_PHASE = 3; // The different insertion modes for the main phase. const BEFOR_HEAD = 0; - const IN_HEAD = 1; + const IN_HEAD = 1; const AFTER_HEAD = 2; - const IN_BODY = 3; - const IN_TABLE = 4; + const IN_BODY = 3; + const IN_TABLE = 4; const IN_CAPTION = 5; - const IN_CGROUP = 6; - const IN_TBODY = 7; - const IN_ROW = 8; - const IN_CELL = 9; - const IN_SELECT = 10; + const IN_CGROUP = 6; + const IN_TBODY = 7; + const IN_ROW = 8; + const IN_CELL = 9; + const IN_SELECT = 10; const AFTER_BODY = 11; - const IN_FRAME = 12; + const IN_FRAME = 12; const AFTR_FRAME = 13; // The different types of elements. - const SPECIAL = 0; - const SCOPING = 1; + const SPECIAL = 0; + const SCOPING = 1; const FORMATTING = 2; - const PHRASING = 3; + const PHRASING = 3; - const MARKER = 0; + const MARKER = 0; - public function __construct() { + public function __construct() + { $this->phase = self::INIT_PHASE; $this->mode = self::BEFOR_HEAD; $this->dom = new DOMDocument; @@ -1239,16 +1710,26 @@ class HTML5TreeConstructer { } // Process tag tokens - public function emitToken($token) { - switch($this->phase) { - case self::INIT_PHASE: return $this->initPhase($token); break; - case self::ROOT_PHASE: return $this->rootElementPhase($token); break; - case self::MAIN_PHASE: return $this->mainPhase($token); break; - case self::END_PHASE : return $this->trailingEndPhase($token); break; + public function emitToken($token) + { + switch ($this->phase) { + case self::INIT_PHASE: + return $this->initPhase($token); + break; + case self::ROOT_PHASE: + return $this->rootElementPhase($token); + break; + case self::MAIN_PHASE: + return $this->mainPhase($token); + break; + case self::END_PHASE : + return $this->trailingEndPhase($token); + break; } } - private function initPhase($token) { + private function initPhase($token) + { /* Initially, the tree construction stage must handle each token emitted from the tokenisation stage as follows: */ @@ -1260,13 +1741,14 @@ class HTML5TreeConstructer { U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), or U+0020 SPACE An end-of-file token */ - if((isset($token['error']) && $token['error']) || - $token['type'] === HTML5::COMMENT || - $token['type'] === HTML5::STARTTAG || - $token['type'] === HTML5::ENDTAG || - $token['type'] === HTML5::EOF || - ($token['type'] === HTML5::CHARACTR && isset($token['data']) && - !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']))) { + if ((isset($token['error']) && $token['error']) || + $token['type'] === HTML5::COMMENT || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF || + ($token['type'] === HTML5::CHARACTR && isset($token['data']) && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) + ) { /* This specification does not define how to handle this case. In particular, user agents may ignore the entirety of this specification altogether for such documents, and instead invoke special parse modes @@ -1275,8 +1757,8 @@ class HTML5TreeConstructer { $this->phase = self::ROOT_PHASE; return $this->rootElementPhase($token); - /* A DOCTYPE token marked as being correct */ - } elseif(isset($token['error']) && !$token['error']) { + /* A DOCTYPE token marked as being correct */ + } elseif (isset($token['error']) && !$token['error']) { /* Append a DocumentType node to the Document node, with the name attribute set to the name given in the DOCTYPE token (which will be "HTML"), and the other attributes specific to DocumentType objects @@ -1287,52 +1769,58 @@ class HTML5TreeConstructer { stage. */ $this->phase = self::ROOT_PHASE; - /* A character token that is one of one of U+0009 CHARACTER TABULATION, - U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), - or U+0020 SPACE */ - } elseif(isset($token['data']) && preg_match('/^[\t\n\x0b\x0c ]+$/', - $token['data'])) { + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif (isset($token['data']) && preg_match( + '/^[\t\n\x0b\x0c ]+$/', + $token['data'] + ) + ) { /* Append that character to the Document node. */ $text = $this->dom->createTextNode($token['data']); $this->dom->appendChild($text); } } - private function rootElementPhase($token) { + private function rootElementPhase($token) + { /* After the initial phase, as each token is emitted from the tokenisation stage, it must be processed as described in this section. */ /* A DOCTYPE token */ - if($token['type'] === HTML5::DOCTYPE) { + if ($token['type'] === HTML5::DOCTYPE) { // Parse error. Ignore the token. - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the Document object with the data attribute set to the data given in the comment token. */ $comment = $this->dom->createComment($token['data']); $this->dom->appendChild($comment); - /* A character token that is one of one of U+0009 CHARACTER TABULATION, - U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), - or U+0020 SPACE */ - } elseif($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Append that character to the Document node. */ $text = $this->dom->createTextNode($token['data']); $this->dom->appendChild($text); - /* A character token that is not one of U+0009 CHARACTER TABULATION, - U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED - (FF), or U+0020 SPACE - A start tag token - An end tag token - An end-of-file token */ - } elseif(($token['type'] === HTML5::CHARACTR && - !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || - $token['type'] === HTML5::STARTTAG || - $token['type'] === HTML5::ENDTAG || - $token['type'] === HTML5::EOF) { + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED + (FF), or U+0020 SPACE + A start tag token + An end tag token + An end-of-file token */ + } elseif (($token['type'] === HTML5::CHARACTR && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF + ) { /* Create an HTMLElement node with the tag name html, in the HTML namespace. Append it to the Document object. Switch to the main phase and reprocess the current token. */ @@ -1345,15 +1833,16 @@ class HTML5TreeConstructer { } } - private function mainPhase($token) { + private function mainPhase($token) + { /* Tokens in the main phase must be handled as follows: */ /* A DOCTYPE token */ - if($token['type'] === HTML5::DOCTYPE) { + if ($token['type'] === HTML5::DOCTYPE) { // Parse error. Ignore the token. - /* A start tag token with the tag name "html" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') { + /* A start tag token with the tag name "html" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') { /* If this start tag token was not the first start tag token, then it is a parse error. */ @@ -1361,59 +1850,91 @@ class HTML5TreeConstructer { is already present on the top element of the stack of open elements. If it is not, add the attribute and its corresponding value to that element. */ - foreach($token['attr'] as $attr) { - if(!$this->stack[0]->hasAttribute($attr['name'])) { + foreach ($token['attr'] as $attr) { + if (!$this->stack[0]->hasAttribute($attr['name'])) { $this->stack[0]->setAttribute($attr['name'], $attr['value']); } } - /* An end-of-file token */ - } elseif($token['type'] === HTML5::EOF) { + /* An end-of-file token */ + } elseif ($token['type'] === HTML5::EOF) { /* Generate implied end tags. */ $this->generateImpliedEndTags(); - /* Anything else. */ + /* Anything else. */ } else { /* Depends on the insertion mode: */ - switch($this->mode) { - case self::BEFOR_HEAD: return $this->beforeHead($token); break; - case self::IN_HEAD: return $this->inHead($token); break; - case self::AFTER_HEAD: return $this->afterHead($token); break; - case self::IN_BODY: return $this->inBody($token); break; - case self::IN_TABLE: return $this->inTable($token); break; - case self::IN_CAPTION: return $this->inCaption($token); break; - case self::IN_CGROUP: return $this->inColumnGroup($token); break; - case self::IN_TBODY: return $this->inTableBody($token); break; - case self::IN_ROW: return $this->inRow($token); break; - case self::IN_CELL: return $this->inCell($token); break; - case self::IN_SELECT: return $this->inSelect($token); break; - case self::AFTER_BODY: return $this->afterBody($token); break; - case self::IN_FRAME: return $this->inFrameset($token); break; - case self::AFTR_FRAME: return $this->afterFrameset($token); break; - case self::END_PHASE: return $this->trailingEndPhase($token); break; + switch ($this->mode) { + case self::BEFOR_HEAD: + return $this->beforeHead($token); + break; + case self::IN_HEAD: + return $this->inHead($token); + break; + case self::AFTER_HEAD: + return $this->afterHead($token); + break; + case self::IN_BODY: + return $this->inBody($token); + break; + case self::IN_TABLE: + return $this->inTable($token); + break; + case self::IN_CAPTION: + return $this->inCaption($token); + break; + case self::IN_CGROUP: + return $this->inColumnGroup($token); + break; + case self::IN_TBODY: + return $this->inTableBody($token); + break; + case self::IN_ROW: + return $this->inRow($token); + break; + case self::IN_CELL: + return $this->inCell($token); + break; + case self::IN_SELECT: + return $this->inSelect($token); + break; + case self::AFTER_BODY: + return $this->afterBody($token); + break; + case self::IN_FRAME: + return $this->inFrameset($token); + break; + case self::AFTR_FRAME: + return $this->afterFrameset($token); + break; + case self::END_PHASE: + return $this->trailingEndPhase($token); + break; } } } - private function beforeHead($token) { + private function beforeHead($token) + { /* Handle the token as follows: */ /* A character token that is one of one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), or U+0020 SPACE */ - if($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Append the character to the current node. */ $this->insertText($token['data']); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $this->insertComment($token['data']); - /* A start tag token with the tag name "head" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') { + /* A start tag token with the tag name "head" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') { /* Create an element for the token, append the new element to the current node and push it onto the stack of open elements. */ $element = $this->insertElement($token); @@ -1424,32 +1945,38 @@ class HTML5TreeConstructer { /* Change the insertion mode to "in head". */ $this->mode = self::IN_HEAD; - /* A start tag token whose tag name is one of: "base", "link", "meta", - "script", "style", "title". Or an end tag with the tag name "html". - Or a character token that is not one of U+0009 CHARACTER TABULATION, - U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), - or U+0020 SPACE. Or any other start tag token */ - } elseif($token['type'] === HTML5::STARTTAG || - ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') || - ($token['type'] === HTML5::CHARACTR && !preg_match('/^[\t\n\x0b\x0c ]$/', - $token['data']))) { + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title". Or an end tag with the tag name "html". + Or a character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or any other start tag token */ + } elseif ($token['type'] === HTML5::STARTTAG || + ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') || + ($token['type'] === HTML5::CHARACTR && !preg_match( + '/^[\t\n\x0b\x0c ]$/', + $token['data'] + )) + ) { /* Act as if a start tag token with the tag name "head" and no attributes had been seen, then reprocess the current token. */ - $this->beforeHead(array( - 'name' => 'head', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); + $this->beforeHead( + array( + 'name' => 'head', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); return $this->inHead($token); - /* Any other end tag */ - } elseif($token['type'] === HTML5::ENDTAG) { + /* Any other end tag */ + } elseif ($token['type'] === HTML5::ENDTAG) { /* Parse error. Ignore the token. */ } } - private function inHead($token) { + private function inHead($token) + { /* Handle the token as follows: */ /* A character token that is one of one of U+0009 CHARACTER TABULATION, @@ -1459,30 +1986,34 @@ class HTML5TreeConstructer { THIS DIFFERS FROM THE SPEC: If the current node is either a title, style or script element, append the character to the current node regardless of its content. */ - if(($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || ( - $token['type'] === HTML5::CHARACTR && in_array(end($this->stack)->nodeName, - array('title', 'style', 'script')))) { + if (($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || ( + $token['type'] === HTML5::CHARACTR && in_array( + end($this->stack)->nodeName, + array('title', 'style', 'script') + )) + ) { /* Append the character to the current node. */ $this->insertText($token['data']); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $this->insertComment($token['data']); - } elseif($token['type'] === HTML5::ENDTAG && - in_array($token['name'], array('title', 'style', 'script'))) { + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('title', 'style', 'script')) + ) { array_pop($this->stack); return HTML5::PCDATA; - /* A start tag with the tag name "title" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') { + /* A start tag with the tag name "title" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') { /* Create an element for the token and append the new element to the node pointed to by the head element pointer, or, if that is null (innerHTML case), to the current node. */ - if($this->head_pointer !== null) { + if ($this->head_pointer !== null) { $element = $this->insertElement($token, false); $this->head_pointer->appendChild($element); @@ -1493,12 +2024,12 @@ class HTML5TreeConstructer { /* Switch the tokeniser's content model flag to the RCDATA state. */ return HTML5::RCDATA; - /* A start tag with the tag name "style" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') { + /* A start tag with the tag name "style" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') { /* Create an element for the token and append the new element to the node pointed to by the head element pointer, or, if that is null (innerHTML case), to the current node. */ - if($this->head_pointer !== null) { + if ($this->head_pointer !== null) { $element = $this->insertElement($token, false); $this->head_pointer->appendChild($element); @@ -1509,8 +2040,8 @@ class HTML5TreeConstructer { /* Switch the tokeniser's content model flag to the CDATA state. */ return HTML5::CDATA; - /* A start tag with the tag name "script" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') { + /* A start tag with the tag name "script" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') { /* Create an element for the token. */ $element = $this->insertElement($token, false); $this->head_pointer->appendChild($element); @@ -1518,13 +2049,16 @@ class HTML5TreeConstructer { /* Switch the tokeniser's content model flag to the CDATA state. */ return HTML5::CDATA; - /* A start tag with the tag name "base", "link", or "meta" */ - } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('base', 'link', 'meta'))) { + /* A start tag with the tag name "base", "link", or "meta" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('base', 'link', 'meta') + ) + ) { /* Create an element for the token and append the new element to the node pointed to by the head element pointer, or, if that is null (innerHTML case), to the current node. */ - if($this->head_pointer !== null) { + if ($this->head_pointer !== null) { $element = $this->insertElement($token, false); $this->head_pointer->appendChild($element); array_pop($this->stack); @@ -1533,14 +2067,14 @@ class HTML5TreeConstructer { $this->insertElement($token); } - /* An end tag with the tag name "head" */ - } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') { + /* An end tag with the tag name "head" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') { /* If the current node is a head element, pop the current node off the stack of open elements. */ - if($this->head_pointer->isSameNode(end($this->stack))) { + if ($this->head_pointer->isSameNode(end($this->stack))) { array_pop($this->stack); - /* Otherwise, this is a parse error. */ + /* Otherwise, this is a parse error. */ } else { // k } @@ -1548,22 +2082,25 @@ class HTML5TreeConstructer { /* Change the insertion mode to "after head". */ $this->mode = self::AFTER_HEAD; - /* A start tag with the tag name "head" or an end tag except "html". */ - } elseif(($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') || - ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html')) { + /* A start tag with the tag name "head" or an end tag except "html". */ + } elseif (($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') || + ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html') + ) { // Parse error. Ignore the token. - /* Anything else */ + /* Anything else */ } else { /* If the current node is a head element, act as if an end tag token with the tag name "head" had been seen. */ - if($this->head_pointer->isSameNode(end($this->stack))) { - $this->inHead(array( - 'name' => 'head', - 'type' => HTML5::ENDTAG - )); + if ($this->head_pointer->isSameNode(end($this->stack))) { + $this->inHead( + array( + 'name' => 'head', + 'type' => HTML5::ENDTAG + ) + ); - /* Otherwise, change the insertion mode to "after head". */ + /* Otherwise, change the insertion mode to "after head". */ } else { $this->mode = self::AFTER_HEAD; } @@ -1573,66 +2110,74 @@ class HTML5TreeConstructer { } } - private function afterHead($token) { + private function afterHead($token) + { /* Handle the token as follows: */ /* A character token that is one of one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), or U+0020 SPACE */ - if($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Append the character to the current node. */ $this->insertText($token['data']); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $this->insertComment($token['data']); - /* A start tag token with the tag name "body" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') { + /* A start tag token with the tag name "body" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') { /* Insert a body element for the token. */ $this->insertElement($token); /* Change the insertion mode to "in body". */ $this->mode = self::IN_BODY; - /* A start tag token with the tag name "frameset" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') { + /* A start tag token with the tag name "frameset" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') { /* Insert a frameset element for the token. */ $this->insertElement($token); /* Change the insertion mode to "in frameset". */ $this->mode = self::IN_FRAME; - /* A start tag token whose tag name is one of: "base", "link", "meta", - "script", "style", "title" */ - } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('base', 'link', 'meta', 'script', 'style', 'title'))) { + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('base', 'link', 'meta', 'script', 'style', 'title') + ) + ) { /* Parse error. Switch the insertion mode back to "in head" and reprocess the token. */ $this->mode = self::IN_HEAD; return $this->inHead($token); - /* Anything else */ + /* Anything else */ } else { /* Act as if a start tag token with the tag name "body" and no attributes had been seen, and then reprocess the current token. */ - $this->afterHead(array( - 'name' => 'body', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); + $this->afterHead( + array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); return $this->inBody($token); } } - private function inBody($token) { + private function inBody($token) + { /* Handle the token as follows: */ - switch($token['type']) { + switch ($token['type']) { /* A character token */ case HTML5::CHARACTR: /* Reconstruct the active formatting elements, if any. */ @@ -1640,1015 +2185,1159 @@ class HTML5TreeConstructer { /* Append the token's character to the current node. */ $this->insertText($token['data']); - break; + break; /* A comment token */ case HTML5::COMMENT: /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $this->insertComment($token['data']); - break; + break; case HTML5::STARTTAG: - switch($token['name']) { - /* A start tag token whose tag name is one of: "script", - "style" */ - case 'script': case 'style': - /* Process the token as if the insertion mode had been "in - head". */ - return $this->inHead($token); - break; + switch ($token['name']) { + /* A start tag token whose tag name is one of: "script", + "style" */ + case 'script': + case 'style': + /* Process the token as if the insertion mode had been "in + head". */ + return $this->inHead($token); + break; - /* A start tag token whose tag name is one of: "base", "link", - "meta", "title" */ - case 'base': case 'link': case 'meta': case 'title': - /* Parse error. Process the token as if the insertion mode - had been "in head". */ - return $this->inHead($token); - break; + /* A start tag token whose tag name is one of: "base", "link", + "meta", "title" */ + case 'base': + case 'link': + case 'meta': + case 'title': + /* Parse error. Process the token as if the insertion mode + had been "in head". */ + return $this->inHead($token); + break; - /* A start tag token with the tag name "body" */ - case 'body': - /* Parse error. If the second element on the stack of open - elements is not a body element, or, if the stack of open - elements has only one node on it, then ignore the token. - (innerHTML case) */ - if(count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') { - // Ignore - - /* Otherwise, for each attribute on the token, check to see - if the attribute is already present on the body element (the - second element) on the stack of open elements. If it is not, - add the attribute and its corresponding value to that - element. */ - } else { - foreach($token['attr'] as $attr) { - if(!$this->stack[1]->hasAttribute($attr['name'])) { - $this->stack[1]->setAttribute($attr['name'], $attr['value']); + /* A start tag token with the tag name "body" */ + case 'body': + /* Parse error. If the second element on the stack of open + elements is not a body element, or, if the stack of open + elements has only one node on it, then ignore the token. + (innerHTML case) */ + if (count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') { + // Ignore + + /* Otherwise, for each attribute on the token, check to see + if the attribute is already present on the body element (the + second element) on the stack of open elements. If it is not, + add the attribute and its corresponding value to that + element. */ + } else { + foreach ($token['attr'] as $attr) { + if (!$this->stack[1]->hasAttribute($attr['name'])) { + $this->stack[1]->setAttribute($attr['name'], $attr['value']); + } } } - } - break; - - /* A start tag whose tag name is one of: "address", - "blockquote", "center", "dir", "div", "dl", "fieldset", - "listing", "menu", "ol", "p", "ul" */ - case 'address': case 'blockquote': case 'center': case 'dir': - case 'div': case 'dl': case 'fieldset': case 'listing': - case 'menu': case 'ol': case 'p': case 'ul': - /* If the stack of open elements has a p element in scope, - then act as if an end tag with the tag name p had been - seen. */ - if($this->elementInScope('p')) { - $this->emitToken(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); - } - - /* Insert an HTML element for the token. */ - $this->insertElement($token); - break; + break; - /* A start tag whose tag name is "form" */ - case 'form': - /* If the form element pointer is not null, ignore the - token with a parse error. */ - if($this->form_pointer !== null) { - // Ignore. - - /* Otherwise: */ - } else { - /* If the stack of open elements has a p element in - scope, then act as if an end tag with the tag name p - had been seen. */ - if($this->elementInScope('p')) { - $this->emitToken(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); + /* A start tag whose tag name is one of: "address", + "blockquote", "center", "dir", "div", "dl", "fieldset", + "listing", "menu", "ol", "p", "ul" */ + case 'address': + case 'blockquote': + case 'center': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'listing': + case 'menu': + case 'ol': + case 'p': + case 'ul': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); } - /* Insert an HTML element for the token, and set the - form element pointer to point to the element created. */ - $element = $this->insertElement($token); - $this->form_pointer = $element; - } - break; + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; - /* A start tag whose tag name is "li", "dd" or "dt" */ - case 'li': case 'dd': case 'dt': - /* If the stack of open elements has a p element in scope, - then act as if an end tag with the tag name p had been - seen. */ - if($this->elementInScope('p')) { - $this->emitToken(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); - } + /* A start tag whose tag name is "form" */ + case 'form': + /* If the form element pointer is not null, ignore the + token with a parse error. */ + if ($this->form_pointer !== null) { + // Ignore. - $stack_length = count($this->stack) - 1; - - for($n = $stack_length; 0 <= $n; $n--) { - /* 1. Initialise node to be the current node (the - bottommost node of the stack). */ - $stop = false; - $node = $this->stack[$n]; - $cat = $this->getElementCategory($node->tagName); - - /* 2. If node is an li, dd or dt element, then pop all - the nodes from the current node up to node, including - node, then stop this algorithm. */ - if($token['name'] === $node->tagName || ($token['name'] !== 'li' - && ($node->tagName === 'dd' || $node->tagName === 'dt'))) { - for($x = $stack_length; $x >= $n ; $x--) { - array_pop($this->stack); + /* Otherwise: */ + } else { + /* If the stack of open elements has a p element in + scope, then act as if an end tag with the tag name p + had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); } - break; + /* Insert an HTML element for the token, and set the + form element pointer to point to the element created. */ + $element = $this->insertElement($token); + $this->form_pointer = $element; } + break; - /* 3. If node is not in the formatting category, and is - not in the phrasing category, and is not an address or - div element, then stop this algorithm. */ - if($cat !== self::FORMATTING && $cat !== self::PHRASING && - $node->tagName !== 'address' && $node->tagName !== 'div') { - break; + /* A start tag whose tag name is "li", "dd" or "dt" */ + case 'li': + case 'dd': + case 'dt': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); } - } - /* Finally, insert an HTML element with the same tag - name as the token's. */ - $this->insertElement($token); - break; + $stack_length = count($this->stack) - 1; + + for ($n = $stack_length; 0 <= $n; $n--) { + /* 1. Initialise node to be the current node (the + bottommost node of the stack). */ + $stop = false; + $node = $this->stack[$n]; + $cat = $this->getElementCategory($node->tagName); + + /* 2. If node is an li, dd or dt element, then pop all + the nodes from the current node up to node, including + node, then stop this algorithm. */ + if ($token['name'] === $node->tagName || ($token['name'] !== 'li' + && ($node->tagName === 'dd' || $node->tagName === 'dt')) + ) { + for ($x = $stack_length; $x >= $n; $x--) { + array_pop($this->stack); + } - /* A start tag token whose tag name is "plaintext" */ - case 'plaintext': - /* If the stack of open elements has a p element in scope, - then act as if an end tag with the tag name p had been - seen. */ - if($this->elementInScope('p')) { - $this->emitToken(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); - } + break; + } - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* 3. If node is not in the formatting category, and is + not in the phrasing category, and is not an address or + div element, then stop this algorithm. */ + if ($cat !== self::FORMATTING && $cat !== self::PHRASING && + $node->tagName !== 'address' && $node->tagName !== 'div' + ) { + break; + } + } - return HTML5::PLAINTEXT; - break; + /* Finally, insert an HTML element with the same tag + name as the token's. */ + $this->insertElement($token); + break; - /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4", - "h5", "h6" */ - case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': - /* If the stack of open elements has a p element in scope, - then act as if an end tag with the tag name p had been seen. */ - if($this->elementInScope('p')) { - $this->emitToken(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); - } + /* A start tag token whose tag name is "plaintext" */ + case 'plaintext': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } - /* If the stack of open elements has in scope an element whose - tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then - this is a parse error; pop elements from the stack until an - element with one of those tag names has been popped from the - stack. */ - while($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { - array_pop($this->stack); - } + /* Insert an HTML element for the token. */ + $this->insertElement($token); - /* Insert an HTML element for the token. */ - $this->insertElement($token); - break; + return HTML5::PLAINTEXT; + break; - /* A start tag whose tag name is "a" */ - case 'a': - /* If the list of active formatting elements contains - an element whose tag name is "a" between the end of the - list and the last marker on the list (or the start of - the list if there is no marker on the list), then this - is a parse error; act as if an end tag with the tag name - "a" had been seen, then remove that element from the list - of active formatting elements and the stack of open - elements if the end tag didn't already remove it (it - might not have if the element is not in table scope). */ - $leng = count($this->a_formatting); - - for($n = $leng - 1; $n >= 0; $n--) { - if($this->a_formatting[$n] === self::MARKER) { - break; - - } elseif($this->a_formatting[$n]->nodeName === 'a') { - $this->emitToken(array( - 'name' => 'a', - 'type' => HTML5::ENDTAG - )); - break; + /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); } - } - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + this is a parse error; pop elements from the stack until an + element with one of those tag names has been popped from the + stack. */ + while ($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { + array_pop($this->stack); + } - /* Insert an HTML element for the token. */ - $el = $this->insertElement($token); + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; - /* Add that element to the list of active formatting - elements. */ - $this->a_formatting[] = $el; - break; + /* A start tag whose tag name is "a" */ + case 'a': + /* If the list of active formatting elements contains + an element whose tag name is "a" between the end of the + list and the last marker on the list (or the start of + the list if there is no marker on the list), then this + is a parse error; act as if an end tag with the tag name + "a" had been seen, then remove that element from the list + of active formatting elements and the stack of open + elements if the end tag didn't already remove it (it + might not have if the element is not in table scope). */ + $leng = count($this->a_formatting); + + for ($n = $leng - 1; $n >= 0; $n--) { + if ($this->a_formatting[$n] === self::MARKER) { + break; - /* A start tag whose tag name is one of: "b", "big", "em", "font", - "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ - case 'b': case 'big': case 'em': case 'font': case 'i': - case 'nobr': case 's': case 'small': case 'strike': - case 'strong': case 'tt': case 'u': - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + } elseif ($this->a_formatting[$n]->nodeName === 'a') { + $this->emitToken( + array( + 'name' => 'a', + 'type' => HTML5::ENDTAG + ) + ); + break; + } + } - /* Insert an HTML element for the token. */ - $el = $this->insertElement($token); + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); - /* Add that element to the list of active formatting - elements. */ - $this->a_formatting[] = $el; - break; + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); - /* A start tag token whose tag name is "button" */ - case 'button': - /* If the stack of open elements has a button element in scope, - then this is a parse error; act as if an end tag with the tag - name "button" had been seen, then reprocess the token. (We don't - do that. Unnecessary.) */ - if($this->elementInScope('button')) { - $this->inBody(array( - 'name' => 'button', - 'type' => HTML5::ENDTAG - )); - } + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* A start tag whose tag name is one of: "b", "big", "em", "font", + "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'b': + case 'big': + case 'em': + case 'font': + case 'i': + case 'nobr': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* A start tag token whose tag name is "button" */ + case 'button': + /* If the stack of open elements has a button element in scope, + then this is a parse error; act as if an end tag with the tag + name "button" had been seen, then reprocess the token. (We don't + do that. Unnecessary.) */ + if ($this->elementInScope('button')) { + $this->inBody( + array( + 'name' => 'button', + 'type' => HTML5::ENDTAG + ) + ); + } - /* Insert a marker at the end of the list of active - formatting elements. */ - $this->a_formatting[] = self::MARKER; - break; + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); - /* A start tag token whose tag name is one of: "marquee", "object" */ - case 'marquee': case 'object': - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* Insert an HTML element for the token. */ + $this->insertElement($token); - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; - /* Insert a marker at the end of the list of active - formatting elements. */ - $this->a_formatting[] = self::MARKER; - break; + /* A start tag token whose tag name is one of: "marquee", "object" */ + case 'marquee': + case 'object': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); - /* A start tag token whose tag name is "xmp" */ - case 'xmp': - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* Insert an HTML element for the token. */ + $this->insertElement($token); - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; - /* Switch the content model flag to the CDATA state. */ - return HTML5::CDATA; - break; + /* A start tag token whose tag name is "xmp" */ + case 'xmp': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); - /* A start tag whose tag name is "table" */ - case 'table': - /* If the stack of open elements has a p element in scope, - then act as if an end tag with the tag name p had been seen. */ - if($this->elementInScope('p')) { - $this->emitToken(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); - } + /* Insert an HTML element for the token. */ + $this->insertElement($token); - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* Switch the content model flag to the CDATA state. */ + return HTML5::CDATA; + break; - /* Change the insertion mode to "in table". */ - $this->mode = self::IN_TABLE; - break; + /* A start tag whose tag name is "table" */ + case 'table': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } - /* A start tag whose tag name is one of: "area", "basefont", - "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */ - case 'area': case 'basefont': case 'bgsound': case 'br': - case 'embed': case 'img': case 'param': case 'spacer': - case 'wbr': - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* Insert an HTML element for the token. */ + $this->insertElement($token); - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* Change the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + break; - /* Immediately pop the current node off the stack of open elements. */ - array_pop($this->stack); - break; + /* A start tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */ + case 'area': + case 'basefont': + case 'bgsound': + case 'br': + case 'embed': + case 'img': + case 'param': + case 'spacer': + case 'wbr': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; - /* A start tag whose tag name is "hr" */ - case 'hr': - /* If the stack of open elements has a p element in scope, - then act as if an end tag with the tag name p had been seen. */ - if($this->elementInScope('p')) { - $this->emitToken(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); - } + /* A start tag whose tag name is "hr" */ + case 'hr': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* Insert an HTML element for the token. */ + $this->insertElement($token); - /* Immediately pop the current node off the stack of open elements. */ - array_pop($this->stack); - break; + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; - /* A start tag whose tag name is "image" */ - case 'image': - /* Parse error. Change the token's tag name to "img" and - reprocess it. (Don't ask.) */ - $token['name'] = 'img'; - return $this->inBody($token); - break; + /* A start tag whose tag name is "image" */ + case 'image': + /* Parse error. Change the token's tag name to "img" and + reprocess it. (Don't ask.) */ + $token['name'] = 'img'; + return $this->inBody($token); + break; - /* A start tag whose tag name is "input" */ - case 'input': - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* A start tag whose tag name is "input" */ + case 'input': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); - /* Insert an input element for the token. */ - $element = $this->insertElement($token, false); + /* Insert an input element for the token. */ + $element = $this->insertElement($token, false); - /* If the form element pointer is not null, then associate the - input element with the form element pointed to by the form - element pointer. */ - $this->form_pointer !== null - ? $this->form_pointer->appendChild($element) - : end($this->stack)->appendChild($element); + /* If the form element pointer is not null, then associate the + input element with the form element pointed to by the form + element pointer. */ + $this->form_pointer !== null + ? $this->form_pointer->appendChild($element) + : end($this->stack)->appendChild($element); - /* Pop that input element off the stack of open elements. */ - array_pop($this->stack); - break; + /* Pop that input element off the stack of open elements. */ + array_pop($this->stack); + break; - /* A start tag whose tag name is "isindex" */ - case 'isindex': - /* Parse error. */ - // w/e - - /* If the form element pointer is not null, - then ignore the token. */ - if($this->form_pointer === null) { - /* Act as if a start tag token with the tag name "form" had - been seen. */ - $this->inBody(array( - 'name' => 'body', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); - - /* Act as if a start tag token with the tag name "hr" had - been seen. */ - $this->inBody(array( - 'name' => 'hr', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); - - /* Act as if a start tag token with the tag name "p" had - been seen. */ - $this->inBody(array( - 'name' => 'p', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); - - /* Act as if a start tag token with the tag name "label" - had been seen. */ - $this->inBody(array( - 'name' => 'label', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); - - /* Act as if a stream of character tokens had been seen. */ - $this->insertText('This is a searchable index. '. - 'Insert your search keywords here: '); - - /* Act as if a start tag token with the tag name "input" - had been seen, with all the attributes from the "isindex" - token, except with the "name" attribute set to the value - "isindex" (ignoring any explicit "name" attribute). */ - $attr = $token['attr']; - $attr[] = array('name' => 'name', 'value' => 'isindex'); - - $this->inBody(array( - 'name' => 'input', - 'type' => HTML5::STARTTAG, - 'attr' => $attr - )); - - /* Act as if a stream of character tokens had been seen - (see below for what they should say). */ - $this->insertText('This is a searchable index. '. - 'Insert your search keywords here: '); - - /* Act as if an end tag token with the tag name "label" - had been seen. */ - $this->inBody(array( - 'name' => 'label', - 'type' => HTML5::ENDTAG - )); - - /* Act as if an end tag token with the tag name "p" had - been seen. */ - $this->inBody(array( - 'name' => 'p', - 'type' => HTML5::ENDTAG - )); - - /* Act as if a start tag token with the tag name "hr" had - been seen. */ - $this->inBody(array( - 'name' => 'hr', - 'type' => HTML5::ENDTAG - )); - - /* Act as if an end tag token with the tag name "form" had - been seen. */ - $this->inBody(array( - 'name' => 'form', - 'type' => HTML5::ENDTAG - )); - } - break; + /* A start tag whose tag name is "isindex" */ + case 'isindex': + /* Parse error. */ + // w/e - /* A start tag whose tag name is "textarea" */ - case 'textarea': - $this->insertElement($token); + /* If the form element pointer is not null, + then ignore the token. */ + if ($this->form_pointer === null) { + /* Act as if a start tag token with the tag name "form" had + been seen. */ + $this->inBody( + array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody( + array( + 'name' => 'hr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "p" had + been seen. */ + $this->inBody( + array( + 'name' => 'p', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "label" + had been seen. */ + $this->inBody( + array( + 'name' => 'label', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a stream of character tokens had been seen. */ + $this->insertText( + 'This is a searchable index. ' . + 'Insert your search keywords here: ' + ); + + /* Act as if a start tag token with the tag name "input" + had been seen, with all the attributes from the "isindex" + token, except with the "name" attribute set to the value + "isindex" (ignoring any explicit "name" attribute). */ + $attr = $token['attr']; + $attr[] = array('name' => 'name', 'value' => 'isindex'); + + $this->inBody( + array( + 'name' => 'input', + 'type' => HTML5::STARTTAG, + 'attr' => $attr + ) + ); + + /* Act as if a stream of character tokens had been seen + (see below for what they should say). */ + $this->insertText( + 'This is a searchable index. ' . + 'Insert your search keywords here: ' + ); + + /* Act as if an end tag token with the tag name "label" + had been seen. */ + $this->inBody( + array( + 'name' => 'label', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if an end tag token with the tag name "p" had + been seen. */ + $this->inBody( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody( + array( + 'name' => 'hr', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if an end tag token with the tag name "form" had + been seen. */ + $this->inBody( + array( + 'name' => 'form', + 'type' => HTML5::ENDTAG + ) + ); + } + break; - /* Switch the tokeniser's content model flag to the - RCDATA state. */ - return HTML5::RCDATA; - break; + /* A start tag whose tag name is "textarea" */ + case 'textarea': + $this->insertElement($token); - /* A start tag whose tag name is one of: "iframe", "noembed", - "noframes" */ - case 'iframe': case 'noembed': case 'noframes': - $this->insertElement($token); + /* Switch the tokeniser's content model flag to the + RCDATA state. */ + return HTML5::RCDATA; + break; - /* Switch the tokeniser's content model flag to the CDATA state. */ - return HTML5::CDATA; - break; + /* A start tag whose tag name is one of: "iframe", "noembed", + "noframes" */ + case 'iframe': + case 'noembed': + case 'noframes': + $this->insertElement($token); - /* A start tag whose tag name is "select" */ - case 'select': - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + break; - /* Insert an HTML element for the token. */ - $this->insertElement($token); + /* A start tag whose tag name is "select" */ + case 'select': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); - /* Change the insertion mode to "in select". */ - $this->mode = self::IN_SELECT; - break; + /* Insert an HTML element for the token. */ + $this->insertElement($token); - /* A start or end tag whose tag name is one of: "caption", "col", - "colgroup", "frame", "frameset", "head", "option", "optgroup", - "tbody", "td", "tfoot", "th", "thead", "tr". */ - case 'caption': case 'col': case 'colgroup': case 'frame': - case 'frameset': case 'head': case 'option': case 'optgroup': - case 'tbody': case 'td': case 'tfoot': case 'th': case 'thead': - case 'tr': - // Parse error. Ignore the token. - break; + /* Change the insertion mode to "in select". */ + $this->mode = self::IN_SELECT; + break; - /* A start or end tag whose tag name is one of: "event-source", - "section", "nav", "article", "aside", "header", "footer", - "datagrid", "command" */ - case 'event-source': case 'section': case 'nav': case 'article': - case 'aside': case 'header': case 'footer': case 'datagrid': - case 'command': - // Work in progress! - break; + /* A start or end tag whose tag name is one of: "caption", "col", + "colgroup", "frame", "frameset", "head", "option", "optgroup", + "tbody", "td", "tfoot", "th", "thead", "tr". */ + case 'caption': + case 'col': + case 'colgroup': + case 'frame': + case 'frameset': + case 'head': + case 'option': + case 'optgroup': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + // Parse error. Ignore the token. + break; - /* A start tag token not covered by the previous entries */ - default: - /* Reconstruct the active formatting elements, if any. */ - $this->reconstructActiveFormattingElements(); + /* A start or end tag whose tag name is one of: "event-source", + "section", "nav", "article", "aside", "header", "footer", + "datagrid", "command" */ + case 'event-source': + case 'section': + case 'nav': + case 'article': + case 'aside': + case 'header': + case 'footer': + case 'datagrid': + case 'command': + // Work in progress! + break; + + /* A start tag token not covered by the previous entries */ + default: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); - $this->insertElement($token, true, true); + $this->insertElement($token, true, true); + break; + } break; - } - break; case HTML5::ENDTAG: - switch($token['name']) { - /* An end tag with the tag name "body" */ - case 'body': - /* If the second element in the stack of open elements is - not a body element, this is a parse error. Ignore the token. - (innerHTML case) */ - if(count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') { - // Ignore. - - /* If the current node is not the body element, then this - is a parse error. */ - } elseif(end($this->stack)->nodeName !== 'body') { - // Parse error. - } + switch ($token['name']) { + /* An end tag with the tag name "body" */ + case 'body': + /* If the second element in the stack of open elements is + not a body element, this is a parse error. Ignore the token. + (innerHTML case) */ + if (count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') { + // Ignore. + + /* If the current node is not the body element, then this + is a parse error. */ + } elseif (end($this->stack)->nodeName !== 'body') { + // Parse error. + } - /* Change the insertion mode to "after body". */ - $this->mode = self::AFTER_BODY; - break; + /* Change the insertion mode to "after body". */ + $this->mode = self::AFTER_BODY; + break; - /* An end tag with the tag name "html" */ - case 'html': - /* Act as if an end tag with tag name "body" had been seen, - then, if that token wasn't ignored, reprocess the current - token. */ - $this->inBody(array( - 'name' => 'body', - 'type' => HTML5::ENDTAG - )); + /* An end tag with the tag name "html" */ + case 'html': + /* Act as if an end tag with tag name "body" had been seen, + then, if that token wasn't ignored, reprocess the current + token. */ + $this->inBody( + array( + 'name' => 'body', + 'type' => HTML5::ENDTAG + ) + ); - return $this->afterBody($token); - break; + return $this->afterBody($token); + break; - /* An end tag whose tag name is one of: "address", "blockquote", - "center", "dir", "div", "dl", "fieldset", "listing", "menu", - "ol", "pre", "ul" */ - case 'address': case 'blockquote': case 'center': case 'dir': - case 'div': case 'dl': case 'fieldset': case 'listing': - case 'menu': case 'ol': case 'pre': case 'ul': - /* If the stack of open elements has an element in scope - with the same tag name as that of the token, then generate - implied end tags. */ - if($this->elementInScope($token['name'])) { - $this->generateImpliedEndTags(); - - /* Now, if the current node is not an element with - the same tag name as that of the token, then this - is a parse error. */ - // w/e + /* An end tag whose tag name is one of: "address", "blockquote", + "center", "dir", "div", "dl", "fieldset", "listing", "menu", + "ol", "pre", "ul" */ + case 'address': + case 'blockquote': + case 'center': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'listing': + case 'menu': + case 'ol': + case 'pre': + case 'ul': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); - /* If the stack of open elements has an element in - scope with the same tag name as that of the token, - then pop elements from this stack until an element - with that tag name has been popped from the stack. */ - for($n = count($this->stack) - 1; $n >= 0; $n--) { - if($this->stack[$n]->nodeName === $token['name']) { - $n = -1; + /* Now, if the current node is not an element with + the same tag name as that of the token, then this + is a parse error. */ + // w/e + + /* If the stack of open elements has an element in + scope with the same tag name as that of the token, + then pop elements from this stack until an element + with that tag name has been popped from the stack. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); } + } + break; + + /* An end tag whose tag name is "form" */ + case 'form': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); - array_pop($this->stack); } - } - break; - /* An end tag whose tag name is "form" */ - case 'form': - /* If the stack of open elements has an element in scope - with the same tag name as that of the token, then generate - implied end tags. */ - if($this->elementInScope($token['name'])) { - $this->generateImpliedEndTags(); + if (end($this->stack)->nodeName !== $token['name']) { + /* Now, if the current node is not an element with the + same tag name as that of the token, then this is a parse + error. */ + // w/e - } + } else { + /* Otherwise, if the current node is an element with + the same tag name as that of the token pop that element + from the stack. */ + array_pop($this->stack); + } - if(end($this->stack)->nodeName !== $token['name']) { - /* Now, if the current node is not an element with the - same tag name as that of the token, then this is a parse - error. */ - // w/e + /* In any case, set the form element pointer to null. */ + $this->form_pointer = null; + break; - } else { - /* Otherwise, if the current node is an element with - the same tag name as that of the token pop that element - from the stack. */ - array_pop($this->stack); - } + /* An end tag whose tag name is "p" */ + case 'p': + /* If the stack of open elements has a p element in scope, + then generate implied end tags, except for p elements. */ + if ($this->elementInScope('p')) { + $this->generateImpliedEndTags(array('p')); - /* In any case, set the form element pointer to null. */ - $this->form_pointer = null; - break; + /* If the current node is not a p element, then this is + a parse error. */ + // k - /* An end tag whose tag name is "p" */ - case 'p': - /* If the stack of open elements has a p element in scope, - then generate implied end tags, except for p elements. */ - if($this->elementInScope('p')) { - $this->generateImpliedEndTags(array('p')); - - /* If the current node is not a p element, then this is - a parse error. */ - // k - - /* If the stack of open elements has a p element in - scope, then pop elements from this stack until the stack - no longer has a p element in scope. */ - for($n = count($this->stack) - 1; $n >= 0; $n--) { - if($this->elementInScope('p')) { - array_pop($this->stack); + /* If the stack of open elements has a p element in + scope, then pop elements from this stack until the stack + no longer has a p element in scope. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->elementInScope('p')) { + array_pop($this->stack); - } else { - break; + } else { + break; + } } } - } - break; - - /* An end tag whose tag name is "dd", "dt", or "li" */ - case 'dd': case 'dt': case 'li': - /* If the stack of open elements has an element in scope - whose tag name matches the tag name of the token, then - generate implied end tags, except for elements with the - same tag name as the token. */ - if($this->elementInScope($token['name'])) { - $this->generateImpliedEndTags(array($token['name'])); - - /* If the current node is not an element with the same - tag name as the token, then this is a parse error. */ - // w/e + break; + /* An end tag whose tag name is "dd", "dt", or "li" */ + case 'dd': + case 'dt': + case 'li': /* If the stack of open elements has an element in scope whose tag name matches the tag name of the token, then - pop elements from this stack until an element with that - tag name has been popped from the stack. */ - for($n = count($this->stack) - 1; $n >= 0; $n--) { - if($this->stack[$n]->nodeName === $token['name']) { - $n = -1; - } + generate implied end tags, except for elements with the + same tag name as the token. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(array($token['name'])); + + /* If the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // w/e + + /* If the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then + pop elements from this stack until an element with that + tag name has been popped from the stack. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } - array_pop($this->stack); + array_pop($this->stack); + } } - } - break; - - /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4", - "h5", "h6" */ - case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': - $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); + break; - /* If the stack of open elements has in scope an element whose - tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then - generate implied end tags. */ - if($this->elementInScope($elements)) { - $this->generateImpliedEndTags(); + /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); + + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + generate implied end tags. */ + if ($this->elementInScope($elements)) { + $this->generateImpliedEndTags(); - /* Now, if the current node is not an element with the same - tag name as that of the token, then this is a parse error. */ - // w/e + /* Now, if the current node is not an element with the same + tag name as that of the token, then this is a parse error. */ + // w/e - /* If the stack of open elements has in scope an element - whose tag name is one of "h1", "h2", "h3", "h4", "h5", or - "h6", then pop elements from the stack until an element - with one of those tag names has been popped from the stack. */ - while($this->elementInScope($elements)) { - array_pop($this->stack); + /* If the stack of open elements has in scope an element + whose tag name is one of "h1", "h2", "h3", "h4", "h5", or + "h6", then pop elements from the stack until an element + with one of those tag names has been popped from the stack. */ + while ($this->elementInScope($elements)) { + array_pop($this->stack); + } } - } - break; + break; - /* An end tag whose tag name is one of: "a", "b", "big", "em", - "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ - case 'a': case 'b': case 'big': case 'em': case 'font': - case 'i': case 'nobr': case 's': case 'small': case 'strike': - case 'strong': case 'tt': case 'u': - /* 1. Let the formatting element be the last element in - the list of active formatting elements that: - * is between the end of the list and the last scope - marker in the list, if any, or the start of the list - otherwise, and - * has the same tag name as the token. - */ - while(true) { - for($a = count($this->a_formatting) - 1; $a >= 0; $a--) { - if($this->a_formatting[$a] === self::MARKER) { + /* An end tag whose tag name is one of: "a", "b", "big", "em", + "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'a': + case 'b': + case 'big': + case 'em': + case 'font': + case 'i': + case 'nobr': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + /* 1. Let the formatting element be the last element in + the list of active formatting elements that: + * is between the end of the list and the last scope + marker in the list, if any, or the start of the list + otherwise, and + * has the same tag name as the token. + */ + while (true) { + for ($a = count($this->a_formatting) - 1; $a >= 0; $a--) { + if ($this->a_formatting[$a] === self::MARKER) { + break; + + } elseif ($this->a_formatting[$a]->tagName === $token['name']) { + $formatting_element = $this->a_formatting[$a]; + $in_stack = in_array($formatting_element, $this->stack, true); + $fe_af_pos = $a; + break; + } + } + + /* If there is no such node, or, if that node is + also in the stack of open elements but the element + is not in scope, then this is a parse error. Abort + these steps. The token is ignored. */ + if (!isset($formatting_element) || ($in_stack && + !$this->elementInScope($token['name'])) + ) { break; - } elseif($this->a_formatting[$a]->tagName === $token['name']) { - $formatting_element = $this->a_formatting[$a]; - $in_stack = in_array($formatting_element, $this->stack, true); - $fe_af_pos = $a; + /* Otherwise, if there is such a node, but that node + is not in the stack of open elements, then this is a + parse error; remove the element from the list, and + abort these steps. */ + } elseif (isset($formatting_element) && !$in_stack) { + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); break; } - } - - /* If there is no such node, or, if that node is - also in the stack of open elements but the element - is not in scope, then this is a parse error. Abort - these steps. The token is ignored. */ - if(!isset($formatting_element) || ($in_stack && - !$this->elementInScope($token['name']))) { - break; - - /* Otherwise, if there is such a node, but that node - is not in the stack of open elements, then this is a - parse error; remove the element from the list, and - abort these steps. */ - } elseif(isset($formatting_element) && !$in_stack) { - unset($this->a_formatting[$fe_af_pos]); - $this->a_formatting = array_merge($this->a_formatting); - break; - } - /* 2. Let the furthest block be the topmost node in the - stack of open elements that is lower in the stack - than the formatting element, and is not an element in - the phrasing or formatting categories. There might - not be one. */ - $fe_s_pos = array_search($formatting_element, $this->stack, true); - $length = count($this->stack); + /* 2. Let the furthest block be the topmost node in the + stack of open elements that is lower in the stack + than the formatting element, and is not an element in + the phrasing or formatting categories. There might + not be one. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $length = count($this->stack); - for($s = $fe_s_pos + 1; $s < $length; $s++) { - $category = $this->getElementCategory($this->stack[$s]->nodeName); + for ($s = $fe_s_pos + 1; $s < $length; $s++) { + $category = $this->getElementCategory($this->stack[$s]->nodeName); - if($category !== self::PHRASING && $category !== self::FORMATTING) { - $furthest_block = $this->stack[$s]; + if ($category !== self::PHRASING && $category !== self::FORMATTING) { + $furthest_block = $this->stack[$s]; + } } - } - /* 3. If there is no furthest block, then the UA must - skip the subsequent steps and instead just pop all - the nodes from the bottom of the stack of open - elements, from the current node up to the formatting - element, and remove the formatting element from the - list of active formatting elements. */ - if(!isset($furthest_block)) { - for($n = $length - 1; $n >= $fe_s_pos; $n--) { - array_pop($this->stack); - } + /* 3. If there is no furthest block, then the UA must + skip the subsequent steps and instead just pop all + the nodes from the bottom of the stack of open + elements, from the current node up to the formatting + element, and remove the formatting element from the + list of active formatting elements. */ + if (!isset($furthest_block)) { + for ($n = $length - 1; $n >= $fe_s_pos; $n--) { + array_pop($this->stack); + } - unset($this->a_formatting[$fe_af_pos]); - $this->a_formatting = array_merge($this->a_formatting); - break; - } + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + break; + } - /* 4. Let the common ancestor be the element - immediately above the formatting element in the stack - of open elements. */ - $common_ancestor = $this->stack[$fe_s_pos - 1]; + /* 4. Let the common ancestor be the element + immediately above the formatting element in the stack + of open elements. */ + $common_ancestor = $this->stack[$fe_s_pos - 1]; - /* 5. If the furthest block has a parent node, then - remove the furthest block from its parent node. */ - if($furthest_block->parentNode !== null) { - $furthest_block->parentNode->removeChild($furthest_block); - } + /* 5. If the furthest block has a parent node, then + remove the furthest block from its parent node. */ + if ($furthest_block->parentNode !== null) { + $furthest_block->parentNode->removeChild($furthest_block); + } - /* 6. Let a bookmark note the position of the - formatting element in the list of active formatting - elements relative to the elements on either side - of it in the list. */ - $bookmark = $fe_af_pos; - - /* 7. Let node and last node be the furthest block. - Follow these steps: */ - $node = $furthest_block; - $last_node = $furthest_block; - - while(true) { - for($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) { - /* 7.1 Let node be the element immediately - prior to node in the stack of open elements. */ - $node = $this->stack[$n]; - - /* 7.2 If node is not in the list of active - formatting elements, then remove node from - the stack of open elements and then go back - to step 1. */ - if(!in_array($node, $this->a_formatting, true)) { - unset($this->stack[$n]); - $this->stack = array_merge($this->stack); + /* 6. Let a bookmark note the position of the + formatting element in the list of active formatting + elements relative to the elements on either side + of it in the list. */ + $bookmark = $fe_af_pos; + + /* 7. Let node and last node be the furthest block. + Follow these steps: */ + $node = $furthest_block; + $last_node = $furthest_block; + + while (true) { + for ($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) { + /* 7.1 Let node be the element immediately + prior to node in the stack of open elements. */ + $node = $this->stack[$n]; + + /* 7.2 If node is not in the list of active + formatting elements, then remove node from + the stack of open elements and then go back + to step 1. */ + if (!in_array($node, $this->a_formatting, true)) { + unset($this->stack[$n]); + $this->stack = array_merge($this->stack); + + } else { + break; + } + } - } else { + /* 7.3 Otherwise, if node is the formatting + element, then go to the next step in the overall + algorithm. */ + if ($node === $formatting_element) { break; + + /* 7.4 Otherwise, if last node is the furthest + block, then move the aforementioned bookmark to + be immediately after the node in the list of + active formatting elements. */ + } elseif ($last_node === $furthest_block) { + $bookmark = array_search($node, $this->a_formatting, true) + 1; } - } - /* 7.3 Otherwise, if node is the formatting - element, then go to the next step in the overall - algorithm. */ - if($node === $formatting_element) { - break; + /* 7.5 If node has any children, perform a + shallow clone of node, replace the entry for + node in the list of active formatting elements + with an entry for the clone, replace the entry + for node in the stack of open elements with an + entry for the clone, and let node be the clone. */ + if ($node->hasChildNodes()) { + $clone = $node->cloneNode(); + $s_pos = array_search($node, $this->stack, true); + $a_pos = array_search($node, $this->a_formatting, true); + + $this->stack[$s_pos] = $clone; + $this->a_formatting[$a_pos] = $clone; + $node = $clone; + } - /* 7.4 Otherwise, if last node is the furthest - block, then move the aforementioned bookmark to - be immediately after the node in the list of - active formatting elements. */ - } elseif($last_node === $furthest_block) { - $bookmark = array_search($node, $this->a_formatting, true) + 1; - } + /* 7.6 Insert last node into node, first removing + it from its previous parent node if any. */ + if ($last_node->parentNode !== null) { + $last_node->parentNode->removeChild($last_node); + } + + $node->appendChild($last_node); - /* 7.5 If node has any children, perform a - shallow clone of node, replace the entry for - node in the list of active formatting elements - with an entry for the clone, replace the entry - for node in the stack of open elements with an - entry for the clone, and let node be the clone. */ - if($node->hasChildNodes()) { - $clone = $node->cloneNode(); - $s_pos = array_search($node, $this->stack, true); - $a_pos = array_search($node, $this->a_formatting, true); - - $this->stack[$s_pos] = $clone; - $this->a_formatting[$a_pos] = $clone; - $node = $clone; + /* 7.7 Let last node be node. */ + $last_node = $node; } - /* 7.6 Insert last node into node, first removing - it from its previous parent node if any. */ - if($last_node->parentNode !== null) { + /* 8. Insert whatever last node ended up being in + the previous step into the common ancestor node, + first removing it from its previous parent node if + any. */ + if ($last_node->parentNode !== null) { $last_node->parentNode->removeChild($last_node); } - $node->appendChild($last_node); + $common_ancestor->appendChild($last_node); - /* 7.7 Let last node be node. */ - $last_node = $node; - } + /* 9. Perform a shallow clone of the formatting + element. */ + $clone = $formatting_element->cloneNode(); - /* 8. Insert whatever last node ended up being in - the previous step into the common ancestor node, - first removing it from its previous parent node if - any. */ - if($last_node->parentNode !== null) { - $last_node->parentNode->removeChild($last_node); - } + /* 10. Take all of the child nodes of the furthest + block and append them to the clone created in the + last step. */ + while ($furthest_block->hasChildNodes()) { + $child = $furthest_block->firstChild; + $furthest_block->removeChild($child); + $clone->appendChild($child); + } - $common_ancestor->appendChild($last_node); + /* 11. Append that clone to the furthest block. */ + $furthest_block->appendChild($clone); - /* 9. Perform a shallow clone of the formatting - element. */ - $clone = $formatting_element->cloneNode(); + /* 12. Remove the formatting element from the list + of active formatting elements, and insert the clone + into the list of active formatting elements at the + position of the aforementioned bookmark. */ + $fe_af_pos = array_search($formatting_element, $this->a_formatting, true); + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); - /* 10. Take all of the child nodes of the furthest - block and append them to the clone created in the - last step. */ - while($furthest_block->hasChildNodes()) { - $child = $furthest_block->firstChild; - $furthest_block->removeChild($child); - $clone->appendChild($child); + $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1); + $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting)); + $this->a_formatting = array_merge($af_part1, array($clone), $af_part2); + + /* 13. Remove the formatting element from the stack + of open elements, and insert the clone into the stack + of open elements immediately after (i.e. in a more + deeply nested position than) the position of the + furthest block in that stack. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $fb_s_pos = array_search($furthest_block, $this->stack, true); + unset($this->stack[$fe_s_pos]); + + $s_part1 = array_slice($this->stack, 0, $fb_s_pos); + $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack)); + $this->stack = array_merge($s_part1, array($clone), $s_part2); + + /* 14. Jump back to step 1 in this series of steps. */ + unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block); } + break; - /* 11. Append that clone to the furthest block. */ - $furthest_block->appendChild($clone); - - /* 12. Remove the formatting element from the list - of active formatting elements, and insert the clone - into the list of active formatting elements at the - position of the aforementioned bookmark. */ - $fe_af_pos = array_search($formatting_element, $this->a_formatting, true); - unset($this->a_formatting[$fe_af_pos]); - $this->a_formatting = array_merge($this->a_formatting); - - $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1); - $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting)); - $this->a_formatting = array_merge($af_part1, array($clone), $af_part2); - - /* 13. Remove the formatting element from the stack - of open elements, and insert the clone into the stack - of open elements immediately after (i.e. in a more - deeply nested position than) the position of the - furthest block in that stack. */ - $fe_s_pos = array_search($formatting_element, $this->stack, true); - $fb_s_pos = array_search($furthest_block, $this->stack, true); - unset($this->stack[$fe_s_pos]); - - $s_part1 = array_slice($this->stack, 0, $fb_s_pos); - $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack)); - $this->stack = array_merge($s_part1, array($clone), $s_part2); - - /* 14. Jump back to step 1 in this series of steps. */ - unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block); - } - break; + /* An end tag token whose tag name is one of: "button", + "marquee", "object" */ + case 'button': + case 'marquee': + case 'object': + /* If the stack of open elements has an element in scope whose + tag name matches the tag name of the token, then generate implied + tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); - /* An end tag token whose tag name is one of: "button", - "marquee", "object" */ - case 'button': case 'marquee': case 'object': - /* If the stack of open elements has an element in scope whose - tag name matches the tag name of the token, then generate implied - tags. */ - if($this->elementInScope($token['name'])) { - $this->generateImpliedEndTags(); - - /* Now, if the current node is not an element with the same - tag name as the token, then this is a parse error. */ - // k - - /* Now, if the stack of open elements has an element in scope - whose tag name matches the tag name of the token, then pop - elements from the stack until that element has been popped from - the stack, and clear the list of active formatting elements up - to the last marker. */ - for($n = count($this->stack) - 1; $n >= 0; $n--) { - if($this->stack[$n]->nodeName === $token['name']) { - $n = -1; - } + /* Now, if the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // k - array_pop($this->stack); - } + /* Now, if the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then pop + elements from the stack until that element has been popped from + the stack, and clear the list of active formatting elements up + to the last marker. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } - $marker = end(array_keys($this->a_formatting, self::MARKER, true)); + array_pop($this->stack); + } - for($n = count($this->a_formatting) - 1; $n > $marker; $n--) { - array_pop($this->a_formatting); - } - } - break; + $marker = end(array_keys($this->a_formatting, self::MARKER, true)); - /* Or an end tag whose tag name is one of: "area", "basefont", - "bgsound", "br", "embed", "hr", "iframe", "image", "img", - "input", "isindex", "noembed", "noframes", "param", "select", - "spacer", "table", "textarea", "wbr" */ - case 'area': case 'basefont': case 'bgsound': case 'br': - case 'embed': case 'hr': case 'iframe': case 'image': - case 'img': case 'input': case 'isindex': case 'noembed': - case 'noframes': case 'param': case 'select': case 'spacer': - case 'table': case 'textarea': case 'wbr': - // Parse error. Ignore the token. - break; + for ($n = count($this->a_formatting) - 1; $n > $marker; $n--) { + array_pop($this->a_formatting); + } + } + break; - /* An end tag token not covered by the previous entries */ - default: - for($n = count($this->stack) - 1; $n >= 0; $n--) { - /* Initialise node to be the current node (the bottommost - node of the stack). */ - $node = end($this->stack); - - /* If node has the same tag name as the end tag token, - then: */ - if($token['name'] === $node->nodeName) { - /* Generate implied end tags. */ - $this->generateImpliedEndTags(); + /* Or an end tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "hr", "iframe", "image", "img", + "input", "isindex", "noembed", "noframes", "param", "select", + "spacer", "table", "textarea", "wbr" */ + case 'area': + case 'basefont': + case 'bgsound': + case 'br': + case 'embed': + case 'hr': + case 'iframe': + case 'image': + case 'img': + case 'input': + case 'isindex': + case 'noembed': + case 'noframes': + case 'param': + case 'select': + case 'spacer': + case 'table': + case 'textarea': + case 'wbr': + // Parse error. Ignore the token. + break; - /* If the tag name of the end tag token does not - match the tag name of the current node, this is a - parse error. */ - // k + /* An end tag token not covered by the previous entries */ + default: + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + /* Initialise node to be the current node (the bottommost + node of the stack). */ + $node = end($this->stack); + + /* If node has the same tag name as the end tag token, + then: */ + if ($token['name'] === $node->nodeName) { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* If the tag name of the end tag token does not + match the tag name of the current node, this is a + parse error. */ + // k + + /* Pop all the nodes from the current node up to + node, including node, then stop this algorithm. */ + for ($x = count($this->stack) - $n; $x >= $n; $x--) { + array_pop($this->stack); + } - /* Pop all the nodes from the current node up to - node, including node, then stop this algorithm. */ - for($x = count($this->stack) - $n; $x >= $n; $x--) { - array_pop($this->stack); - } - - } else { - $category = $this->getElementCategory($node); - - if($category !== self::SPECIAL && $category !== self::SCOPING) { - /* Otherwise, if node is in neither the formatting - category nor the phrasing category, then this is a - parse error. Stop this algorithm. The end tag token - is ignored. */ - return false; + } else { + $category = $this->getElementCategory($node); + + if ($category !== self::SPECIAL && $category !== self::SCOPING) { + /* Otherwise, if node is in neither the formatting + category nor the phrasing category, then this is a + parse error. Stop this algorithm. The end tag token + is ignored. */ + return false; + } } } - } + break; + } break; - } - break; } } - private function inTable($token) { + private function inTable($token) + { $clear = array('html', 'table'); /* A character token that is one of one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), or U+0020 SPACE */ - if($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Append the character to the current node. */ $text = $this->dom->createTextNode($token['data']); end($this->stack)->appendChild($text); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $comment = $this->dom->createComment($token['data']); end($this->stack)->appendChild($comment); - /* A start tag whose tag name is "caption" */ - } elseif($token['type'] === HTML5::STARTTAG && - $token['name'] === 'caption') { + /* A start tag whose tag name is "caption" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'caption' + ) { /* Clear the stack back to a table context. */ $this->clearStackToTableContext($clear); @@ -2661,9 +3350,10 @@ class HTML5TreeConstructer { $this->insertElement($token); $this->mode = self::IN_CAPTION; - /* A start tag whose tag name is "colgroup" */ - } elseif($token['type'] === HTML5::STARTTAG && - $token['name'] === 'colgroup') { + /* A start tag whose tag name is "colgroup" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'colgroup' + ) { /* Clear the stack back to a table context. */ $this->clearStackToTableContext($clear); @@ -2672,20 +3362,26 @@ class HTML5TreeConstructer { $this->insertElement($token); $this->mode = self::IN_CGROUP; - /* A start tag whose tag name is "col" */ - } elseif($token['type'] === HTML5::STARTTAG && - $token['name'] === 'col') { - $this->inTable(array( - 'name' => 'colgroup', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); + /* A start tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'col' + ) { + $this->inTable( + array( + 'name' => 'colgroup', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); $this->inColumnGroup($token); - /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ - } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('tbody', 'tfoot', 'thead'))) { + /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('tbody', 'tfoot', 'thead') + ) + ) { /* Clear the stack back to a table context. */ $this->clearStackToTableContext($clear); @@ -2694,42 +3390,49 @@ class HTML5TreeConstructer { $this->insertElement($token); $this->mode = self::IN_TBODY; - /* A start tag whose tag name is one of: "td", "th", "tr" */ - } elseif($token['type'] === HTML5::STARTTAG && - in_array($token['name'], array('td', 'th', 'tr'))) { + /* A start tag whose tag name is one of: "td", "th", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && + in_array($token['name'], array('td', 'th', 'tr')) + ) { /* Act as if a start tag token with the tag name "tbody" had been seen, then reprocess the current token. */ - $this->inTable(array( - 'name' => 'tbody', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); + $this->inTable( + array( + 'name' => 'tbody', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); return $this->inTableBody($token); - /* A start tag whose tag name is "table" */ - } elseif($token['type'] === HTML5::STARTTAG && - $token['name'] === 'table') { + /* A start tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'table' + ) { /* Parse error. Act as if an end tag token with the tag name "table" had been seen, then, if that token wasn't ignored, reprocess the current token. */ - $this->inTable(array( - 'name' => 'table', - 'type' => HTML5::ENDTAG - )); + $this->inTable( + array( + 'name' => 'table', + 'type' => HTML5::ENDTAG + ) + ); return $this->mainPhase($token); - /* An end tag whose tag name is "table" */ - } elseif($token['type'] === HTML5::ENDTAG && - $token['name'] === 'table') { + /* An end tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table' + ) { /* If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. (innerHTML case) */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { return false; - /* Otherwise: */ + /* Otherwise: */ } else { /* Generate implied end tags. */ $this->generateImpliedEndTags(); @@ -2740,11 +3443,11 @@ class HTML5TreeConstructer { /* Pop elements from this stack until a table element has been popped from the stack. */ - while(true) { + while (true) { $current = end($this->stack)->nodeName; array_pop($this->stack); - if($current === 'table') { + if ($current === 'table') { break; } } @@ -2753,14 +3456,28 @@ class HTML5TreeConstructer { $this->resetInsertionMode(); } - /* An end tag whose tag name is one of: "body", "caption", "col", - "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ - } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], - array('body', 'caption', 'col', 'colgroup', 'html', 'tbody', 'td', - 'tfoot', 'th', 'thead', 'tr'))) { + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array( + 'body', + 'caption', + 'col', + 'colgroup', + 'html', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { // Parse error. Ignore the token. - /* Anything else */ + /* Anything else */ } else { /* Parse error. Process the token as if the insertion mode was "in body", with the following exception: */ @@ -2768,8 +3485,11 @@ class HTML5TreeConstructer { /* If the current node is a table, tbody, tfoot, thead, or tr element, then, whenever a node would be inserted into the current node, it must instead be inserted into the foster parent element. */ - if(in_array(end($this->stack)->nodeName, - array('table', 'tbody', 'tfoot', 'thead', 'tr'))) { + if (in_array( + end($this->stack)->nodeName, + array('table', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { /* The foster parent element is the parent element of the last table element in the stack of open elements, if there is a table element and it has such a parent element. If there is no @@ -2781,21 +3501,22 @@ class HTML5TreeConstructer { its parent node is not an element, then the foster parent element is the element before the last table element in the stack of open elements. */ - for($n = count($this->stack) - 1; $n >= 0; $n--) { - if($this->stack[$n]->nodeName === 'table') { + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === 'table') { $table = $this->stack[$n]; break; } } - if(isset($table) && $table->parentNode !== null) { + if (isset($table) && $table->parentNode !== null) { $this->foster_parent = $table->parentNode; - } elseif(!isset($table)) { + } elseif (!isset($table)) { $this->foster_parent = $this->stack[0]; - } elseif(isset($table) && ($table->parentNode === null || - $table->parentNode->nodeType !== XML_ELEMENT_NODE)) { + } elseif (isset($table) && ($table->parentNode === null || + $table->parentNode->nodeType !== XML_ELEMENT_NODE) + ) { $this->foster_parent = $this->stack[$n - 1]; } } @@ -2804,16 +3525,17 @@ class HTML5TreeConstructer { } } - private function inCaption($token) { + private function inCaption($token) + { /* An end tag whose tag name is "caption" */ - if($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') { + if ($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') { /* If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. (innerHTML case) */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { // Ignore - /* Otherwise: */ + /* Otherwise: */ } else { /* Generate implied end tags. */ $this->generateImpliedEndTags(); @@ -2824,11 +3546,11 @@ class HTML5TreeConstructer { /* Pop elements from this stack until a caption element has been popped from the stack. */ - while(true) { + while (true) { $node = end($this->stack)->nodeName; array_pop($this->stack); - if($node === 'caption') { + if ($node === 'caption') { break; } } @@ -2841,99 +3563,131 @@ class HTML5TreeConstructer { $this->mode = self::IN_TABLE; } - /* A start tag whose tag name is one of: "caption", "col", "colgroup", - "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag - name is "table" */ - } elseif(($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', - 'thead', 'tr'))) || ($token['type'] === HTML5::ENDTAG && - $token['name'] === 'table')) { + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag + name is "table" */ + } elseif (($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + )) || ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table') + ) { /* Parse error. Act as if an end tag with the tag name "caption" had been seen, then, if that token wasn't ignored, reprocess the current token. */ - $this->inCaption(array( - 'name' => 'caption', - 'type' => HTML5::ENDTAG - )); + $this->inCaption( + array( + 'name' => 'caption', + 'type' => HTML5::ENDTAG + ) + ); return $this->inTable($token); - /* An end tag whose tag name is one of: "body", "col", "colgroup", - "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ - } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], - array('body', 'col', 'colgroup', 'html', 'tbody', 'tfoot', 'th', - 'thead', 'tr'))) { + /* An end tag whose tag name is one of: "body", "col", "colgroup", + "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array( + 'body', + 'col', + 'colgroup', + 'html', + 'tbody', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { // Parse error. Ignore the token. - /* Anything else */ + /* Anything else */ } else { /* Process the token as if the insertion mode was "in body". */ $this->inBody($token); } } - private function inColumnGroup($token) { + private function inColumnGroup($token) + { /* A character token that is one of one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), or U+0020 SPACE */ - if($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Append the character to the current node. */ $text = $this->dom->createTextNode($token['data']); end($this->stack)->appendChild($text); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $comment = $this->dom->createComment($token['data']); end($this->stack)->appendChild($comment); - /* A start tag whose tag name is "col" */ - } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') { + /* A start tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') { /* Insert a col element for the token. Immediately pop the current node off the stack of open elements. */ $this->insertElement($token); array_pop($this->stack); - /* An end tag whose tag name is "colgroup" */ - } elseif($token['type'] === HTML5::ENDTAG && - $token['name'] === 'colgroup') { + /* An end tag whose tag name is "colgroup" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'colgroup' + ) { /* If the current node is the root html element, then this is a parse error, ignore the token. (innerHTML case) */ - if(end($this->stack)->nodeName === 'html') { + if (end($this->stack)->nodeName === 'html') { // Ignore - /* Otherwise, pop the current node (which will be a colgroup - element) from the stack of open elements. Switch the insertion - mode to "in table". */ + /* Otherwise, pop the current node (which will be a colgroup + element) from the stack of open elements. Switch the insertion + mode to "in table". */ } else { array_pop($this->stack); $this->mode = self::IN_TABLE; } - /* An end tag whose tag name is "col" */ - } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') { + /* An end tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') { /* Parse error. Ignore the token. */ - /* Anything else */ + /* Anything else */ } else { /* Act as if an end tag with the tag name "colgroup" had been seen, and then, if that token wasn't ignored, reprocess the current token. */ - $this->inColumnGroup(array( - 'name' => 'colgroup', - 'type' => HTML5::ENDTAG - )); + $this->inColumnGroup( + array( + 'name' => 'colgroup', + 'type' => HTML5::ENDTAG + ) + ); return $this->inTable($token); } } - private function inTableBody($token) { + private function inTableBody($token) + { $clear = array('tbody', 'tfoot', 'thead', 'html'); /* A start tag whose tag name is "tr" */ - if($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') { + if ($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') { /* Clear the stack back to a table body context. */ $this->clearStackToTableContext($clear); @@ -2942,29 +3696,33 @@ class HTML5TreeConstructer { $this->insertElement($token); $this->mode = self::IN_ROW; - /* A start tag whose tag name is one of: "th", "td" */ - } elseif($token['type'] === HTML5::STARTTAG && - ($token['name'] === 'th' || $token['name'] === 'td')) { + /* A start tag whose tag name is one of: "th", "td" */ + } elseif ($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td') + ) { /* Parse error. Act as if a start tag with the tag name "tr" had been seen, then reprocess the current token. */ - $this->inTableBody(array( - 'name' => 'tr', - 'type' => HTML5::STARTTAG, - 'attr' => array() - )); + $this->inTableBody( + array( + 'name' => 'tr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); return $this->inRow($token); - /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ - } elseif($token['type'] === HTML5::ENDTAG && - in_array($token['name'], array('tbody', 'tfoot', 'thead'))) { + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead')) + ) { /* If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { // Ignore - /* Otherwise: */ + /* Otherwise: */ } else { /* Clear the stack back to a table body context. */ $this->clearStackToTableContext($clear); @@ -2975,18 +3733,21 @@ class HTML5TreeConstructer { $this->mode = self::IN_TABLE; } - /* A start tag whose tag name is one of: "caption", "col", "colgroup", - "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */ - } elseif(($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead'))) || - ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table')) { + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */ + } elseif (($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead') + )) || + ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table') + ) { /* If the stack of open elements does not have a tbody, thead, or tfoot element in table scope, this is a parse error. Ignore the token. (innerHTML case) */ - if(!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) { + if (!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) { // Ignore. - /* Otherwise: */ + /* Otherwise: */ } else { /* Clear the stack back to a table body context. */ $this->clearStackToTableContext($clear); @@ -2994,33 +3755,40 @@ class HTML5TreeConstructer { /* Act as if an end tag with the same tag name as the current node ("tbody", "tfoot", or "thead") had been seen, then reprocess the current token. */ - $this->inTableBody(array( - 'name' => end($this->stack)->nodeName, - 'type' => HTML5::ENDTAG - )); + $this->inTableBody( + array( + 'name' => end($this->stack)->nodeName, + 'type' => HTML5::ENDTAG + ) + ); return $this->mainPhase($token); } - /* An end tag whose tag name is one of: "body", "caption", "col", - "colgroup", "html", "td", "th", "tr" */ - } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], - array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'))) { + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr') + ) + ) { /* Parse error. Ignore the token. */ - /* Anything else */ + /* Anything else */ } else { /* Process the token as if the insertion mode was "in table". */ $this->inTable($token); } } - private function inRow($token) { + private function inRow($token) + { $clear = array('tr', 'html'); /* A start tag whose tag name is one of: "th", "td" */ - if($token['type'] === HTML5::STARTTAG && - ($token['name'] === 'th' || $token['name'] === 'td')) { + if ($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td') + ) { /* Clear the stack back to a table row context. */ $this->clearStackToTableContext($clear); @@ -3033,15 +3801,15 @@ class HTML5TreeConstructer { elements. */ $this->a_formatting[] = self::MARKER; - /* An end tag whose tag name is "tr" */ - } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') { + /* An end tag whose tag name is "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') { /* If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. (innerHTML case) */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { // Ignore. - /* Otherwise: */ + /* Otherwise: */ } else { /* Clear the stack back to a table row context. */ $this->clearStackToTableContext($clear); @@ -3053,64 +3821,77 @@ class HTML5TreeConstructer { $this->mode = self::IN_TBODY; } - /* A start tag whose tag name is one of: "caption", "col", "colgroup", - "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */ - } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr'))) { + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { /* Act as if an end tag with the tag name "tr" had been seen, then, if that token wasn't ignored, reprocess the current token. */ - $this->inRow(array( - 'name' => 'tr', - 'type' => HTML5::ENDTAG - )); + $this->inRow( + array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + ) + ); return $this->inCell($token); - /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ - } elseif($token['type'] === HTML5::ENDTAG && - in_array($token['name'], array('tbody', 'tfoot', 'thead'))) { + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead')) + ) { /* If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { // Ignore. - /* Otherwise: */ + /* Otherwise: */ } else { /* Otherwise, act as if an end tag with the tag name "tr" had been seen, then reprocess the current token. */ - $this->inRow(array( - 'name' => 'tr', - 'type' => HTML5::ENDTAG - )); + $this->inRow( + array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + ) + ); return $this->inCell($token); } - /* An end tag whose tag name is one of: "body", "caption", "col", - "colgroup", "html", "td", "th" */ - } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], - array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'))) { + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr') + ) + ) { /* Parse error. Ignore the token. */ - /* Anything else */ + /* Anything else */ } else { /* Process the token as if the insertion mode was "in table". */ $this->inTable($token); } } - private function inCell($token) { + private function inCell($token) + { /* An end tag whose tag name is one of: "td", "th" */ - if($token['type'] === HTML5::ENDTAG && - ($token['name'] === 'td' || $token['name'] === 'th')) { + if ($token['type'] === HTML5::ENDTAG && + ($token['name'] === 'td' || $token['name'] === 'th') + ) { /* If the stack of open elements does not have an element in table scope with the same tag name as that of the token, then this is a parse error and the token must be ignored. */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { // Ignore. - /* Otherwise: */ + /* Otherwise: */ } else { /* Generate implied end tags, except for elements with the same tag name as the token. */ @@ -3122,11 +3903,11 @@ class HTML5TreeConstructer { /* Pop elements from this stack until an element with the same tag name as the token has been popped from the stack. */ - while(true) { + while (true) { $node = end($this->stack)->nodeName; array_pop($this->stack); - if($node === $token['name']) { + if ($node === $token['name']) { break; } } @@ -3140,178 +3921,223 @@ class HTML5TreeConstructer { $this->mode = self::IN_ROW; } - /* A start tag whose tag name is one of: "caption", "col", "colgroup", - "tbody", "td", "tfoot", "th", "thead", "tr" */ - } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', - 'thead', 'tr'))) { + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { /* If the stack of open elements does not have a td or th element in table scope, then this is a parse error; ignore the token. (innerHTML case) */ - if(!$this->elementInScope(array('td', 'th'), true)) { + if (!$this->elementInScope(array('td', 'th'), true)) { // Ignore. - /* Otherwise, close the cell (see below) and reprocess the current - token. */ + /* Otherwise, close the cell (see below) and reprocess the current + token. */ } else { $this->closeCell(); return $this->inRow($token); } - /* A start tag whose tag name is one of: "caption", "col", "colgroup", - "tbody", "td", "tfoot", "th", "thead", "tr" */ - } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'], - array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', - 'thead', 'tr'))) { + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { /* If the stack of open elements does not have a td or th element in table scope, then this is a parse error; ignore the token. (innerHTML case) */ - if(!$this->elementInScope(array('td', 'th'), true)) { + if (!$this->elementInScope(array('td', 'th'), true)) { // Ignore. - /* Otherwise, close the cell (see below) and reprocess the current - token. */ + /* Otherwise, close the cell (see below) and reprocess the current + token. */ } else { $this->closeCell(); return $this->inRow($token); } - /* An end tag whose tag name is one of: "body", "caption", "col", - "colgroup", "html" */ - } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], - array('body', 'caption', 'col', 'colgroup', 'html'))) { + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html') + ) + ) { /* Parse error. Ignore the token. */ - /* An end tag whose tag name is one of: "table", "tbody", "tfoot", - "thead", "tr" */ - } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'], - array('table', 'tbody', 'tfoot', 'thead', 'tr'))) { + /* An end tag whose tag name is one of: "table", "tbody", "tfoot", + "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('table', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { /* If the stack of open elements does not have an element in table scope with the same tag name as that of the token (which can only happen for "tbody", "tfoot" and "thead", or, in the innerHTML case), then this is a parse error and the token must be ignored. */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { // Ignore. - /* Otherwise, close the cell (see below) and reprocess the current - token. */ + /* Otherwise, close the cell (see below) and reprocess the current + token. */ } else { $this->closeCell(); return $this->inRow($token); } - /* Anything else */ + /* Anything else */ } else { /* Process the token as if the insertion mode was "in body". */ $this->inBody($token); } } - private function inSelect($token) { + private function inSelect($token) + { /* Handle the token as follows: */ /* A character token */ - if($token['type'] === HTML5::CHARACTR) { + if ($token['type'] === HTML5::CHARACTR) { /* Append the token's character to the current node. */ $this->insertText($token['data']); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $this->insertComment($token['data']); - /* A start tag token whose tag name is "option" */ - } elseif($token['type'] === HTML5::STARTTAG && - $token['name'] === 'option') { + /* A start tag token whose tag name is "option" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'option' + ) { /* If the current node is an option element, act as if an end tag with the tag name "option" had been seen. */ - if(end($this->stack)->nodeName === 'option') { - $this->inSelect(array( - 'name' => 'option', - 'type' => HTML5::ENDTAG - )); + if (end($this->stack)->nodeName === 'option') { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); } /* Insert an HTML element for the token. */ $this->insertElement($token); - /* A start tag token whose tag name is "optgroup" */ - } elseif($token['type'] === HTML5::STARTTAG && - $token['name'] === 'optgroup') { + /* A start tag token whose tag name is "optgroup" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'optgroup' + ) { /* If the current node is an option element, act as if an end tag with the tag name "option" had been seen. */ - if(end($this->stack)->nodeName === 'option') { - $this->inSelect(array( - 'name' => 'option', - 'type' => HTML5::ENDTAG - )); + if (end($this->stack)->nodeName === 'option') { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); } /* If the current node is an optgroup element, act as if an end tag with the tag name "optgroup" had been seen. */ - if(end($this->stack)->nodeName === 'optgroup') { - $this->inSelect(array( - 'name' => 'optgroup', - 'type' => HTML5::ENDTAG - )); + if (end($this->stack)->nodeName === 'optgroup') { + $this->inSelect( + array( + 'name' => 'optgroup', + 'type' => HTML5::ENDTAG + ) + ); } /* Insert an HTML element for the token. */ $this->insertElement($token); - /* An end tag token whose tag name is "optgroup" */ - } elseif($token['type'] === HTML5::ENDTAG && - $token['name'] === 'optgroup') { + /* An end tag token whose tag name is "optgroup" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'optgroup' + ) { /* First, if the current node is an option element, and the node immediately before it in the stack of open elements is an optgroup element, then act as if an end tag with the tag name "option" had been seen. */ $elements_in_stack = count($this->stack); - if($this->stack[$elements_in_stack - 1]->nodeName === 'option' && - $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup') { - $this->inSelect(array( - 'name' => 'option', - 'type' => HTML5::ENDTAG - )); + if ($this->stack[$elements_in_stack - 1]->nodeName === 'option' && + $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup' + ) { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); } /* If the current node is an optgroup element, then pop that node from the stack of open elements. Otherwise, this is a parse error, ignore the token. */ - if($this->stack[$elements_in_stack - 1] === 'optgroup') { + if ($this->stack[$elements_in_stack - 1] === 'optgroup') { array_pop($this->stack); } - /* An end tag token whose tag name is "option" */ - } elseif($token['type'] === HTML5::ENDTAG && - $token['name'] === 'option') { + /* An end tag token whose tag name is "option" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'option' + ) { /* If the current node is an option element, then pop that node from the stack of open elements. Otherwise, this is a parse error, ignore the token. */ - if(end($this->stack)->nodeName === 'option') { + if (end($this->stack)->nodeName === 'option') { array_pop($this->stack); } - /* An end tag whose tag name is "select" */ - } elseif($token['type'] === HTML5::ENDTAG && - $token['name'] === 'select') { + /* An end tag whose tag name is "select" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'select' + ) { /* If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. (innerHTML case) */ - if(!$this->elementInScope($token['name'], true)) { + if (!$this->elementInScope($token['name'], true)) { // w/e - /* Otherwise: */ + /* Otherwise: */ } else { /* Pop elements from the stack of open elements until a select element has been popped from the stack. */ - while(true) { + while (true) { $current = end($this->stack)->nodeName; array_pop($this->stack); - if($current === 'select') { + if ($current === 'select') { break; } } @@ -3320,20 +4146,35 @@ class HTML5TreeConstructer { $this->resetInsertionMode(); } - /* A start tag whose tag name is "select" */ - } elseif($token['name'] === 'select' && - $token['type'] === HTML5::STARTTAG) { + /* A start tag whose tag name is "select" */ + } elseif ($token['name'] === 'select' && + $token['type'] === HTML5::STARTTAG + ) { /* Parse error. Act as if the token had been an end tag with the tag name "select" instead. */ - $this->inSelect(array( - 'name' => 'select', - 'type' => HTML5::ENDTAG - )); - - /* An end tag whose tag name is one of: "caption", "table", "tbody", - "tfoot", "thead", "tr", "td", "th" */ - } elseif(in_array($token['name'], array('caption', 'table', 'tbody', - 'tfoot', 'thead', 'tr', 'td', 'th')) && $token['type'] === HTML5::ENDTAG) { + $this->inSelect( + array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + ) + ); + + /* An end tag whose tag name is one of: "caption", "table", "tbody", + "tfoot", "thead", "tr", "td", "th" */ + } elseif (in_array( + $token['name'], + array( + 'caption', + 'table', + 'tbody', + 'tfoot', + 'thead', + 'tr', + 'td', + 'th' + ) + ) && $token['type'] === HTML5::ENDTAG + ) { /* Parse error. */ // w/e @@ -3341,43 +4182,47 @@ class HTML5TreeConstructer { the same tag name as that of the token, then act as if an end tag with the tag name "select" had been seen, and reprocess the token. Otherwise, ignore the token. */ - if($this->elementInScope($token['name'], true)) { - $this->inSelect(array( - 'name' => 'select', - 'type' => HTML5::ENDTAG - )); + if ($this->elementInScope($token['name'], true)) { + $this->inSelect( + array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + ) + ); $this->mainPhase($token); } - /* Anything else */ + /* Anything else */ } else { /* Parse error. Ignore the token. */ } } - private function afterBody($token) { + private function afterBody($token) + { /* Handle the token as follows: */ /* A character token that is one of one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), or U+0020 SPACE */ - if($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Process the token as it would be processed if the insertion mode was "in body". */ $this->inBody($token); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the first element in the stack of open elements (the html element), with the data attribute set to the data given in the comment token. */ $comment = $this->dom->createComment($token['data']); $this->stack[0]->appendChild($comment); - /* An end tag with the tag name "html" */ - } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') { + /* An end tag with the tag name "html" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') { /* If the parser was originally created in order to handle the setting of an element's innerHTML attribute, this is a parse error; ignore the token. (The element will be an html element in this @@ -3386,7 +4231,7 @@ class HTML5TreeConstructer { /* Otherwise, switch to the trailing end phase. */ $this->phase = self::END_PHASE; - /* Anything else */ + /* Anything else */ } else { /* Parse error. Set the insertion mode to "in body" and reprocess the token. */ @@ -3395,34 +4240,38 @@ class HTML5TreeConstructer { } } - private function inFrameset($token) { + private function inFrameset($token) + { /* Handle the token as follows: */ /* A character token that is one of one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ - if($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Append the character to the current node. */ $this->insertText($token['data']); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $this->insertComment($token['data']); - /* A start tag with the tag name "frameset" */ - } elseif($token['name'] === 'frameset' && - $token['type'] === HTML5::STARTTAG) { + /* A start tag with the tag name "frameset" */ + } elseif ($token['name'] === 'frameset' && + $token['type'] === HTML5::STARTTAG + ) { $this->insertElement($token); - /* An end tag with the tag name "frameset" */ - } elseif($token['name'] === 'frameset' && - $token['type'] === HTML5::ENDTAG) { + /* An end tag with the tag name "frameset" */ + } elseif ($token['name'] === 'frameset' && + $token['type'] === HTML5::ENDTAG + ) { /* If the current node is the root html element, then this is a parse error; ignore the token. (innerHTML case) */ - if(end($this->stack)->nodeName === 'html') { + if (end($this->stack)->nodeName === 'html') { // Ignore } else { @@ -3437,103 +4286,113 @@ class HTML5TreeConstructer { $this->mode = self::AFTR_FRAME; } - /* A start tag with the tag name "frame" */ - } elseif($token['name'] === 'frame' && - $token['type'] === HTML5::STARTTAG) { + /* A start tag with the tag name "frame" */ + } elseif ($token['name'] === 'frame' && + $token['type'] === HTML5::STARTTAG + ) { /* Insert an HTML element for the token. */ $this->insertElement($token); /* Immediately pop the current node off the stack of open elements. */ array_pop($this->stack); - /* A start tag with the tag name "noframes" */ - } elseif($token['name'] === 'noframes' && - $token['type'] === HTML5::STARTTAG) { + /* A start tag with the tag name "noframes" */ + } elseif ($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG + ) { /* Process the token as if the insertion mode had been "in body". */ $this->inBody($token); - /* Anything else */ + /* Anything else */ } else { /* Parse error. Ignore the token. */ } } - private function afterFrameset($token) { + private function afterFrameset($token) + { /* Handle the token as follows: */ /* A character token that is one of one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ - if($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Append the character to the current node. */ $this->insertText($token['data']); - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the current node with the data attribute set to the data given in the comment token. */ $this->insertComment($token['data']); - /* An end tag with the tag name "html" */ - } elseif($token['name'] === 'html' && - $token['type'] === HTML5::ENDTAG) { + /* An end tag with the tag name "html" */ + } elseif ($token['name'] === 'html' && + $token['type'] === HTML5::ENDTAG + ) { /* Switch to the trailing end phase. */ $this->phase = self::END_PHASE; - /* A start tag with the tag name "noframes" */ - } elseif($token['name'] === 'noframes' && - $token['type'] === HTML5::STARTTAG) { + /* A start tag with the tag name "noframes" */ + } elseif ($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG + ) { /* Process the token as if the insertion mode had been "in body". */ $this->inBody($token); - /* Anything else */ + /* Anything else */ } else { /* Parse error. Ignore the token. */ } } - private function trailingEndPhase($token) { + private function trailingEndPhase($token) + { /* After the main phase, as each token is emitted from the tokenisation stage, it must be processed as described in this section. */ /* A DOCTYPE token */ - if($token['type'] === HTML5::DOCTYPE) { + if ($token['type'] === HTML5::DOCTYPE) { // Parse error. Ignore the token. - /* A comment token */ - } elseif($token['type'] === HTML5::COMMENT) { + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { /* Append a Comment node to the Document object with the data attribute set to the data given in the comment token. */ $comment = $this->dom->createComment($token['data']); $this->dom->appendChild($comment); - /* A character token that is one of one of U+0009 CHARACTER TABULATION, - U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), - or U+0020 SPACE */ - } elseif($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) { + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { /* Process the token as it would be processed in the main phase. */ $this->mainPhase($token); - /* A character token that is not one of U+0009 CHARACTER TABULATION, - U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), - or U+0020 SPACE. Or a start tag token. Or an end tag token. */ - } elseif(($token['type'] === HTML5::CHARACTR && - preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || - $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG) { + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or a start tag token. Or an end tag token. */ + } elseif (($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG + ) { /* Parse error. Switch back to the main phase and reprocess the token. */ $this->phase = self::MAIN_PHASE; return $this->mainPhase($token); - /* An end-of-file token */ - } elseif($token['type'] === HTML5::EOF) { + /* An end-of-file token */ + } elseif ($token['type'] === HTML5::EOF) { /* OMG DONE!! */ } } - private function insertElement($token, $append = true, $check = false) { + private function insertElement($token, $append = true, $check = false) + { // Proprietary workaround for libxml2's limitations with tag names if ($check) { // Slightly modified HTML5 tag-name modification, @@ -3542,13 +4401,15 @@ class HTML5TreeConstructer { // Remove leading hyphens and numbers $token['name'] = ltrim($token['name'], '-0..9'); // In theory, this should ever be needed, but just in case - if ($token['name'] === '') $token['name'] = 'span'; // arbitrary generic choice + if ($token['name'] === '') { + $token['name'] = 'span'; + } // arbitrary generic choice } - + $el = $this->dom->createElement($token['name']); - foreach($token['attr'] as $attr) { - if(!$el->hasAttribute($attr['name'])) { + foreach ($token['attr'] as $attr) { + if (!$el->hasAttribute($attr['name'])) { $el->setAttribute($attr['name'], $attr['value']); } } @@ -3559,48 +4420,54 @@ class HTML5TreeConstructer { return $el; } - private function insertText($data) { + private function insertText($data) + { $text = $this->dom->createTextNode($data); $this->appendToRealParent($text); } - private function insertComment($data) { + private function insertComment($data) + { $comment = $this->dom->createComment($data); $this->appendToRealParent($comment); } - private function appendToRealParent($node) { - if($this->foster_parent === null) { + private function appendToRealParent($node) + { + if ($this->foster_parent === null) { end($this->stack)->appendChild($node); - } elseif($this->foster_parent !== null) { + } elseif ($this->foster_parent !== null) { /* If the foster parent element is the parent element of the last table element in the stack of open elements, then the new node must be inserted immediately before the last table element in the stack of open elements in the foster parent element; otherwise, the new node must be appended to the foster parent element. */ - for($n = count($this->stack) - 1; $n >= 0; $n--) { - if($this->stack[$n]->nodeName === 'table' && - $this->stack[$n]->parentNode !== null) { + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === 'table' && + $this->stack[$n]->parentNode !== null + ) { $table = $this->stack[$n]; break; } } - if(isset($table) && $this->foster_parent->isSameNode($table->parentNode)) + if (isset($table) && $this->foster_parent->isSameNode($table->parentNode)) { $this->foster_parent->insertBefore($node, $table); - else + } else { $this->foster_parent->appendChild($node); + } $this->foster_parent = null; } } - private function elementInScope($el, $table = false) { - if(is_array($el)) { - foreach($el as $element) { - if($this->elementInScope($element, $table)) { + private function elementInScope($el, $table = false) + { + if (is_array($el)) { + foreach ($el as $element) { + if ($this->elementInScope($element, $table)) { return true; } } @@ -3610,28 +4477,38 @@ class HTML5TreeConstructer { $leng = count($this->stack); - for($n = 0; $n < $leng; $n++) { + for ($n = 0; $n < $leng; $n++) { /* 1. Initialise node to be the current node (the bottommost node of the stack). */ $node = $this->stack[$leng - 1 - $n]; - if($node->tagName === $el) { + if ($node->tagName === $el) { /* 2. If node is the target node, terminate in a match state. */ return true; - } elseif($node->tagName === 'table') { + } elseif ($node->tagName === 'table') { /* 3. Otherwise, if node is a table element, terminate in a failure state. */ return false; - } elseif($table === true && in_array($node->tagName, array('caption', 'td', - 'th', 'button', 'marquee', 'object'))) { + } elseif ($table === true && in_array( + $node->tagName, + array( + 'caption', + 'td', + 'th', + 'button', + 'marquee', + 'object' + ) + ) + ) { /* 4. Otherwise, if the algorithm is the "has an element in scope" variant (rather than the "has an element in table scope" variant), and node is one of the following, terminate in a failure state. */ return false; - } elseif($node === $node->ownerDocument->documentElement) { + } elseif ($node === $node->ownerDocument->documentElement) { /* 5. Otherwise, if node is an html element (root element), terminate in a failure state. (This can only happen if the node is the topmost node of the stack of open elements, and prevents the next step from @@ -3646,12 +4523,13 @@ class HTML5TreeConstructer { } } - private function reconstructActiveFormattingElements() { + private function reconstructActiveFormattingElements() + { /* 1. If there are no entries in the list of active formatting elements, then there is nothing to reconstruct; stop this algorithm. */ $formatting_elements = count($this->a_formatting); - if($formatting_elements === 0) { + if ($formatting_elements === 0) { return false; } @@ -3663,14 +4541,14 @@ class HTML5TreeConstructer { formatting elements is a marker, or if it is an element that is in the stack of open elements, then there is nothing to reconstruct; stop this algorithm. */ - if($entry === self::MARKER || in_array($entry, $this->stack, true)) { + if ($entry === self::MARKER || in_array($entry, $this->stack, true)) { return false; } - for($a = $formatting_elements - 1; $a >= 0; true) { + for ($a = $formatting_elements - 1; $a >= 0; true) { /* 4. If there are no entries before entry in the list of active formatting elements, then jump to step 8. */ - if($a === 0) { + if ($a === 0) { $step_seven = false; break; } @@ -3682,15 +4560,15 @@ class HTML5TreeConstructer { /* 6. If entry is neither a marker nor an element that is also in thetack of open elements, go to step 4. */ - if($entry === self::MARKER || in_array($entry, $this->stack, true)) { + if ($entry === self::MARKER || in_array($entry, $this->stack, true)) { break; } } - while(true) { + while (true) { /* 7. Let entry be the element one later than entry in the list of active formatting elements. */ - if(isset($step_seven) && $step_seven === true) { + if (isset($step_seven) && $step_seven === true) { $a++; $entry = $this->a_formatting[$a]; } @@ -3709,7 +4587,7 @@ class HTML5TreeConstructer { /* 11. If the entry for clone in the list of active formatting elements is not the last entry in the list, return to step 7. */ - if(end($this->a_formatting) !== $clone) { + if (end($this->a_formatting) !== $clone) { $step_seven = true; } else { break; @@ -3717,12 +4595,13 @@ class HTML5TreeConstructer { } } - private function clearTheActiveFormattingElementsUpToTheLastMarker() { + private function clearTheActiveFormattingElementsUpToTheLastMarker() + { /* When the steps below require the UA to clear the list of active formatting elements up to the last marker, the UA must perform the following steps: */ - while(true) { + while (true) { /* 1. Let entry be the last (most recently added) entry in the list of active formatting elements. */ $entry = end($this->a_formatting); @@ -3732,13 +4611,14 @@ class HTML5TreeConstructer { /* 3. If entry was a marker, then stop the algorithm at this point. The list has been cleared up to the last marker. */ - if($entry === self::MARKER) { + if ($entry === self::MARKER) { break; } } } - private function generateImpliedEndTags($exclude = array()) { + private function generateImpliedEndTags($exclude = array()) + { /* When the steps below require the UA to generate implied end tags, then, if the current node is a dd element, a dt element, an li element, a p element, a td element, a th element, or a tr element, the UA must @@ -3747,36 +4627,36 @@ class HTML5TreeConstructer { $node = end($this->stack); $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude); - while(in_array(end($this->stack)->nodeName, $elements)) { + while (in_array(end($this->stack)->nodeName, $elements)) { array_pop($this->stack); } } - private function getElementCategory($node) { + private function getElementCategory($node) + { $name = $node->tagName; - if(in_array($name, $this->special)) + if (in_array($name, $this->special)) { return self::SPECIAL; - - elseif(in_array($name, $this->scoping)) + } elseif (in_array($name, $this->scoping)) { return self::SCOPING; - - elseif(in_array($name, $this->formatting)) + } elseif (in_array($name, $this->formatting)) { return self::FORMATTING; - - else + } else { return self::PHRASING; + } } - private function clearStackToTableContext($elements) { + private function clearStackToTableContext($elements) + { /* When the steps above require the UA to clear the stack back to a table context, it means that the UA must, while the current node is not a table element or an html element, pop elements from the stack of open elements. If this causes any elements to be popped from the stack, then this is a parse error. */ - while(true) { + while (true) { $node = end($this->stack)->nodeName; - if(in_array($node, $elements)) { + if (in_array($node, $elements)) { break; } else { array_pop($this->stack); @@ -3784,12 +4664,13 @@ class HTML5TreeConstructer { } } - private function resetInsertionMode() { + private function resetInsertionMode() + { /* 1. Let last be false. */ $last = false; $leng = count($this->stack); - for($n = $leng - 1; $n >= 0; $n--) { + for ($n = $leng - 1; $n >= 0; $n--) { /* 2. Let node be the last node in the stack of open elements. */ $node = $this->stack[$n]; @@ -3797,108 +4678,111 @@ class HTML5TreeConstructer { set last to true. If the element whose innerHTML attribute is being set is neither a td element nor a th element, then set node to the element whose innerHTML attribute is being set. (innerHTML case) */ - if($this->stack[0]->isSameNode($node)) { + if ($this->stack[0]->isSameNode($node)) { $last = true; } /* 4. If node is a select element, then switch the insertion mode to "in select" and abort these steps. (innerHTML case) */ - if($node->nodeName === 'select') { + if ($node->nodeName === 'select') { $this->mode = self::IN_SELECT; break; - /* 5. If node is a td or th element, then switch the insertion mode - to "in cell" and abort these steps. */ - } elseif($node->nodeName === 'td' || $node->nodeName === 'th') { + /* 5. If node is a td or th element, then switch the insertion mode + to "in cell" and abort these steps. */ + } elseif ($node->nodeName === 'td' || $node->nodeName === 'th') { $this->mode = self::IN_CELL; break; - /* 6. If node is a tr element, then switch the insertion mode to - "in row" and abort these steps. */ - } elseif($node->nodeName === 'tr') { + /* 6. If node is a tr element, then switch the insertion mode to + "in row" and abort these steps. */ + } elseif ($node->nodeName === 'tr') { $this->mode = self::IN_ROW; break; - /* 7. If node is a tbody, thead, or tfoot element, then switch the - insertion mode to "in table body" and abort these steps. */ - } elseif(in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) { + /* 7. If node is a tbody, thead, or tfoot element, then switch the + insertion mode to "in table body" and abort these steps. */ + } elseif (in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) { $this->mode = self::IN_TBODY; break; - /* 8. If node is a caption element, then switch the insertion mode - to "in caption" and abort these steps. */ - } elseif($node->nodeName === 'caption') { + /* 8. If node is a caption element, then switch the insertion mode + to "in caption" and abort these steps. */ + } elseif ($node->nodeName === 'caption') { $this->mode = self::IN_CAPTION; break; - /* 9. If node is a colgroup element, then switch the insertion mode - to "in column group" and abort these steps. (innerHTML case) */ - } elseif($node->nodeName === 'colgroup') { + /* 9. If node is a colgroup element, then switch the insertion mode + to "in column group" and abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'colgroup') { $this->mode = self::IN_CGROUP; break; - /* 10. If node is a table element, then switch the insertion mode - to "in table" and abort these steps. */ - } elseif($node->nodeName === 'table') { + /* 10. If node is a table element, then switch the insertion mode + to "in table" and abort these steps. */ + } elseif ($node->nodeName === 'table') { $this->mode = self::IN_TABLE; break; - /* 11. If node is a head element, then switch the insertion mode - to "in body" ("in body"! not "in head"!) and abort these steps. - (innerHTML case) */ - } elseif($node->nodeName === 'head') { + /* 11. If node is a head element, then switch the insertion mode + to "in body" ("in body"! not "in head"!) and abort these steps. + (innerHTML case) */ + } elseif ($node->nodeName === 'head') { $this->mode = self::IN_BODY; break; - /* 12. If node is a body element, then switch the insertion mode to - "in body" and abort these steps. */ - } elseif($node->nodeName === 'body') { + /* 12. If node is a body element, then switch the insertion mode to + "in body" and abort these steps. */ + } elseif ($node->nodeName === 'body') { $this->mode = self::IN_BODY; break; - /* 13. If node is a frameset element, then switch the insertion - mode to "in frameset" and abort these steps. (innerHTML case) */ - } elseif($node->nodeName === 'frameset') { + /* 13. If node is a frameset element, then switch the insertion + mode to "in frameset" and abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'frameset') { $this->mode = self::IN_FRAME; break; - /* 14. If node is an html element, then: if the head element - pointer is null, switch the insertion mode to "before head", - otherwise, switch the insertion mode to "after head". In either - case, abort these steps. (innerHTML case) */ - } elseif($node->nodeName === 'html') { + /* 14. If node is an html element, then: if the head element + pointer is null, switch the insertion mode to "before head", + otherwise, switch the insertion mode to "after head". In either + case, abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'html') { $this->mode = ($this->head_pointer === null) ? self::BEFOR_HEAD : self::AFTER_HEAD; break; - /* 15. If last is true, then set the insertion mode to "in body" - and abort these steps. (innerHTML case) */ - } elseif($last) { + /* 15. If last is true, then set the insertion mode to "in body" + and abort these steps. (innerHTML case) */ + } elseif ($last) { $this->mode = self::IN_BODY; break; } } } - private function closeCell() { + private function closeCell() + { /* If the stack of open elements has a td or th element in table scope, then act as if an end tag token with that tag name had been seen. */ - foreach(array('td', 'th') as $cell) { - if($this->elementInScope($cell, true)) { - $this->inCell(array( - 'name' => $cell, - 'type' => HTML5::ENDTAG - )); + foreach (array('td', 'th') as $cell) { + if ($this->elementInScope($cell, true)) { + $this->inCell( + array( + 'name' => $cell, + 'type' => HTML5::ENDTAG + ) + ); break; } } } - public function save() { + public function save() + { return $this->dom; } } -?> diff --git a/library/HTMLPurifier/PercentEncoder.php b/library/HTMLPurifier/PercentEncoder.php index a43c44f4..18c8bbb0 100644 --- a/library/HTMLPurifier/PercentEncoder.php +++ b/library/HTMLPurifier/PercentEncoder.php @@ -13,17 +13,26 @@ class HTMLPurifier_PercentEncoder /** * Reserved characters to preserve when using encode(). + * @type array */ protected $preserve = array(); /** * String of characters that should be preserved while using encode(). + * @param bool $preserve */ - public function __construct($preserve = false) { + public function __construct($preserve = false) + { // unreserved letters, ought to const-ify - for ($i = 48; $i <= 57; $i++) $this->preserve[$i] = true; // digits - for ($i = 65; $i <= 90; $i++) $this->preserve[$i] = true; // upper-case - for ($i = 97; $i <= 122; $i++) $this->preserve[$i] = true; // lower-case + for ($i = 48; $i <= 57; $i++) { // digits + $this->preserve[$i] = true; + } + for ($i = 65; $i <= 90; $i++) { // upper-case + $this->preserve[$i] = true; + } + for ($i = 97; $i <= 122; $i++) { // lower-case + $this->preserve[$i] = true; + } $this->preserve[45] = true; // Dash - $this->preserve[46] = true; // Period . $this->preserve[95] = true; // Underscore _ @@ -44,13 +53,14 @@ class HTMLPurifier_PercentEncoder * Assumes that the string has already been normalized, making any * and all percent escape sequences valid. Percents will not be * re-escaped, regardless of their status in $preserve - * @param $string String to be encoded - * @return Encoded string. + * @param string $string String to be encoded + * @return string Encoded string. */ - public function encode($string) { + public function encode($string) + { $ret = ''; for ($i = 0, $c = strlen($string); $i < $c; $i++) { - if ($string[$i] !== '%' && !isset($this->preserve[$int = ord($string[$i])]) ) { + if ($string[$i] !== '%' && !isset($this->preserve[$int = ord($string[$i])])) { $ret .= '%' . sprintf('%02X', $int); } else { $ret .= $string[$i]; @@ -64,10 +74,14 @@ class HTMLPurifier_PercentEncoder * @warning This function is affected by $preserve, even though the * usual desired behavior is for this not to preserve those * characters. Be careful when reusing instances of PercentEncoder! - * @param $string String to normalize + * @param string $string String to normalize + * @return string */ - public function normalize($string) { - if ($string == '') return ''; + public function normalize($string) + { + if ($string == '') { + return ''; + } $parts = explode('%', $string); $ret = array_shift($parts); foreach ($parts as $part) { @@ -92,7 +106,6 @@ class HTMLPurifier_PercentEncoder } return $ret; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Printer.php b/library/HTMLPurifier/Printer.php index e7eb82e8..549e4cea 100644 --- a/library/HTMLPurifier/Printer.php +++ b/library/HTMLPurifier/Printer.php @@ -7,25 +7,30 @@ class HTMLPurifier_Printer { /** - * Instance of HTMLPurifier_Generator for HTML generation convenience funcs + * For HTML generation convenience funcs. + * @type HTMLPurifier_Generator */ protected $generator; /** - * Instance of HTMLPurifier_Config, for easy access + * For easy access. + * @type HTMLPurifier_Config */ protected $config; /** * Initialize $generator. */ - public function __construct() { + public function __construct() + { } /** * Give generator necessary configuration if possible + * @param HTMLPurifier_Config $config */ - public function prepareGenerator($config) { + public function prepareGenerator($config) + { $all = $config->getAll(); $context = new HTMLPurifier_Context(); $this->generator = new HTMLPurifier_Generator($config, $context); @@ -39,45 +44,62 @@ class HTMLPurifier_Printer /** * Returns a start tag - * @param $tag Tag name - * @param $attr Attribute array + * @param string $tag Tag name + * @param array $attr Attribute array + * @return string */ - protected function start($tag, $attr = array()) { + protected function start($tag, $attr = array()) + { return $this->generator->generateFromToken( - new HTMLPurifier_Token_Start($tag, $attr ? $attr : array()) - ); + new HTMLPurifier_Token_Start($tag, $attr ? $attr : array()) + ); } /** - * Returns an end teg - * @param $tag Tag name + * Returns an end tag + * @param string $tag Tag name + * @return string */ - protected function end($tag) { + protected function end($tag) + { return $this->generator->generateFromToken( - new HTMLPurifier_Token_End($tag) - ); + new HTMLPurifier_Token_End($tag) + ); } /** * Prints a complete element with content inside - * @param $tag Tag name - * @param $contents Element contents - * @param $attr Tag attributes - * @param $escape Bool whether or not to escape contents + * @param string $tag Tag name + * @param string $contents Element contents + * @param array $attr Tag attributes + * @param bool $escape whether or not to escape contents + * @return string */ - protected function element($tag, $contents, $attr = array(), $escape = true) { + protected function element($tag, $contents, $attr = array(), $escape = true) + { return $this->start($tag, $attr) . - ($escape ? $this->escape($contents) : $contents) . - $this->end($tag); + ($escape ? $this->escape($contents) : $contents) . + $this->end($tag); } - protected function elementEmpty($tag, $attr = array()) { + /** + * @param string $tag + * @param array $attr + * @return string + */ + protected function elementEmpty($tag, $attr = array()) + { return $this->generator->generateFromToken( new HTMLPurifier_Token_Empty($tag, $attr) ); } - protected function text($text) { + /** + * @param string $text + * @return string + */ + protected function text($text) + { return $this->generator->generateFromToken( new HTMLPurifier_Token_Text($text) ); @@ -85,24 +107,29 @@ class HTMLPurifier_Printer /** * Prints a simple key/value row in a table. - * @param $name Key - * @param $value Value + * @param string $name Key + * @param mixed $value Value + * @return string */ - protected function row($name, $value) { - if (is_bool($value)) $value = $value ? 'On' : 'Off'; + protected function row($name, $value) + { + if (is_bool($value)) { + $value = $value ? 'On' : 'Off'; + } return $this->start('tr') . "\n" . - $this->element('th', $name) . "\n" . - $this->element('td', $value) . "\n" . - $this->end('tr') - ; + $this->element('th', $name) . "\n" . + $this->element('td', $value) . "\n" . + $this->end('tr'); } /** * Escapes a string for HTML output. - * @param $string String to escape + * @param string $string String to escape + * @return string */ - protected function escape($string) { + protected function escape($string) + { $string = HTMLPurifier_Encoder::cleanUTF8($string); $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8'); return $string; @@ -110,32 +137,46 @@ class HTMLPurifier_Printer /** * Takes a list of strings and turns them into a single list - * @param $array List of strings - * @param $polite Bool whether or not to add an end before the last + * @param string[] $array List of strings + * @param bool $polite Bool whether or not to add an end before the last + * @return string */ - protected function listify($array, $polite = false) { - if (empty($array)) return 'None'; + protected function listify($array, $polite = false) + { + if (empty($array)) { + return 'None'; + } $ret = ''; $i = count($array); foreach ($array as $value) { $i--; $ret .= $value; - if ($i > 0 && !($polite && $i == 1)) $ret .= ', '; - if ($polite && $i == 1) $ret .= 'and '; + if ($i > 0 && !($polite && $i == 1)) { + $ret .= ', '; + } + if ($polite && $i == 1) { + $ret .= 'and '; + } } return $ret; } /** * Retrieves the class of an object without prefixes, as well as metadata - * @param $obj Object to determine class of - * @param $prefix Further prefix to remove + * @param object $obj Object to determine class of + * @param string $sec_prefix Further prefix to remove + * @return string */ - protected function getClass($obj, $sec_prefix = '') { + protected function getClass($obj, $sec_prefix = '') + { static $five = null; - if ($five === null) $five = version_compare(PHP_VERSION, '5', '>='); + if ($five === null) { + $five = version_compare(PHP_VERSION, '5', '>='); + } $prefix = 'HTMLPurifier_' . $sec_prefix; - if (!$five) $prefix = strtolower($prefix); + if (!$five) { + $prefix = strtolower($prefix); + } $class = str_replace($prefix, '', get_class($obj)); $lclass = strtolower($class); $class .= '('; @@ -164,13 +205,14 @@ class HTMLPurifier_Printer break; case 'css_importantdecorator': $class .= $this->getClass($obj->def, $sec_prefix); - if ($obj->allow) $class .= ', !important'; + if ($obj->allow) { + $class .= ', !important'; + } break; } $class .= ')'; return $class; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Printer/CSSDefinition.php b/library/HTMLPurifier/Printer/CSSDefinition.php index 81f98659..29505fe1 100644 --- a/library/HTMLPurifier/Printer/CSSDefinition.php +++ b/library/HTMLPurifier/Printer/CSSDefinition.php @@ -2,10 +2,17 @@ class HTMLPurifier_Printer_CSSDefinition extends HTMLPurifier_Printer { - + /** + * @type HTMLPurifier_CSSDefinition + */ protected $def; - public function render($config) { + /** + * @param HTMLPurifier_Config $config + * @return string + */ + public function render($config) + { $this->def = $config->getCSSDefinition(); $ret = ''; @@ -32,7 +39,6 @@ class HTMLPurifier_Printer_CSSDefinition extends HTMLPurifier_Printer return $ret; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Printer/ConfigForm.php b/library/HTMLPurifier/Printer/ConfigForm.php index 02aa6568..36100ce7 100644 --- a/library/HTMLPurifier/Printer/ConfigForm.php +++ b/library/HTMLPurifier/Printer/ConfigForm.php @@ -7,17 +7,20 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer { /** - * Printers for specific fields + * Printers for specific fields. + * @type HTMLPurifier_Printer[] */ protected $fields = array(); /** - * Documentation URL, can have fragment tagged on end + * Documentation URL, can have fragment tagged on end. + * @type string */ protected $docURL; /** - * Name of form element to stuff config in + * Name of form element to stuff config in. + * @type string */ protected $name; @@ -25,24 +28,27 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer * Whether or not to compress directive names, clipping them off * after a certain amount of letters. False to disable or integer letters * before clipping. + * @type bool */ protected $compress = false; /** - * @param $name Form element name for directives to be stuffed into - * @param $doc_url String documentation URL, will have fragment tagged on - * @param $compress Integer max length before compressing a directive name, set to false to turn off + * @param string $name Form element name for directives to be stuffed into + * @param string $doc_url String documentation URL, will have fragment tagged on + * @param bool $compress Integer max length before compressing a directive name, set to false to turn off */ public function __construct( - $name, $doc_url = null, $compress = false + $name, + $doc_url = null, + $compress = false ) { parent::__construct(); $this->docURL = $doc_url; - $this->name = $name; + $this->name = $name; $this->compress = $compress; // initialize sub-printers - $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default(); - $this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool(); + $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default(); + $this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool(); } /** @@ -50,32 +56,42 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer * @param $cols Integer columns of textarea, null to use default * @param $rows Integer rows of textarea, null to use default */ - public function setTextareaDimensions($cols = null, $rows = null) { - if ($cols) $this->fields['default']->cols = $cols; - if ($rows) $this->fields['default']->rows = $rows; + public function setTextareaDimensions($cols = null, $rows = null) + { + if ($cols) { + $this->fields['default']->cols = $cols; + } + if ($rows) { + $this->fields['default']->rows = $rows; + } } /** * Retrieves styling, in case it is not accessible by webserver */ - public static function getCSS() { + public static function getCSS() + { return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css'); } /** * Retrieves JavaScript, in case it is not accessible by webserver */ - public static function getJavaScript() { + public static function getJavaScript() + { return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js'); } /** * Returns HTML output for a configuration form - * @param $config Configuration object of current form state, or an array + * @param HTMLPurifier_Config|array $config Configuration object of current form state, or an array * where [0] has an HTML namespace and [1] is being rendered. - * @param $allowed Optional namespace(s) and directives to restrict form to. + * @param array|bool $allowed Optional namespace(s) and directives to restrict form to. + * @param bool $render_controls + * @return string */ - public function render($config, $allowed = true, $render_controls = true) { + public function render($config, $allowed = true, $render_controls = true) + { if (is_array($config) && isset($config[0])) { $gen_config = $config[0]; $config = $config[1]; @@ -91,29 +107,29 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer $all = array(); foreach ($allowed as $key) { list($ns, $directive) = $key; - $all[$ns][$directive] = $config->get($ns .'.'. $directive); + $all[$ns][$directive] = $config->get($ns . '.' . $directive); } $ret = ''; $ret .= $this->start('table', array('class' => 'hp-config')); $ret .= $this->start('thead'); $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive')); - $ret .= $this->element('th', 'Value', array('class' => 'hp-value')); + $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive')); + $ret .= $this->element('th', 'Value', array('class' => 'hp-value')); $ret .= $this->end('tr'); $ret .= $this->end('thead'); foreach ($all as $ns => $directives) { $ret .= $this->renderNamespace($ns, $directives); } if ($render_controls) { - $ret .= $this->start('tbody'); - $ret .= $this->start('tr'); - $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls')); - $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit')); - $ret .= '[Reset]'; - $ret .= $this->end('td'); - $ret .= $this->end('tr'); - $ret .= $this->end('tbody'); + $ret .= $this->start('tbody'); + $ret .= $this->start('tr'); + $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls')); + $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit')); + $ret .= '[Reset]'; + $ret .= $this->end('td'); + $ret .= $this->end('tr'); + $ret .= $this->end('tbody'); } $ret .= $this->end('table'); return $ret; @@ -122,13 +138,15 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer /** * Renders a single namespace * @param $ns String namespace name - * @param $directive Associative array of directives to values + * @param array $directives array of directives to values + * @return string */ - protected function renderNamespace($ns, $directives) { + protected function renderNamespace($ns, $directives) + { $ret = ''; $ret .= $this->start('tbody', array('class' => 'namespace')); $ret .= $this->start('tr'); - $ret .= $this->element('th', $ns, array('colspan' => 2)); + $ret .= $this->element('th', $ns, array('colspan' => 2)); $ret .= $this->end('tr'); $ret .= $this->end('tbody'); $ret .= $this->start('tbody'); @@ -139,40 +157,44 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer $url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL); $ret .= $this->start('a', array('href' => $url)); } - $attr = array('for' => "{$this->name}:$ns.$directive"); - - // crop directive name if it's too long - if (!$this->compress || (strlen($directive) < $this->compress)) { - $directive_disp = $directive; - } else { - $directive_disp = substr($directive, 0, $this->compress - 2) . '...'; - $attr['title'] = $directive; - } + $attr = array('for' => "{$this->name}:$ns.$directive"); + + // crop directive name if it's too long + if (!$this->compress || (strlen($directive) < $this->compress)) { + $directive_disp = $directive; + } else { + $directive_disp = substr($directive, 0, $this->compress - 2) . '...'; + $attr['title'] = $directive; + } - $ret .= $this->element( - 'label', - $directive_disp, - // component printers must create an element with this id - $attr - ); - if ($this->docURL) $ret .= $this->end('a'); + $ret .= $this->element( + 'label', + $directive_disp, + // component printers must create an element with this id + $attr + ); + if ($this->docURL) { + $ret .= $this->end('a'); + } $ret .= $this->end('th'); $ret .= $this->start('td'); - $def = $this->config->def->info["$ns.$directive"]; - if (is_int($def)) { - $allow_null = $def < 0; - $type = abs($def); - } else { - $type = $def->type; - $allow_null = isset($def->allow_null); - } - if (!isset($this->fields[$type])) $type = 0; // default - $type_obj = $this->fields[$type]; - if ($allow_null) { - $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj); - } - $ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config)); + $def = $this->config->def->info["$ns.$directive"]; + if (is_int($def)) { + $allow_null = $def < 0; + $type = abs($def); + } else { + $type = $def->type; + $allow_null = isset($def->allow_null); + } + if (!isset($this->fields[$type])) { + $type = 0; + } // default + $type_obj = $this->fields[$type]; + if ($allow_null) { + $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj); + } + $ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config)); $ret .= $this->end('td'); $ret .= $this->end('tr'); } @@ -185,19 +207,33 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer /** * Printer decorator for directives that accept null */ -class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer { +class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer +{ /** * Printer being decorated + * @type HTMLPurifier_Printer */ protected $obj; + /** - * @param $obj Printer to decorate + * @param HTMLPurifier_Printer $obj Printer to decorate */ - public function __construct($obj) { + public function __construct($obj) + { parent::__construct(); $this->obj = $obj; } - public function render($ns, $directive, $value, $name, $config) { + + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { if (is_array($config) && isset($config[0])) { $gen_config = $config[0]; $config = $config[1]; @@ -215,15 +251,19 @@ class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer 'type' => 'checkbox', 'value' => '1', 'class' => 'null-toggle', - 'name' => "$name"."[Null_$ns.$directive]", + 'name' => "$name" . "[Null_$ns.$directive]", 'id' => "$name:Null_$ns.$directive", 'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!! ); if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) { // modify inline javascript slightly - $attr['onclick'] = "toggleWriteability('$name:Yes_$ns.$directive',checked);toggleWriteability('$name:No_$ns.$directive',checked)"; + $attr['onclick'] = + "toggleWriteability('$name:Yes_$ns.$directive',checked);" . + "toggleWriteability('$name:No_$ns.$directive',checked)"; + } + if ($value === null) { + $attr['checked'] = 'checked'; } - if ($value === null) $attr['checked'] = 'checked'; $ret .= $this->elementEmpty('input', $attr); $ret .= $this->text(' or '); $ret .= $this->elementEmpty('br'); @@ -235,10 +275,28 @@ class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer /** * Swiss-army knife configuration form field printer */ -class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer { +class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer +{ + /** + * @type int + */ public $cols = 18; + + /** + * @type int + */ public $rows = 5; - public function render($ns, $directive, $value, $name, $config) { + + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { if (is_array($config) && isset($config[0])) { $gen_config = $config[0]; $config = $config[1]; @@ -262,6 +320,7 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer { foreach ($array as $val => $b) { $value[] = $val; } + //TODO does this need a break? case HTMLPurifier_VarParser::ALIST: $value = implode(PHP_EOL, $value); break; @@ -281,25 +340,27 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer { $value = serialize($value); } $attr = array( - 'name' => "$name"."[$ns.$directive]", + 'name' => "$name" . "[$ns.$directive]", 'id' => "$name:$ns.$directive" ); - if ($value === null) $attr['disabled'] = 'disabled'; + if ($value === null) { + $attr['disabled'] = 'disabled'; + } if (isset($def->allowed)) { $ret .= $this->start('select', $attr); foreach ($def->allowed as $val => $b) { $attr = array(); - if ($value == $val) $attr['selected'] = 'selected'; + if ($value == $val) { + $attr['selected'] = 'selected'; + } $ret .= $this->element('option', $val, $attr); } $ret .= $this->end('select'); - } elseif ( - $type === HTMLPurifier_VarParser::TEXT || - $type === HTMLPurifier_VarParser::ITEXT || - $type === HTMLPurifier_VarParser::ALIST || - $type === HTMLPurifier_VarParser::HASH || - $type === HTMLPurifier_VarParser::LOOKUP - ) { + } elseif ($type === HTMLPurifier_VarParser::TEXT || + $type === HTMLPurifier_VarParser::ITEXT || + $type === HTMLPurifier_VarParser::ALIST || + $type === HTMLPurifier_VarParser::HASH || + $type === HTMLPurifier_VarParser::LOOKUP) { $attr['cols'] = $this->cols; $attr['rows'] = $this->rows; $ret .= $this->start('textarea', $attr); @@ -317,8 +378,18 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer { /** * Bool form field printer */ -class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer { - public function render($ns, $directive, $value, $name, $config) { +class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer +{ + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { if (is_array($config) && isset($config[0])) { $gen_config = $config[0]; $config = $config[1]; @@ -336,12 +407,16 @@ class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer { $attr = array( 'type' => 'radio', - 'name' => "$name"."[$ns.$directive]", + 'name' => "$name" . "[$ns.$directive]", 'id' => "$name:Yes_$ns.$directive", 'value' => '1' ); - if ($value === true) $attr['checked'] = 'checked'; - if ($value === null) $attr['disabled'] = 'disabled'; + if ($value === true) { + $attr['checked'] = 'checked'; + } + if ($value === null) { + $attr['disabled'] = 'disabled'; + } $ret .= $this->elementEmpty('input', $attr); $ret .= $this->start('label', array('for' => "$name:No_$ns.$directive")); @@ -351,12 +426,16 @@ class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer { $attr = array( 'type' => 'radio', - 'name' => "$name"."[$ns.$directive]", + 'name' => "$name" . "[$ns.$directive]", 'id' => "$name:No_$ns.$directive", 'value' => '0' ); - if ($value === false) $attr['checked'] = 'checked'; - if ($value === null) $attr['disabled'] = 'disabled'; + if ($value === false) { + $attr['checked'] = 'checked'; + } + if ($value === null) { + $attr['disabled'] = 'disabled'; + } $ret .= $this->elementEmpty('input', $attr); $ret .= $this->end('div'); diff --git a/library/HTMLPurifier/Printer/HTMLDefinition.php b/library/HTMLPurifier/Printer/HTMLDefinition.php index 8a8f126b..5f2f2f8a 100644 --- a/library/HTMLPurifier/Printer/HTMLDefinition.php +++ b/library/HTMLPurifier/Printer/HTMLDefinition.php @@ -4,11 +4,16 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer { /** - * Instance of HTMLPurifier_HTMLDefinition, for easy access + * @type HTMLPurifier_HTMLDefinition, for easy access */ protected $def; - public function render($config) { + /** + * @param HTMLPurifier_Config $config + * @return string + */ + public function render($config) + { $ret = ''; $this->config =& $config; @@ -28,8 +33,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Renders the Doctype table + * @return string */ - protected function renderDoctype() { + protected function renderDoctype() + { $doctype = $this->def->doctype; $ret = ''; $ret .= $this->start('table'); @@ -45,8 +52,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Renders environment table, which is miscellaneous info + * @return string */ - protected function renderEnvironment() { + protected function renderEnvironment() + { $def = $this->def; $ret = ''; @@ -59,28 +68,28 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer $ret .= $this->row('Block wrap name', $def->info_block_wrapper); $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Global attributes'); - $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr),0,0); + $ret .= $this->element('th', 'Global attributes'); + $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr), null, 0); $ret .= $this->end('tr'); $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Tag transforms'); - $list = array(); - foreach ($def->info_tag_transform as $old => $new) { - $new = $this->getClass($new, 'TagTransform_'); - $list[] = "<$old> with $new"; - } - $ret .= $this->element('td', $this->listify($list)); + $ret .= $this->element('th', 'Tag transforms'); + $list = array(); + foreach ($def->info_tag_transform as $old => $new) { + $new = $this->getClass($new, 'TagTransform_'); + $list[] = "<$old> with $new"; + } + $ret .= $this->element('td', $this->listify($list)); $ret .= $this->end('tr'); $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Pre-AttrTransform'); - $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre)); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre)); $ret .= $this->end('tr'); $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Post-AttrTransform'); - $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post)); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post)); $ret .= $this->end('tr'); $ret .= $this->end('table'); @@ -89,8 +98,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Renders the Content Sets table + * @return string */ - protected function renderContentSets() { + protected function renderContentSets() + { $ret = ''; $ret .= $this->start('table'); $ret .= $this->element('caption', 'Content Sets'); @@ -106,8 +117,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Renders the Elements ($info) table + * @return string */ - protected function renderInfo() { + protected function renderInfo() + { $ret = ''; $ret .= $this->start('table'); $ret .= $this->element('caption', 'Elements ($info)'); @@ -118,39 +131,39 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer $ret .= $this->end('tr'); foreach ($this->def->info as $name => $def) { $ret .= $this->start('tr'); - $ret .= $this->element('th', "<$name>", array('class'=>'heavy', 'colspan' => 2)); + $ret .= $this->element('th', "<$name>", array('class' => 'heavy', 'colspan' => 2)); $ret .= $this->end('tr'); $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Inline content'); - $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No'); + $ret .= $this->element('th', 'Inline content'); + $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No'); $ret .= $this->end('tr'); if (!empty($def->excludes)) { $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Excludes'); - $ret .= $this->element('td', $this->listifyTagLookup($def->excludes)); + $ret .= $this->element('th', 'Excludes'); + $ret .= $this->element('td', $this->listifyTagLookup($def->excludes)); $ret .= $this->end('tr'); } if (!empty($def->attr_transform_pre)) { $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Pre-AttrTransform'); - $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre)); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre)); $ret .= $this->end('tr'); } if (!empty($def->attr_transform_post)) { $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Post-AttrTransform'); - $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post)); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post)); $ret .= $this->end('tr'); } if (!empty($def->auto_close)) { $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Auto closed by'); - $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close)); + $ret .= $this->element('th', 'Auto closed by'); + $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close)); $ret .= $this->end('tr'); } $ret .= $this->start('tr'); - $ret .= $this->element('th', 'Allowed attributes'); - $ret .= $this->element('td',$this->listifyAttr($def->attr), array(), 0); + $ret .= $this->element('th', 'Allowed attributes'); + $ret .= $this->element('td', $this->listifyAttr($def->attr), array(), 0); $ret .= $this->end('tr'); if (!empty($def->required_attr)) { @@ -165,64 +178,94 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Renders a row describing the allowed children of an element - * @param $def HTMLPurifier_ChildDef of pertinent element + * @param HTMLPurifier_ChildDef $def HTMLPurifier_ChildDef of pertinent element + * @return string */ - protected function renderChildren($def) { + protected function renderChildren($def) + { $context = new HTMLPurifier_Context(); $ret = ''; $ret .= $this->start('tr'); - $elements = array(); - $attr = array(); - if (isset($def->elements)) { - if ($def->type == 'strictblockquote') { - $def->validateChildren(array(), $this->config, $context); - } - $elements = $def->elements; + $elements = array(); + $attr = array(); + if (isset($def->elements)) { + if ($def->type == 'strictblockquote') { + $def->validateChildren(array(), $this->config, $context); } - if ($def->type == 'chameleon') { - $attr['rowspan'] = 2; - } elseif ($def->type == 'empty') { - $elements = array(); - } elseif ($def->type == 'table') { - $elements = array_flip(array('col', 'caption', 'colgroup', 'thead', - 'tfoot', 'tbody', 'tr')); - } - $ret .= $this->element('th', 'Allowed children', $attr); - - if ($def->type == 'chameleon') { - - $ret .= $this->element('td', - 'Block: ' . - $this->escape($this->listifyTagLookup($def->block->elements)),0,0); - $ret .= $this->end('tr'); - $ret .= $this->start('tr'); - $ret .= $this->element('td', - 'Inline: ' . - $this->escape($this->listifyTagLookup($def->inline->elements)),0,0); - - } elseif ($def->type == 'custom') { + $elements = $def->elements; + } + if ($def->type == 'chameleon') { + $attr['rowspan'] = 2; + } elseif ($def->type == 'empty') { + $elements = array(); + } elseif ($def->type == 'table') { + $elements = array_flip( + array( + 'col', + 'caption', + 'colgroup', + 'thead', + 'tfoot', + 'tbody', + 'tr' + ) + ); + } + $ret .= $this->element('th', 'Allowed children', $attr); - $ret .= $this->element('td', ''.ucfirst($def->type).': ' . - $def->dtd_regex); + if ($def->type == 'chameleon') { - } else { - $ret .= $this->element('td', - ''.ucfirst($def->type).': ' . - $this->escape($this->listifyTagLookup($elements)),0,0); - } + $ret .= $this->element( + 'td', + 'Block: ' . + $this->escape($this->listifyTagLookup($def->block->elements)), + null, + 0 + ); + $ret .= $this->end('tr'); + $ret .= $this->start('tr'); + $ret .= $this->element( + 'td', + 'Inline: ' . + $this->escape($this->listifyTagLookup($def->inline->elements)), + null, + 0 + ); + + } elseif ($def->type == 'custom') { + + $ret .= $this->element( + 'td', + '' . ucfirst($def->type) . ': ' . + $def->dtd_regex + ); + + } else { + $ret .= $this->element( + 'td', + '' . ucfirst($def->type) . ': ' . + $this->escape($this->listifyTagLookup($elements)), + null, + 0 + ); + } $ret .= $this->end('tr'); return $ret; } /** * Listifies a tag lookup table. - * @param $array Tag lookup array in form of array('tagname' => true) + * @param array $array Tag lookup array in form of array('tagname' => true) + * @return string */ - protected function listifyTagLookup($array) { + protected function listifyTagLookup($array) + { ksort($array); $list = array(); foreach ($array as $name => $discard) { - if ($name !== '#PCDATA' && !isset($this->def->info[$name])) continue; + if ($name !== '#PCDATA' && !isset($this->def->info[$name])) { + continue; + } $list[] = $name; } return $this->listify($list); @@ -230,13 +273,15 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Listifies a list of objects by retrieving class names and internal state - * @param $array List of objects + * @param array $array List of objects + * @return string * @todo Also add information about internal state */ - protected function listifyObjectList($array) { + protected function listifyObjectList($array) + { ksort($array); $list = array(); - foreach ($array as $discard => $obj) { + foreach ($array as $obj) { $list[] = $this->getClass($obj, 'AttrTransform_'); } return $this->listify($list); @@ -244,13 +289,17 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Listifies a hash of attributes to AttrDef classes - * @param $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef) + * @param array $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef) + * @return string */ - protected function listifyAttr($array) { + protected function listifyAttr($array) + { ksort($array); $list = array(); foreach ($array as $name => $obj) { - if ($obj === false) continue; + if ($obj === false) { + continue; + } $list[] = "$name = " . $this->getClass($obj, 'AttrDef_') . ''; } return $this->listify($list); @@ -258,15 +307,18 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer /** * Creates a heavy header row + * @param string $text + * @param int $num + * @return string */ - protected function heavyHeader($text, $num = 1) { + protected function heavyHeader($text, $num = 1) + { $ret = ''; $ret .= $this->start('tr'); $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy')); $ret .= $this->end('tr'); return $ret; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/PropertyList.php b/library/HTMLPurifier/PropertyList.php index 2b99fb7b..189348fd 100644 --- a/library/HTMLPurifier/PropertyList.php +++ b/library/HTMLPurifier/PropertyList.php @@ -6,61 +6,93 @@ class HTMLPurifier_PropertyList { /** - * Internal data-structure for properties + * Internal data-structure for properties. + * @type array */ protected $data = array(); /** - * Parent plist + * Parent plist. + * @type HTMLPurifier_PropertyList */ protected $parent; + /** + * Cache. + * @type array + */ protected $cache; - public function __construct($parent = null) { + /** + * @param HTMLPurifier_PropertyList $parent Parent plist + */ + public function __construct($parent = null) + { $this->parent = $parent; } /** * Recursively retrieves the value for a key + * @param string $name + * @throws HTMLPurifier_Exception */ - public function get($name) { - if ($this->has($name)) return $this->data[$name]; + public function get($name) + { + if ($this->has($name)) { + return $this->data[$name]; + } // possible performance bottleneck, convert to iterative if necessary - if ($this->parent) return $this->parent->get($name); + if ($this->parent) { + return $this->parent->get($name); + } throw new HTMLPurifier_Exception("Key '$name' not found"); } /** * Sets the value of a key, for this plist + * @param string $name + * @param mixed $value */ - public function set($name, $value) { + public function set($name, $value) + { $this->data[$name] = $value; } /** * Returns true if a given key exists + * @param string $name + * @return bool */ - public function has($name) { + public function has($name) + { return array_key_exists($name, $this->data); } /** * Resets a value to the value of it's parent, usually the default. If * no value is specified, the entire plist is reset. + * @param string $name */ - public function reset($name = null) { - if ($name == null) $this->data = array(); - else unset($this->data[$name]); + public function reset($name = null) + { + if ($name == null) { + $this->data = array(); + } else { + unset($this->data[$name]); + } } /** * Squashes this property list and all of its property lists into a single * array, and returns the array. This value is cached by default. - * @param $force If true, ignores the cache and regenerates the array. + * @param bool $force If true, ignores the cache and regenerates the array. + * @return array */ - public function squash($force = false) { - if ($this->cache !== null && !$force) return $this->cache; + public function squash($force = false) + { + if ($this->cache !== null && !$force) { + return $this->cache; + } if ($this->parent) { return $this->cache = array_merge($this->parent->squash($force), $this->data); } else { @@ -70,15 +102,19 @@ class HTMLPurifier_PropertyList /** * Returns the parent plist. + * @return HTMLPurifier_PropertyList */ - public function getParent() { + public function getParent() + { return $this->parent; } /** * Sets the parent plist. + * @param HTMLPurifier_PropertyList $plist Parent plist */ - public function setParent($plist) { + public function setParent($plist) + { $this->parent = $plist; } } diff --git a/library/HTMLPurifier/PropertyListIterator.php b/library/HTMLPurifier/PropertyListIterator.php index 8f250443..15b330ea 100644 --- a/library/HTMLPurifier/PropertyListIterator.php +++ b/library/HTMLPurifier/PropertyListIterator.php @@ -6,27 +6,37 @@ class HTMLPurifier_PropertyListIterator extends FilterIterator { + /** + * @type int + */ protected $l; + /** + * @type string + */ protected $filter; /** - * @param $data Array of data to iterate over - * @param $filter Optional prefix to only allow values of + * @param Iterator $iterator Array of data to iterate over + * @param string $filter Optional prefix to only allow values of */ - public function __construct(Iterator $iterator, $filter = null) { + public function __construct(Iterator $iterator, $filter = null) + { parent::__construct($iterator); $this->l = strlen($filter); $this->filter = $filter; } - public function accept() { + /** + * @return bool + */ + public function accept() + { $key = $this->getInnerIterator()->key(); - if( strncmp($key, $this->filter, $this->l) !== 0 ) { + if (strncmp($key, $this->filter, $this->l) !== 0) { return false; } return true; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Strategy.php b/library/HTMLPurifier/Strategy.php index 24628652..e1ff3b72 100644 --- a/library/HTMLPurifier/Strategy.php +++ b/library/HTMLPurifier/Strategy.php @@ -15,12 +15,12 @@ abstract class HTMLPurifier_Strategy /** * Executes the strategy on the tokens. * - * @param $tokens Array of HTMLPurifier_Token objects to be operated on. - * @param $config Configuration options - * @returns Processed array of token objects. + * @param HTMLPurifier_Token[] $tokens Array of HTMLPurifier_Token objects to be operated on. + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] Processed array of token objects. */ abstract public function execute($tokens, $config, $context); - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Strategy/Composite.php b/library/HTMLPurifier/Strategy/Composite.php index 92aefd33..d7d35ce7 100644 --- a/library/HTMLPurifier/Strategy/Composite.php +++ b/library/HTMLPurifier/Strategy/Composite.php @@ -8,16 +8,23 @@ abstract class HTMLPurifier_Strategy_Composite extends HTMLPurifier_Strategy /** * List of strategies to run tokens through. + * @type HTMLPurifier_Strategy[] */ protected $strategies = array(); - public function execute($tokens, $config, $context) { + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] + */ + public function execute($tokens, $config, $context) + { foreach ($this->strategies as $strategy) { $tokens = $strategy->execute($tokens, $config, $context); } return $tokens; } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Strategy/Core.php b/library/HTMLPurifier/Strategy/Core.php index d90e1586..4414c17d 100644 --- a/library/HTMLPurifier/Strategy/Core.php +++ b/library/HTMLPurifier/Strategy/Core.php @@ -5,14 +5,13 @@ */ class HTMLPurifier_Strategy_Core extends HTMLPurifier_Strategy_Composite { - - public function __construct() { + public function __construct() + { $this->strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements(); $this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed(); $this->strategies[] = new HTMLPurifier_Strategy_FixNesting(); $this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes(); } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Strategy/FixNesting.php b/library/HTMLPurifier/Strategy/FixNesting.php index d1588b93..d00c6d04 100644 --- a/library/HTMLPurifier/Strategy/FixNesting.php +++ b/library/HTMLPurifier/Strategy/FixNesting.php @@ -47,7 +47,14 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy { - public function execute($tokens, $config, $context) { + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array|HTMLPurifier_Token[] + */ + public function execute($tokens, $config, $context) + { //####################################################################// // Pre-processing @@ -95,7 +102,7 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy // iterate through all start nodes. Determining the start node // is complicated so it has been omitted from the loop construct - for ($i = 0, $size = count($tokens) ; $i < $size; ) { + for ($i = 0, $size = count($tokens); $i < $size;) { //################################################################// // Gather information on children @@ -110,12 +117,16 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy $depth++; // skip token assignment on first iteration, this is the // token we currently are on - if ($depth == 1) continue; + if ($depth == 1) { + continue; + } } elseif ($tokens[$j] instanceof HTMLPurifier_Token_End) { $depth--; // skip token assignment on last iteration, this is the // end token of the token we're currently on - if ($depth == 0) break; + if ($depth == 0) { + break; + } } $child_tokens[] = $tokens[$j]; } @@ -130,12 +141,12 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy // calculate parent information if ($count = count($stack)) { - $parent_index = $stack[$count-1]; - $parent_name = $tokens[$parent_index]->name; + $parent_index = $stack[$count - 1]; + $parent_name = $tokens[$parent_index]->name; if ($parent_index == 0) { - $parent_def = $definition->info_parent_def; + $parent_def = $definition->info_parent_def; } else { - $parent_def = $definition->info[$parent_name]; + $parent_def = $definition->info[$parent_name]; } } else { // processing as if the parent were the "root" node @@ -195,7 +206,10 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy if (!empty($def->child)) { // have DTD child def validate children $result = $def->child->validateChildren( - $child_tokens, $config, $context); + $child_tokens, + $config, + $context + ); } else { // weird, no child definition, get rid of everything $result = false; @@ -217,12 +231,14 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy $stack[] = $i; // register exclusions if there are any - if (!empty($excludes)) $exclude_stack[] = $excludes; + if (!empty($excludes)) { + $exclude_stack[] = $excludes; + } // move cursor to next possible start node $i++; - } elseif($result === false) { + } elseif ($result === false) { // remove entire node if ($e) { @@ -286,11 +302,12 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy $stack[] = $i; // register exclusions if there are any - if (!empty($excludes)) $exclude_stack[] = $excludes; + if (!empty($excludes)) { + $exclude_stack[] = $excludes; + } // move cursor to next possible start node $i++; - } //################################################################// @@ -336,11 +353,8 @@ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy //####################################################################// // Return - return $tokens; - } - } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Strategy/MakeWellFormed.php b/library/HTMLPurifier/Strategy/MakeWellFormed.php index 53cd0db0..899d6750 100644 --- a/library/HTMLPurifier/Strategy/MakeWellFormed.php +++ b/library/HTMLPurifier/Strategy/MakeWellFormed.php @@ -16,36 +16,49 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy /** * Array stream of tokens being processed. + * @type HTMLPurifier_Token[] */ protected $tokens; /** * Current index in $tokens. + * @type int */ protected $t; /** * Current nesting of elements. + * @type array */ protected $stack; /** * Injectors active in this stream processing. + * @type HTMLPurifier_Injector[] */ protected $injectors; /** * Current instance of HTMLPurifier_Config. + * @type HTMLPurifier_Config */ protected $config; /** * Current instance of HTMLPurifier_Context. + * @type HTMLPurifier_Context */ protected $context; - public function execute($tokens, $config, $context) { - + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] + * @throws HTMLPurifier_Exception + */ + public function execute($tokens, $config, $context) + { $definition = $config->getHTMLDefinition(); // local variables @@ -56,22 +69,22 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy $e = $context->get('ErrorCollector', true); $t = false; // token index $i = false; // injector index - $token = false; // the current token - $reprocess = false; // whether or not to reprocess the same token + $token = false; // the current token + $reprocess = false; // whether or not to reprocess the same token $stack = array(); // member variables - $this->stack =& $stack; - $this->t =& $t; - $this->tokens =& $tokens; - $this->config = $config; + $this->stack =& $stack; + $this->t =& $t; + $this->tokens =& $tokens; + $this->config = $config; $this->context = $context; // context variables $context->register('CurrentNesting', $stack); - $context->register('InputIndex', $t); - $context->register('InputTokens', $tokens); - $context->register('CurrentToken', $token); + $context->register('InputIndex', $t); + $context->register('InputTokens', $tokens); + $context->register('CurrentToken', $token); // -- begin INJECTOR -- @@ -83,9 +96,13 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy unset($injectors['Custom']); // special case foreach ($injectors as $injector => $b) { // XXX: Fix with a legitimate lookup table of enabled filters - if (strpos($injector, '.') !== false) continue; + if (strpos($injector, '.') !== false) { + continue; + } $injector = "HTMLPurifier_Injector_$injector"; - if (!$b) continue; + if (!$b) { + continue; + } $this->injectors[] = new $injector; } foreach ($def_injectors as $injector) { @@ -93,7 +110,9 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy $this->injectors[] = $injector; } foreach ($custom_injectors as $injector) { - if (!$injector) continue; + if (!$injector) { + continue; + } if (is_string($injector)) { $injector = "HTMLPurifier_Injector_$injector"; $injector = new $injector; @@ -105,7 +124,9 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy // variables for performance reasons foreach ($this->injectors as $ix => $injector) { $error = $injector->prepare($config, $context); - if (!$error) continue; + if (!$error) { + continue; + } array_splice($this->injectors, $ix, 1); // rm the injector trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING); } @@ -121,12 +142,10 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy // punt ($reprocess = true; continue;) and it does that for us. // isset is in loop because $tokens size changes during loop exec - for ( - $t = 0; - $t == 0 || isset($tokens[$t - 1]); + for ($t = 0; + $t == 0 || isset($tokens[$t - 1]); // only increment if we don't need to reprocess - $reprocess ? $reprocess = false : $t++ - ) { + $reprocess ? $reprocess = false : $t++) { // check for a rewind if (is_int($i) && $i >= 0) { @@ -135,7 +154,9 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy // infinite loop, but might hinder some advanced rewinding. $rewind_to = $this->injectors[$i]->getRewind(); if (is_int($rewind_to) && $rewind_to < $t) { - if ($rewind_to < 0) $rewind_to = 0; + if ($rewind_to < 0) { + $rewind_to = 0; + } while ($t > $rewind_to) { $t--; $prev = $tokens[$t]; @@ -143,8 +164,11 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy // but we need to reprocess it unset($prev->skip[$i]); $prev->rewind = $i; - if ($prev instanceof HTMLPurifier_Token_Start) array_pop($this->stack); - elseif ($prev instanceof HTMLPurifier_Token_End) $this->stack[] = $prev->start; + if ($prev instanceof HTMLPurifier_Token_Start) { + array_pop($this->stack); + } elseif ($prev instanceof HTMLPurifier_Token_End) { + $this->stack[] = $prev->start; + } } } $i = false; @@ -153,7 +177,9 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy // handle case of document end if (!isset($tokens[$t])) { // kill processing if stack is empty - if (empty($this->stack)) break; + if (empty($this->stack)) { + break; + } // peek $top_nesting = array_pop($this->stack); @@ -181,8 +207,12 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy if (empty($token->is_tag)) { if ($token instanceof HTMLPurifier_Token_Text) { foreach ($this->injectors as $i => $injector) { - if (isset($token->skip[$i])) continue; - if ($token->rewind !== null && $token->rewind !== $i) continue; + if (isset($token->skip[$i])) { + continue; + } + if ($token->rewind !== null && $token->rewind !== $i) { + continue; + } $injector->handleText($token); $this->processToken($token, $i); $reprocess = true; @@ -203,12 +233,20 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy $ok = false; if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) { // claims to be a start tag but is empty - $token = new HTMLPurifier_Token_Empty($token->name, $token->attr, $token->line, $token->col, $token->armor); + $token = new HTMLPurifier_Token_Empty( + $token->name, + $token->attr, + $token->line, + $token->col, + $token->armor + ); $ok = true; } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) { // claims to be empty but really is a start tag $this->swap(new HTMLPurifier_Token_End($token->name)); - $this->insertBefore(new HTMLPurifier_Token_Start($token->name, $token->attr, $token->line, $token->col, $token->armor)); + $this->insertBefore( + new HTMLPurifier_Token_Start($token->name, $token->attr, $token->line, $token->col, $token->armor) + ); // punt (since we had to modify the input stream in a non-trivial way) $reprocess = true; continue; @@ -247,8 +285,8 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy } if ($autoclose && $definition->info[$token->name]->wrap) { - // Check if an element can be wrapped by another - // element to make it valid in a context (for + // Check if an element can be wrapped by another + // element to make it valid in a context (for // example,