mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-08-05 13:47:24 +02:00
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f38e81785f | ||
|
2cc829a8cf | ||
|
e80a54a7c9 | ||
|
6f71e65661 | ||
|
6f25c39c3e | ||
|
b8b1ac283d | ||
|
450fc6649d | ||
|
369a69d533 | ||
|
72f5819ef6 | ||
|
3540ea7fce | ||
|
c03953f85e | ||
|
0d262b3a1d | ||
|
234cd2196f | ||
|
0dbe87bbc7 | ||
|
245b5bdb27 | ||
|
864cb9e136 | ||
|
487fcd55ea | ||
|
ec6b6821cf | ||
|
f26eb7551a | ||
|
a2aca4819d | ||
|
a75e4c6b7c | ||
|
e7fa8cbdd5 | ||
|
5fa575f8ac | ||
|
9f23bc005b | ||
|
957a840f54 | ||
|
a7762c5137 | ||
|
aca9d725ed | ||
|
4ce3deba26 | ||
|
d4da02ba95 | ||
|
97d3c8509c | ||
|
21c6803401 | ||
|
36badb06f6 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
|||||||
configdoc/usage.xml -crlf
|
|
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,13 +0,0 @@
|
|||||||
conf/
|
|
||||||
test-settings.php
|
|
||||||
library/HTMLPurifier/DefinitionCache/Serializer/*/
|
|
||||||
library/standalone/
|
|
||||||
library/HTMLPurifier.standalone.php
|
|
||||||
configdoc/*.html
|
|
||||||
configdoc/configdoc.xml
|
|
||||||
*.phpt.diff
|
|
||||||
*.phpt.exp
|
|
||||||
*.phpt.log
|
|
||||||
*.phpt.out
|
|
||||||
*.phpt.php
|
|
||||||
*.phpt.skip.php
|
|
2
Doxyfile
2
Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 3.2.0
|
PROJECT_NUMBER = 2.1.5
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
|
13
FOCUS
13
FOCUS
@@ -1,13 +0,0 @@
|
|||||||
5 - Major feature enhancements
|
|
||||||
|
|
||||||
[ Appendix A: Release focus IDs ]
|
|
||||||
0 - N/A
|
|
||||||
1 - Initial freshmeat announcement
|
|
||||||
2 - Documentation
|
|
||||||
3 - Code cleanup
|
|
||||||
4 - Minor feature enhancements
|
|
||||||
5 - Major feature enhancements
|
|
||||||
6 - Minor bugfixes
|
|
||||||
7 - Major bugfixes
|
|
||||||
8 - Minor security fixes
|
|
||||||
9 - Major security fixes
|
|
161
INSTALL
161
INSTALL
@@ -7,19 +7,19 @@ library is extremely easy. (Although... if you were looking for a
|
|||||||
step-by-step installation GUI, you've downloaded the wrong software!)
|
step-by-step installation GUI, you've downloaded the wrong software!)
|
||||||
|
|
||||||
While the impatient can get going immediately with some of the sample
|
While the impatient can get going immediately with some of the sample
|
||||||
code at the bottom of this library, it's well worth reading this entire
|
code at the bottom of this library, it's well worth performing some
|
||||||
document--most of the other documentation assumes that you are familiar
|
basic sanity checks to get the most out of this library.
|
||||||
with these contents.
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
1. Compatibility
|
1. Compatibility
|
||||||
|
|
||||||
HTML Purifier is PHP 5 only, and is actively tested from PHP 5.0.5 and
|
THIS IS A DEPRECATED PHP4 VERSION OF HTML PURIFIER.
|
||||||
up. It has no core dependencies with other libraries. PHP
|
|
||||||
4 support was deprecated on December 31, 2007 with HTML Purifier 3.0.0.
|
If you are running PHP5, please go to http://htmlpurifier.org to download
|
||||||
Essential security fixes will be issued for the 2.1.x branch until
|
the latest version. This version of HTML Purifier is only actively tested
|
||||||
August 8, 2008.
|
from PHP 4.3.7 to PHP 5.0.5. Essential security will be released for this branch
|
||||||
|
fixes will be issued for the PHP 4 version until August 8, 2008.
|
||||||
|
|
||||||
These optional extensions can enhance the capabilities of HTML Purifier:
|
These optional extensions can enhance the capabilities of HTML Purifier:
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ HTML Purifier can process these doctypes:
|
|||||||
* UTF-8 (default)
|
* UTF-8 (default)
|
||||||
* Any encoding iconv supports (with crippled internationalization support)
|
* Any encoding iconv supports (with crippled internationalization support)
|
||||||
|
|
||||||
These defaults reflect what my choices would be if I were authoring an
|
These defaults reflect what my choices where be if I were authoring an
|
||||||
HTML document, however, what you choose depends on the nature of your
|
HTML document, however, what you choose depends on the nature of your
|
||||||
codebase. If you don't know what doctype you are using, you can determine
|
codebase. If you don't know what doctype you are using, you can determine
|
||||||
the doctype from this identifier at the top of your source code:
|
the doctype from this identifier at the top of your source code:
|
||||||
@@ -64,8 +64,8 @@ the doctype from this identifier at the top of your source code:
|
|||||||
If the character encoding declaration is missing, STOP NOW, and
|
If the character encoding declaration is missing, STOP NOW, and
|
||||||
read 'docs/enduser-utf8.html' (web accessible at
|
read 'docs/enduser-utf8.html' (web accessible at
|
||||||
http://htmlpurifier.org/docs/enduser-utf8.html). In fact, even if it is
|
http://htmlpurifier.org/docs/enduser-utf8.html). In fact, even if it is
|
||||||
present, read this document anyway, as many websites specify their
|
present, read this document anyway, as most websites specify character
|
||||||
document's character encoding incorrectly.
|
encoding incorrectly.
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
@@ -75,142 +75,25 @@ The procedure is quite simple:
|
|||||||
|
|
||||||
require_once '/path/to/library/HTMLPurifier.auto.php';
|
require_once '/path/to/library/HTMLPurifier.auto.php';
|
||||||
|
|
||||||
This will setup an autoloader, so the library's files are only included
|
I recommend only including HTML Purifier when you need it, because that
|
||||||
when you use them.
|
call represents the inclusion of a lot of PHP files which constitute
|
||||||
|
the bulk of HTML Purifier's memory usage.
|
||||||
|
|
||||||
|
If you don't like your include_path to be fiddled around with, simply set
|
||||||
|
HTML Purifier's library/ directory to the include path yourself and then:
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier.php';
|
||||||
|
|
||||||
Only the contents in the library/ folder are necessary, so you can remove
|
Only the contents in the library/ folder are necessary, so you can remove
|
||||||
everything else when using HTML Purifier in a production environment.
|
everything else when using HTML Purifier in a production environment.
|
||||||
|
|
||||||
If you installed HTML Purifier via PEAR, all you need to do is:
|
|
||||||
|
|
||||||
require_once 'HTMLPurifier.auto.php';
|
|
||||||
|
|
||||||
Please note that the usual PEAR practice of including just the classes you
|
|
||||||
want will not work with HTML Purifier's autoloading scheme.
|
|
||||||
|
|
||||||
Advanced users, read on; other users can skip to section 4.
|
|
||||||
|
|
||||||
Autoload compatibility
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
HTML Purifier attempts to be as smart as possible when registering an
|
|
||||||
autoloader, but there are some cases where you will need to change
|
|
||||||
your own code to accomodate HTML Purifier. These are those cases:
|
|
||||||
|
|
||||||
PHP VERSION IS LESS THAN 5.1.2, AND YOU'VE DEFINED __autoload
|
|
||||||
Because spl_autoload_register() doesn't exist in early versions
|
|
||||||
of PHP 5, HTML Purifier has no way of adding itself to the autoload
|
|
||||||
stack. Modify your __autoload function to test
|
|
||||||
HTMLPurifier_Bootstrap::autoload($class)
|
|
||||||
|
|
||||||
For example, suppose your autoload function looks like this:
|
|
||||||
|
|
||||||
function __autoload($class) {
|
|
||||||
require str_replace('_', '/', $class) . '.php';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
A modified version with HTML Purifier would look like this:
|
|
||||||
|
|
||||||
function __autoload($class) {
|
|
||||||
if (HTMLPurifier_Bootstrap::autoload($class)) return true;
|
|
||||||
require str_replace('_', '/', $class) . '.php';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Note that there *is* some custom behavior in our autoloader; the
|
|
||||||
original autoloader in our example would work for 99% of the time,
|
|
||||||
but would fail when including language files.
|
|
||||||
|
|
||||||
AN __autoload FUNCTION IS DECLARED AFTER OUR AUTOLOADER IS REGISTERED
|
|
||||||
spl_autoload_register() has the curious behavior of disabling
|
|
||||||
the existing __autoload() handler. Users need to explicitly
|
|
||||||
spl_autoload_register('__autoload'). Because we use SPL when it
|
|
||||||
is available, __autoload() will ALWAYS be disabled. If __autoload()
|
|
||||||
is declared before HTML Purifier is loaded, this is not a problem:
|
|
||||||
HTML Purifier will register the function for you. But if it is
|
|
||||||
declared afterwards, it will mysteriously not work. This
|
|
||||||
snippet of code (after your autoloader is defined) will fix it:
|
|
||||||
|
|
||||||
spl_autoload_register('__autoload')
|
|
||||||
|
|
||||||
Users should also be on guard if they use a version of PHP previous
|
|
||||||
to 5.1.2 without an autoloader--HTML Purifier will define __autoload()
|
|
||||||
for you, which can collide with an autoloader that was added by *you*
|
|
||||||
later.
|
|
||||||
|
|
||||||
|
|
||||||
For better performance
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
Opcode caches, which greatly speed up PHP initialization for scripts
|
|
||||||
with large amounts of code (HTML Purifier included), don't like
|
|
||||||
autoloaders. We offer an include file that includes all of HTML Purifier's
|
|
||||||
files in one go in an opcode cache friendly manner:
|
|
||||||
|
|
||||||
// If /path/to/library isn't already in your include path, uncomment
|
|
||||||
// the below line:
|
|
||||||
// require '/path/to/library/HTMLPurifier.path.php';
|
|
||||||
|
|
||||||
require 'HTMLPurifier.includes.php';
|
|
||||||
|
|
||||||
Optional components still need to be included--you'll know if you try to
|
|
||||||
use a feature and you get a class doesn't exists error! The autoloader
|
|
||||||
can be used in conjunction with this approach to catch classes that are
|
|
||||||
missing. Simply add this afterwards:
|
|
||||||
|
|
||||||
require 'HTMLPurifier.autoload.php';
|
|
||||||
|
|
||||||
Standalone version
|
|
||||||
------------------
|
|
||||||
|
|
||||||
HTML Purifier has a standalone distribution; you can also generate
|
|
||||||
a standalone file from the full version by running the script
|
|
||||||
maintenance/generate-standalone.php . The standalone version has the
|
|
||||||
benefit of having most of its code in one file, so parsing is much
|
|
||||||
faster and the library is easier to manage.
|
|
||||||
|
|
||||||
If HTMLPurifier.standalone.php exists in the library directory, you
|
|
||||||
can use it like this:
|
|
||||||
|
|
||||||
require '/path/to/HTMLPurifier.standalone.php';
|
|
||||||
|
|
||||||
This is equivalent to including HTMLPurifier.includes.php, except that
|
|
||||||
the contents of standalone/ will be added to your path. To override this
|
|
||||||
behavior, specify a new HTMLPURIFIER_PREFIX where standalone files can
|
|
||||||
be found (usually, this will be one directory up, the "true" library
|
|
||||||
directory in full distributions). Don't forget to set your path too!
|
|
||||||
|
|
||||||
The autoloader can be added to the end to ensure the classes are
|
|
||||||
loaded when necessary; otherwise you can manually include them.
|
|
||||||
To use the autoloader, use this:
|
|
||||||
|
|
||||||
require 'HTMLPurifier.autoload.php';
|
|
||||||
|
|
||||||
For advanced users
|
|
||||||
------------------
|
|
||||||
|
|
||||||
HTMLPurifier.auto.php performs a number of operations that can be done
|
|
||||||
individually. These are:
|
|
||||||
|
|
||||||
HTMLPurifier.path.php
|
|
||||||
Puts /path/to/library in the include path. For high performance,
|
|
||||||
this should be done in php.ini.
|
|
||||||
|
|
||||||
HTMLPurifier.autoload.php
|
|
||||||
Registers our autoload handler HTMLPurifier_Bootstrap::autoload($class).
|
|
||||||
|
|
||||||
You can do these operations by yourself--in fact, you must modify your own
|
|
||||||
autoload handler if you are using a version of PHP earlier than PHP 5.1.2
|
|
||||||
(See "Autoload compatibility" above).
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
4. Configuration
|
4. Configuration
|
||||||
|
|
||||||
HTML Purifier is designed to run out-of-the-box, but occasionally HTML
|
HTML Purifier is designed to run out-of-the-box, but occasionally HTML
|
||||||
Purifier needs to be told what to do. If you answer no to any of these
|
Purifier needs to be told what to do. If you answered no to any of these
|
||||||
questions, read on; otherwise, you can skip to the next section (or, if you're
|
questions, read on, otherwise, you can skip to the next section (or, if you're
|
||||||
into configuring things just for the heck of it, skip to 4.3).
|
into configuring things just for the heck of it, skip to 4.3).
|
||||||
|
|
||||||
* Am I using UTF-8?
|
* Am I using UTF-8?
|
||||||
|
@@ -17,7 +17,7 @@ ce document pour quelques choses.
|
|||||||
|
|
||||||
1. Compatibilité
|
1. Compatibilité
|
||||||
|
|
||||||
HTML Purifier fonctionne dans PHP 5. PHP 5.0.5 est le dernier
|
HTML Purifier fonctionne dans PHP 4 et PHP 5. PHP 4.3.2 est le dernier
|
||||||
version que je le testais. Il ne dépend de les autre librairies.
|
version que je le testais. Il ne dépend de les autre librairies.
|
||||||
|
|
||||||
Les extensions optionnel est iconv (en général déjà installer) et
|
Les extensions optionnel est iconv (en général déjà installer) et
|
||||||
@@ -34,15 +34,19 @@ Utilisez:
|
|||||||
...quand vous devez utiliser HTML Purifier (ne inclure pas quand vous
|
...quand vous devez utiliser HTML Purifier (ne inclure pas quand vous
|
||||||
ne devez pas, parce que HTML Purifier est trés grand.)
|
ne devez pas, parce que HTML Purifier est trés grand.)
|
||||||
|
|
||||||
HTML Purifier utilise 'autoload'. Si vous avez définu la fonction
|
Si vous n'aime pas que HTML Purifier change vos include_path, on peut
|
||||||
__autoload, vous doivez ajoute cet programme:
|
change vos include_path, et:
|
||||||
|
|
||||||
spl_autoload_register('__autoload')
|
require_once 'HTMLPurifier.php';
|
||||||
|
|
||||||
Plus d'information est dans le document 'INSTALL'.
|
Seuleument les contents dans library/ est essentiel; vous peut enlever
|
||||||
|
les autre fichiers quand vous est dans une atmosphère professionnel.
|
||||||
|
|
||||||
|
|
||||||
3. Installation vite
|
[En cours de construction]
|
||||||
|
|
||||||
|
|
||||||
|
6. Installation vite
|
||||||
|
|
||||||
Si votre site web est en UTF-8 et XHTML Transitional, utilisez:
|
Si votre site web est en UTF-8 et XHTML Transitional, utilisez:
|
||||||
|
|
||||||
|
303
NEWS
303
NEWS
@@ -9,123 +9,35 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
. Internal change
|
. Internal change
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
3.2.0, released 2008-10-31
|
ERRATA
|
||||||
# Using %Core.CollectErrors forces line number/column tracking on, whereas
|
- PH5P is seriously broken here; it can result in fatal errors and exceptions.
|
||||||
previously you could theoretically turn it off.
|
If you desire to use it, please use it with the latest, PHP5-only version of
|
||||||
# HTMLPurifier_Injector->notifyEnd() is formally deprecated. Please
|
HTML Purifier.
|
||||||
use handleEnd() instead.
|
|
||||||
! %Output.AttrSort for when you need your attributes in alphabetical order to
|
|
||||||
deal with a bug in FCKEditor. Requested by frank farmer.
|
|
||||||
! Enable HTML comments when %HTML.Trusted is on. Requested by Waldo Jaquith.
|
|
||||||
! Proper support for name attribute. It is now allowed and equivalent to the id
|
|
||||||
attribute in a and img tags, and is only converted to id when %HTML.TidyLevel
|
|
||||||
is heavy (for all doctypes).
|
|
||||||
! %AutoFormat.RemoveEmpty to remove some empty tags from documents. Please don't
|
|
||||||
use on hand-written HTML.
|
|
||||||
! Add error-cases for unsupported elements in MakeWellFormed. This enables
|
|
||||||
the strategy to be used, standalone, on untrusted input.
|
|
||||||
! %Core.AggressivelyFixLt is on by default. This causes more sensible
|
|
||||||
processing of left angled brackets in smileys and other whatnot.
|
|
||||||
! Test scripts now have a 'type' parameter, which lets you say 'htmlpurifier',
|
|
||||||
'phpt', 'vtest', etc. in order to only execute those tests. This supercedes
|
|
||||||
the --only-phpt parameter, although for backwards-compatibility the flag
|
|
||||||
will still work.
|
|
||||||
! AutoParagraph auto-formatter will now preserve double-newlines upon output.
|
|
||||||
Users who are not performing inbound filtering, this may seem a little
|
|
||||||
useless, but as a bonus, the test suite and handling of edge cases is also
|
|
||||||
improved.
|
|
||||||
! Experimental implementation of forms for %HTML.Trusted
|
|
||||||
! Track column numbers when maintain line numbers is on
|
|
||||||
! Proprietary 'background' attribute on table-related elements converted into
|
|
||||||
corresponding CSS. Thanks Fusemail for sponsoring this feature!
|
|
||||||
! Add forward(), forwardUntilEndToken(), backward() and current() to Injector
|
|
||||||
supertype.
|
|
||||||
! HTMLPurifier_Injector->handleEnd() permits modification to end tokens. The
|
|
||||||
time of operation varies slightly from notifyEnd() as *all* end tokens are
|
|
||||||
processed by the injector before they are subject to the well-formedness rules.
|
|
||||||
! %Attr.DefaultImageAlt allows overriding default behavior of setting alt to
|
|
||||||
basename of image when not present.
|
|
||||||
! %AutoFormat.DisplayLinkURI neuters <a> tags into plain text URLs.
|
|
||||||
- Fix two bugs in %URI.MakeAbsolute; one involving empty paths in base URLs,
|
|
||||||
the other involving an undefined $is_folder error.
|
|
||||||
- Throw error when %Core.Encoding is set to a spurious value. Previously,
|
|
||||||
this errored silently and returned false.
|
|
||||||
- Redirected stderr to stdout for flush error output.
|
|
||||||
- %URI.DisableExternal will now use the host in %URI.Base if %URI.Host is not
|
|
||||||
available.
|
|
||||||
- Do not re-munge URL if the output URL has the same host as the input URL.
|
|
||||||
Requested by Chris.
|
|
||||||
- Fix error in documentation regarding %Filter.ExtractStyleBlocks
|
|
||||||
- Prevent <![CDATA[<body></body>]]> from triggering %Core.ConvertDocumentToFragment
|
|
||||||
- Fix bug with inline elements in blockquotes conflicting with strict doctype
|
|
||||||
- Detect if HTML support is disabled for DOM by checking for loadHTML() method.
|
|
||||||
- Fix bug where dots and double-dots in absolute URLs without hostname were
|
|
||||||
not collapsed by URIFilter_MakeAbsolute.
|
|
||||||
- Fix bug with anonymous modules operating on SafeEmbed or SafeObject elements
|
|
||||||
by reordering their addition.
|
|
||||||
- Will now throw exception on many error conditions during lexer creation; also
|
|
||||||
throw an exception when MaintainLineNumbers is true, but a non-tracksLineNumbers
|
|
||||||
is being used.
|
|
||||||
- Detect if domxml extension is loaded, and use DirectLEx accordingly.
|
|
||||||
- Improve handling of big numbers with floating point arithmetic in UnitConverter.
|
|
||||||
Reported by David Morton.
|
|
||||||
. Strategy_MakeWellFormed now operates in-place, saving memory and allowing
|
|
||||||
for more interesting filter-backtracking
|
|
||||||
. New HTMLPurifier_Injector->rewind() functionality, allows injectors to rewind
|
|
||||||
index to reprocess tokens.
|
|
||||||
. StringHashParser now allows for multiline sections with "empty" content;
|
|
||||||
previously the section would remain undefined.
|
|
||||||
. Added --quick option to multitest.php, which tests only the most recent
|
|
||||||
release for each series.
|
|
||||||
. Added --distro option to multitest.php, which accepts either 'normal' or
|
|
||||||
'standalone'. This supercedes --exclude-normal and --exclude-standalone
|
|
||||||
|
|
||||||
3.1.1, released 2008-06-19
|
2.1.5, released 2008-06-19
|
||||||
# %URI.Munge now, by default, does not munge resources (for example, <img src="">)
|
|
||||||
In order to enable this again, please set %URI.MungeResources to true.
|
|
||||||
! More robust imagecrash protection with height/width CSS with %CSS.MaxImgLength,
|
! More robust imagecrash protection with height/width CSS with %CSS.MaxImgLength,
|
||||||
and height/width HTML with %HTML.MaxImgLength.
|
and height/width HTML with %HTML.MaxImgLength.
|
||||||
! %URI.MungeSecretKey for secure URI munging. Thanks Chris
|
|
||||||
for sponsoring this feature. Check out the corresponding documentation
|
|
||||||
for details. (Att Nightly testers: The API for this feature changed before
|
|
||||||
the general release. Namely, rename your directives %URI.SecureMungeSecretKey =>
|
|
||||||
%URI.MungeSecretKey and and %URI.SecureMunge => %URI.Munge)
|
|
||||||
! Implemented post URI filtering. Set member variable $post to true to set
|
|
||||||
a URIFilter as such.
|
|
||||||
! Allow modules to define injectors via $info_injector. Injectors are
|
|
||||||
automatically disabled if injector's needed elements are not found.
|
|
||||||
! Support for "safe" objects added, use %HTML.SafeObject and %HTML.SafeEmbed.
|
|
||||||
Thanks Chris for sponsoring. If you've been using ad hoc code from the
|
|
||||||
forums, PLEASE use this instead.
|
|
||||||
! Added substitutions for %e, %n, %a and %p in %URI.Munge (in order,
|
|
||||||
embedded, tag name, attribute name, CSS property name). See %URI.Munge
|
|
||||||
for more details. Requested by Jochem Blok.
|
|
||||||
- Disable percent height/width attributes for img.
|
|
||||||
- AttrValidator operations are now atomic; updates to attributes are not
|
- AttrValidator operations are now atomic; updates to attributes are not
|
||||||
manifest in token until end of operations. This prevents naughty internal
|
manifest in token until end of operations. This prevents naughty internal
|
||||||
code from directly modifying CurrentToken when they're not supposed to.
|
code from directly modifying CurrentToken when they're not supposed to.
|
||||||
This semantics change was requested by frank farmer.
|
|
||||||
- Percent encoding checks enabled for URI query and fragment
|
- Percent encoding checks enabled for URI query and fragment
|
||||||
|
- Disable percent height/width attributes for img
|
||||||
- Fix stray backslashes in font-family; CSS Unicode character escapes are
|
- Fix stray backslashes in font-family; CSS Unicode character escapes are
|
||||||
now properly resolved (although *only* in font-family). Thanks Takeshi Terada
|
now properly resolved (although *only* in font-family).
|
||||||
for reporting.
|
|
||||||
- Improve parseCDATA algorithm to take into account newline normalization
|
- Improve parseCDATA algorithm to take into account newline normalization
|
||||||
- Account for browser confusion between Yen character and backslash in
|
- Account for browser confusion between Yen character and backslash in
|
||||||
Shift_JIS encoding. This fix generalizes to any other encoding which is not
|
Shift_JIS encoding. This fix generalizes to any other encoding which is not
|
||||||
a strict superset of printable ASCII. Thanks Takeshi Terada for reporting.
|
a strict superset of printable ASCII.
|
||||||
- Fix missing configuration parameter in Generator calls. Thanks vs for the
|
|
||||||
partial patch.
|
|
||||||
- Improved adherence to Unicode by checking for non-character codepoints.
|
- Improved adherence to Unicode by checking for non-character codepoints.
|
||||||
Thanks Geoffrey Sneddon for reporting. This may result in degraded
|
Thanks Geoffrey Sneddon for reporting. This may result in degraded
|
||||||
performance for extremely large inputs.
|
performance for extremely large inputs.
|
||||||
- Allow CSS property-value pair ''text-decoration: none''. Thanks Jochem Blok
|
- Allow CSS property-value pair ''text-decoration: none''
|
||||||
for reporting.
|
|
||||||
. Added HTMLPurifier_UnitConverter and HTMLPurifier_Length for convenient
|
. Added HTMLPurifier_UnitConverter and HTMLPurifier_Length for convenient
|
||||||
handling of CSS-style lengths. HTMLPurifier_AttrDef_CSS_Length now uses
|
handling of CSS-style lengths. HTMLPurifier_AttrDef_CSS_Length now uses
|
||||||
this class.
|
this class.
|
||||||
. API of HTMLPurifier_AttrDef_CSS_Length changed from __construct($disable_negative)
|
. API of HTMLPurifier_AttrDef_CSS_Length changed from __construct($disable_negative)
|
||||||
to __construct($min, $max). __construct(true) is equivalent to
|
to __construct($min, $max). __construct(true) is equivalent to
|
||||||
__construct('0').
|
__construct('0'). (replace __construct with HTMLPurifier_AttrDef_CSS_Length)
|
||||||
. Added HTMLPurifier_AttrDef_Switch class
|
. Added HTMLPurifier_AttrDef_Switch class
|
||||||
. Rename HTMLPurifier_HTMLModule_Tidy->construct() to setup() and bubble method
|
. Rename HTMLPurifier_HTMLModule_Tidy->construct() to setup() and bubble method
|
||||||
up inheritance hierarchy to HTMLPurifier_HTMLModule. All HTMLModules
|
up inheritance hierarchy to HTMLPurifier_HTMLModule. All HTMLModules
|
||||||
@@ -134,197 +46,26 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
will still work--the new format, however, lets modules access the
|
will still work--the new format, however, lets modules access the
|
||||||
configuration object for HTML namespace dependant tweaks.
|
configuration object for HTML namespace dependant tweaks.
|
||||||
. AttrDef_HTML_Pixels now takes a single construction parameter, pixels.
|
. AttrDef_HTML_Pixels now takes a single construction parameter, pixels.
|
||||||
. ConfigSchema data-structure heavily optimized; on average it uses a third
|
|
||||||
the memory it did previously. The interface has changed accordingly,
|
|
||||||
consult changes to HTMLPurifier_Config for details.
|
|
||||||
. Variable parsing types now are magic integers instead of strings
|
|
||||||
. Added benchmark for ConfigSchema
|
|
||||||
. HTMLPurifier_Generator requires $config and $context parameters. If you
|
|
||||||
don't know what they should be, use HTMLPurifier_Config::createDefault()
|
|
||||||
and new HTMLPurifier_Context().
|
|
||||||
. Printers now properly distinguish between output configuration, and
|
|
||||||
target configuration. This is not applicable to scripts using
|
|
||||||
the Printers for HTML Purifier related tasks.
|
|
||||||
. HTML/CSS Printers must be primed with prepareGenerator($gen_config), otherwise
|
|
||||||
fatal errors will ensue.
|
|
||||||
. URIFilter->prepare can return false in order to abort loading of the filter
|
|
||||||
. Factory for AttrDef_URI implemented, URI#embedded to indicate URI that embeds
|
|
||||||
an external resource.
|
|
||||||
. %URI.Munge functionality factored out into a post-filter class.
|
|
||||||
. Added CurrentCSSProperty context variable during CSS validation
|
|
||||||
|
|
||||||
3.1.0, released 2008-05-18
|
2.1.4, released 2008-05-18
|
||||||
# Unnecessary references to objects (vestiges of PHP4) removed from method
|
! DefinitionCacheFactory now can register new implementations
|
||||||
signatures. The following methods do not need references when assigning from
|
! CSS properties are now case-insensitive
|
||||||
them and will result in E_STRICT errors if you try:
|
! Encoder optimized with valid UTF-8 input
|
||||||
+ HTMLPurifier_Config->get*Definition() [* = HTML, CSS]
|
|
||||||
+ HTMLPurifier_ConfigSchema::instance()
|
|
||||||
+ HTMLPurifier_DefinitionCacheFactory::instance()
|
|
||||||
+ HTMLPurifier_DefinitionCacheFactory->create()
|
|
||||||
+ HTMLPurifier_DoctypeRegistry->register()
|
|
||||||
+ HTMLPurifier_DoctypeRegistry->get()
|
|
||||||
+ HTMLPurifier_HTMLModule->addElement()
|
|
||||||
+ HTMLPurifier_HTMLModule->addBlankElement()
|
|
||||||
+ HTMLPurifier_LanguageFactory::instance()
|
|
||||||
# Printer_ConfigForm's get*() functions were static-ified
|
|
||||||
# %HTML.ForbiddenAttributes requires attribute declarations to be in the
|
|
||||||
form of tag@attr, NOT tag.attr (which will throw an error and won't do
|
|
||||||
anything). This is for forwards compatibility with XML; you'd do best
|
|
||||||
to migrate an %HTML.AllowedAttributes directives to this syntax too.
|
|
||||||
! Allow index to be false for config from form creation
|
|
||||||
! Added HTMLPurifier::VERSION constant
|
|
||||||
! Commas, not dashes, used for serializer IDs. This change is forwards-compatible
|
|
||||||
and allows for version numbers like "3.1.0-dev".
|
|
||||||
! %HTML.Allowed deals gracefully with whitespace anywhere, anytime!
|
|
||||||
! HTML Purifier's URI handling is a lot more robust, with much stricter
|
! HTML Purifier's URI handling is a lot more robust, with much stricter
|
||||||
validation checks and better percent encoding handling. Thanks Gareth Heyes
|
validation checks and better percent encoding handling.
|
||||||
for indicating security vulnerabilities from lax percent encoding.
|
- Colors missing # but in hex form will be corrected
|
||||||
! Bootstrap autoloader deals more robustly with classes that don't exist,
|
- CSS Number algorithm improved
|
||||||
preventing class_exists($class, true) from barfing.
|
|
||||||
- InterchangeBuilder now alphabetizes its lists
|
|
||||||
- Validation error in configdoc output fixed
|
|
||||||
- Iconv and other encoding errors muted even with custom error handlers that
|
|
||||||
do not honor error_reporting
|
|
||||||
- Add protection against imagecrash attack with CSS height/width
|
|
||||||
- HTMLPurifier::instance() created for consistency, is equivalent to getInstance()
|
|
||||||
- Fixed and revamped broken ConfigForm smoketest
|
|
||||||
- Bug with bool/null fields in Printer_ConfigForm fixed
|
|
||||||
- Bug with global forbidden attributes fixed
|
|
||||||
- Improved error messages for allowed and forbidden HTML elements and attributes
|
|
||||||
- Missing (or null) in configdoc documentation restored
|
|
||||||
- If DOM throws and exception during parsing with PH5P (occurs in newer versions
|
|
||||||
of DOM), HTML Purifier punts to DirectLex
|
|
||||||
- Fatal error with unserialization of ScriptRequired
|
|
||||||
- Created directories are now chmod'ed properly
|
|
||||||
- Fixed bug with fallback languages in LanguageFactory
|
|
||||||
- Standalone testing setup properly with autoload
|
|
||||||
. Out-of-date documentation revised
|
|
||||||
. UTF-8 encoding check optimization as suggested by Diego
|
|
||||||
. HTMLPurifier_Error removed in favor of exceptions
|
|
||||||
. More copy() function removed; should use clone instead
|
|
||||||
. More extensive unit tests for HTMLDefinition
|
|
||||||
. assertPurification moved to central harness
|
|
||||||
. HTMLPurifier_Generator accepts $config and $context parameters during
|
|
||||||
instantiation, not runtime
|
|
||||||
. Double-quotes outside of attribute values are now unescaped
|
|
||||||
|
|
||||||
3.1.0rc1, released 2008-04-22
|
|
||||||
# Autoload support added. Internal require_once's removed in favor of an
|
|
||||||
explicit require list or autoloading. To use HTML Purifier,
|
|
||||||
you must now either use HTMLPurifier.auto.php
|
|
||||||
or HTMLPurifier.includes.php; setting the include path and including
|
|
||||||
HTMLPurifier.php is insufficient--in such cases include HTMLPurifier.autoload.php
|
|
||||||
as well to register our autoload handler (or modify your autoload function
|
|
||||||
to check HTMLPurifier_Bootstrap::getPath($class)). You can also use
|
|
||||||
HTMLPurifier.safe-includes.php for a less performance friendly but more
|
|
||||||
user-friendly library load.
|
|
||||||
# HTMLPurifier_ConfigSchema static functions are officially deprecated. Schema
|
|
||||||
information is stored in the ConfigSchema directory, and the
|
|
||||||
maintenance/generate-schema-cache.php generates the schema.ser file, which
|
|
||||||
is now instantiated. Support for userland schema changes coming soon!
|
|
||||||
# HTMLPurifier_Config will now throw E_USER_NOTICE when you use a directive
|
|
||||||
alias; to get rid of these errors just modify your configuration to use
|
|
||||||
the new directive name.
|
|
||||||
# HTMLPurifier->addFilter is deprecated; built-in filters can now be
|
|
||||||
enabled using %Filter.$filter_name or by setting your own filters using
|
|
||||||
%Filter.Custom
|
|
||||||
# Directive-level safety properties superceded in favor of module-level
|
|
||||||
safety. Internal method HTMLModule->addElement() has changed, although
|
|
||||||
the externally visible HTMLDefinition->addElement has *not* changed.
|
|
||||||
! Extra utility classes for testing and non-library operations can
|
|
||||||
be found in extras/. Specifically, these are FSTools and ConfigDoc.
|
|
||||||
You may find a use for these in your own project, but right now they
|
|
||||||
are highly experimental and volatile.
|
|
||||||
! Integration with PHPT allows for automated smoketests
|
|
||||||
! Limited support for proprietary HTML elements, namely <marquee>, sponsored
|
|
||||||
by Chris. You can enable them with %HTML.Proprietary if your client
|
|
||||||
demands them.
|
|
||||||
! Support for !important CSS cascade modifier. By default, this will be stripped
|
|
||||||
from CSS, but you can enable it using %CSS.AllowImportant
|
|
||||||
! Support for display and visibility CSS properties added, set %CSS.AllowTricky
|
|
||||||
to true to use them.
|
|
||||||
! HTML Purifier now has its own Exception hierarchy under HTMLPurifier_Exception.
|
|
||||||
Developer error (not enduser error) can cause these to be triggered.
|
|
||||||
! Experimental kses() wrapper introduced with HTMLPurifier.kses.php
|
|
||||||
! Finally %CSS.AllowedProperties for tweaking allowed CSS properties without
|
|
||||||
mucking around with HTMLPurifier_CSSDefinition
|
|
||||||
! ConfigDoc output has been enhanced with version and deprecation info.
|
|
||||||
! %HTML.ForbiddenAttributes and %HTML.ForbiddenElements implemented.
|
|
||||||
- Autoclose now operates iteratively, i.e. <span><span><div> now has
|
- Autoclose now operates iteratively, i.e. <span><span><div> now has
|
||||||
both span tags closed.
|
both span tags closed.
|
||||||
- Various HTMLPurifier_Config convenience functions now accept another parameter
|
|
||||||
$schema which defines what HTMLPurifier_ConfigSchema to use besides the
|
|
||||||
global default.
|
|
||||||
- Fix bug with trusted script handling in libxml versions later than 2.6.28.
|
- Fix bug with trusted script handling in libxml versions later than 2.6.28.
|
||||||
- Fix bug in ExtractStyleBlocks with comments in style tags
|
- Fix bug in comment parsing with DirectLex
|
||||||
- Fix bug in comment parsing for DirectLex
|
|
||||||
- Flush output now displayed when in command line mode for unit tester
|
|
||||||
- Fix bug with rgb(0, 1, 2) color syntax with spaces inside shorthand syntax
|
- Fix bug with rgb(0, 1, 2) color syntax with spaces inside shorthand syntax
|
||||||
- HTMLPurifier_HTMLDefinition->addAttribute can now be called multiple times
|
- HTMLPurifier_HTMLDefinition->addAttribute can now be called multiple times
|
||||||
on the same element without emitting errors.
|
on the same element without emitting errors.
|
||||||
- Fixed fatal error in PH5P lexer with invalid tag names
|
- Iconv uses set_error_handler instead of shut-up operator
|
||||||
. Plugins now get their own changelogs according to project conventions.
|
- Add protection against imagecrash attack with CSS height/width
|
||||||
. Convert tokens to use instanceof, reducing memory footprint and
|
- HTMLPurifier::getInstance() renamed to HTMLPurifier::instance() for consistency
|
||||||
improving comparison speed.
|
- Fixed bug with fallback languages in LanguageFactory
|
||||||
. Dry runs now supported in SimpleTest; testing facilities improved
|
|
||||||
. Bootstrap class added for handling autoloading functionality
|
|
||||||
. Implemented recursive glob at FSTools->globr
|
|
||||||
. ConfigSchema now has instance methods for all corresponding define*
|
|
||||||
static methods.
|
|
||||||
. A couple of new historical maintenance scripts were added.
|
|
||||||
. HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php split into two files
|
|
||||||
. tests/index.php can now be run from any directory.
|
|
||||||
. HTMLPurifier_Token subclasses split into seperate files
|
|
||||||
. HTMLPURIFIER_PREFIX now is defined in Bootstrap.php, NOT HTMLPurifier.php
|
|
||||||
. HTMLPURIFIER_PREFIX can now be defined outside of HTML Purifier
|
|
||||||
. New --php=php flag added, allows PHP executable to be specified (command
|
|
||||||
line only!)
|
|
||||||
. htmlpurifier_add_test() preferred method to translate test files in to
|
|
||||||
classes, because it handles PHPT files too.
|
|
||||||
. Debugger class is deprecated and will be removed soon.
|
|
||||||
. Command line argument parsing for testing scripts revamped, now --opt value
|
|
||||||
format is supported.
|
|
||||||
. Smoketests now cleanup after magic quotes
|
|
||||||
. Generator now can output comments (however, comments are still stripped
|
|
||||||
from HTML Purifier output)
|
|
||||||
. HTMLPurifier_ConfigSchema->validate() deprecated in favor of
|
|
||||||
HTMLPurifier_VarParser->parse()
|
|
||||||
. Integers auto-cast into float type by VarParser.
|
|
||||||
. HTMLPURIFIER_STRICT removed; no validation is performed on runtime, only
|
|
||||||
during cache generation
|
|
||||||
. Reordered script calls in maintenance/flush.php
|
|
||||||
. Command line scripts now honor exit codes
|
|
||||||
. When --flush fails in unit testers, abort tests and print message
|
|
||||||
. Improved documentation in docs/dev-flush.html about the maintenance scripts
|
|
||||||
. copy() methods removed in favor of clone keyword
|
|
||||||
|
|
||||||
3.0.0, released 2008-01-06
|
|
||||||
# HTML Purifier is PHP 5 only! The 2.1.x branch will be maintained
|
|
||||||
until PHP 4 is completely deprecated, but no new features will be added
|
|
||||||
to it.
|
|
||||||
+ Visibility declarations added
|
|
||||||
+ Constructor methods renamed to __construct()
|
|
||||||
+ PHP4 reference cruft removed (in progress)
|
|
||||||
! CSS properties are now case-insensitive
|
|
||||||
! DefinitionCacheFactory now can register new implementations
|
|
||||||
! New HTMLPurifier_Filter_ExtractStyleBlocks for extracting <style> from
|
|
||||||
documents and cleaning their contents up. Requires the CSSTidy library
|
|
||||||
<http://csstidy.sourceforge.net/>. You can access the blocks with the
|
|
||||||
'StyleBlocks' Context variable ($purifier->context->get('StyleBlocks')).
|
|
||||||
The output CSS can also be "scoped" for a specific element, use:
|
|
||||||
%Filter.ExtractStyleBlocksScope
|
|
||||||
! Experimental support for some proprietary CSS attributes allowed:
|
|
||||||
opacity (and all of the browser-specific equivalents) and scrollbar colors.
|
|
||||||
Enable by setting %CSS.Proprietary to true.
|
|
||||||
- Colors missing # but in hex form will be corrected
|
|
||||||
- CSS Number algorithm improved
|
|
||||||
- Unit testing and multi-testing now on steroids: command lines,
|
|
||||||
XML output, and other goodies now added.
|
|
||||||
. Unit tests for Injector improved
|
|
||||||
. New classes:
|
|
||||||
+ HTMLPurifier_AttrDef_CSS_AlphaValue
|
|
||||||
+ HTMLPurifier_AttrDef_CSS_Filter
|
|
||||||
. Multitest now has a file docblock
|
|
||||||
|
|
||||||
2.1.3, released 2007-11-05
|
2.1.3, released 2007-11-05
|
||||||
! tests/multitest.php allows you to test multiple versions by running
|
! tests/multitest.php allows you to test multiple versions by running
|
||||||
|
109
TODO
109
TODO
@@ -7,122 +7,83 @@ TODO List
|
|||||||
? Maybe I'll Do It
|
? Maybe I'll Do It
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
If no interest is expressed for a feature that may require a considerable
|
If no interest is expressed for a feature that may required a considerable
|
||||||
amount of effort to implement, it may get endlessly delayed. Do not be
|
amount of effort to implement, it may get endlessly delayed. Do not be
|
||||||
afraid to cast your vote for the next feature to be implemented!
|
afraid to cast your vote for the next feature to be implemented!
|
||||||
|
|
||||||
- Investigate how early internal structures can be accessed; this would
|
2.2 release [Error'ed]
|
||||||
prevent structures from being parsed and serialized multiple times.
|
|
||||||
- Built-in support for target="_blank" on all external links
|
|
||||||
- Allow <a id="asdf" name="asdf">
|
|
||||||
- Implement overflow CSS property (as per jlp09550)
|
|
||||||
|
|
||||||
FUTURE VERSIONS
|
|
||||||
---------------
|
|
||||||
|
|
||||||
3.3 release [It's All About Trust] (floating)
|
|
||||||
# Implement untrusted, dangerous elements/attributes
|
|
||||||
# Implement IDREF support (harder than it seems, since you cannot have
|
|
||||||
IDREFs to non-existent IDs)
|
|
||||||
# Frameset XHTML 1.0 and HTML 4.01 doctypes
|
|
||||||
- Implement <area>
|
|
||||||
- Figure out how to simultaneously set %CSS.Trusted and %HTML.Trusted (?)
|
|
||||||
|
|
||||||
3.4 release [Error'ed]
|
|
||||||
# Error logging for filtering/cleanup procedures
|
# Error logging for filtering/cleanup procedures
|
||||||
- XSS-attempt detection--certain errors are flagged XSS-like
|
- XSS-attempt detection
|
||||||
|
|
||||||
3.5 release [Do What I Mean, Not What I Say]
|
2.3 release [Do What I Mean, Not What I Say]
|
||||||
# Additional support for poorly written HTML
|
# Additional support for poorly written HTML
|
||||||
- Microsoft Word HTML cleaning (i.e. MsoNormal, but research essential!)
|
- Microsoft Word HTML cleaning (i.e. MsoNormal, but research essential!)
|
||||||
- Friendly strict handling of <address> (block -> <br>)
|
- Friendly strict handling of <address> (block -> <br>)
|
||||||
? Remove redundant tags, ex. <u><u>Underlined</u></u>. Implementation notes:
|
- Remove redundant tags, ex. <u><u>Underlined</u></u>. Implementation notes:
|
||||||
1. Analyzing which tags to remove duplicants
|
1. Analyzing which tags to remove duplicants
|
||||||
2. Ensure attributes are merged into the parent tag
|
2. Ensure attributes are merged into the parent tag
|
||||||
3. Extend the tag exclusion system to specify whether or not the
|
3. Extend the tag exclusion system to specify whether or not the
|
||||||
contents should be dropped or not (currently, there's code that could do
|
contents should be dropped or not (currently, there's code that could do
|
||||||
something like this if it didn't drop the inner text too.)
|
something like this if it didn't drop the inner text too.)
|
||||||
- Remove <span> tags that don't do anything (no attributes)
|
- Remove <span> tags that don't do anything (no attributes)
|
||||||
|
- Remove empty inline tags<i></i>
|
||||||
- Append something to duplicate IDs so they're still usable (impl. note: the
|
- Append something to duplicate IDs so they're still usable (impl. note: the
|
||||||
dupe detector would also need to detect the suffix as well)
|
dupe detector would also need to detect the suffix as well)
|
||||||
- Externalize inline CSS to promote clean HTML, proposed by Sander Tekelenburg
|
- Externalize inline CSS to promote clean HTML
|
||||||
|
|
||||||
4.0 release [Beyond HTML]
|
2.4 release [It's All About Trust] (floating)
|
||||||
|
# Implement untrusted, dangerous elements/attributes
|
||||||
|
# Implement IDREF support (harder than it seems, since you cannot have
|
||||||
|
IDREFs to non-existent IDs)
|
||||||
|
# Frameset XHTML 1.0 and HTML 4.01 doctypes
|
||||||
|
|
||||||
|
3.0 release [Beyond HTML]
|
||||||
# Legit token based CSS parsing (will require revamping almost every
|
# Legit token based CSS parsing (will require revamping almost every
|
||||||
AttrDef class). Probably will use CSSTidy class?
|
AttrDef class). Probably will use CSSTidy class
|
||||||
# More control over allowed CSS properties using a modularization
|
# More control over allowed CSS properties (maybe modularize it in the
|
||||||
# HTML 5 support
|
same fashion!)
|
||||||
# IRI support (this includes IDN)
|
# Formatters for plaintext
|
||||||
|
- Smileys
|
||||||
- Standardize token armor for all areas of processing
|
- Standardize token armor for all areas of processing
|
||||||
- Convert RTL/LTR override characters to <bdo> tags, or vice versa on demand.
|
- Convert RTL/LTR override characters to <bdo> tags, or vice versa on demand.
|
||||||
Also, enable disabling of directionality
|
Also, enable disabling of directionality
|
||||||
|
|
||||||
5.0 release [To XML and Beyond]
|
4.0 release [To XML and Beyond]
|
||||||
- Extended HTML capabilities based on namespacing and tag transforms (COMPLEX)
|
- Extended HTML capabilities based on namespacing and tag transforms (COMPLEX)
|
||||||
- Hooks for adding custom processors to custom namespaced tags and
|
- Hooks for adding custom processors to custom namespaced tags and
|
||||||
attributes, offer default implementation
|
attributes, offer default implementation
|
||||||
- Lots of documentation and samples
|
- Lots of documentation and samples
|
||||||
|
|
||||||
Ongoing
|
Ongoing
|
||||||
- More refactoring to take advantage of PHP5's facilities
|
- Lots of profiling, make it faster!
|
||||||
- Refactor unit tests into lots of test methods
|
|
||||||
- Plugins for major CMSes (COMPLEX)
|
- Plugins for major CMSes (COMPLEX)
|
||||||
- phpBB
|
- phpBB
|
||||||
- Drupal needs loving!
|
- eFiction
|
||||||
- Phorum need loving!
|
|
||||||
- more! (look for ones that use WYSIWYGs)
|
- more! (look for ones that use WYSIWYGs)
|
||||||
- Also, maybe a FAQ for extension writers with HTML Purifier
|
- Complete basic smoketests
|
||||||
|
|
||||||
AutoFormat
|
Unknown release (on a scratch-an-itch basis)
|
||||||
- Smileys
|
# CHMOD install script for PEAR installs
|
||||||
- Syntax highlighting (with GeSHi) with <pre> and possibly <?php
|
? Have 'lang' attribute be checked against official lists, achieved by
|
||||||
- Look at http://drupal.org/project/Modules/category/63 for ideas
|
encoding all characters that have string entity equivalents
|
||||||
|
- Abstract ChildDef_BlockQuote to work with all elements that only
|
||||||
Optimizations
|
allow blocks in them, required or optional
|
||||||
- Reduce size of internal data-structures (esp. HTMLDefinition)
|
- Reorganize Unit Tests
|
||||||
- Research memory usage of objects versus arrays
|
- Reorganize configuration directives (Create more namespaces! Get messy!)
|
||||||
- Combine multiple strategies into a single, single-pass strategy
|
|
||||||
- Get PH5P working with the latest versions of DOM, which have much more
|
|
||||||
stringent error checking procedures. Maybe convert straight to tokens.
|
|
||||||
- Get rid of set_include_path(). Save this for another major release.
|
|
||||||
|
|
||||||
Neat feature related
|
|
||||||
! Factor demo.php into a set of Printer classes, and then create a stub
|
|
||||||
file for users here (inside the actual HTML Purifier library)
|
|
||||||
! Support exporting configuration, so users can easily tweak settings
|
|
||||||
in the demo, and then copy-paste into their own setup
|
|
||||||
- Advanced URI filtering schemes (see docs/proposal-new-directives.txt)
|
- Advanced URI filtering schemes (see docs/proposal-new-directives.txt)
|
||||||
- Allow scoped="scoped" attribute in <style> tags; may be troublesome
|
- Implement lenient <ruby> child validation
|
||||||
because regular CSS has no way of uniquely identifying nodes, so we'd
|
|
||||||
have to generate IDs
|
|
||||||
- Explain how to use HTML Purifier in non-PHP languages / create
|
- Explain how to use HTML Purifier in non-PHP languages / create
|
||||||
a simple command line stub (or complicated?)
|
a simple command line stub (or complicated?)
|
||||||
- Fixes for Firefox's inability to handle COL alignment props (Bug 915)
|
- Fixes for Firefox's inability to handle COL alignment props (Bug 915)
|
||||||
- Automatically add non-breaking spaces to empty table cells when
|
- Automatically add non-breaking spaces to empty table cells when
|
||||||
empty-cells:show is applied to have compatibility with Internet Explorer
|
empty-cells:show is applied to have compatibility with Internet Explorer
|
||||||
- Table of Contents generation (XHTML Compiler might be reusable). May also
|
|
||||||
be out-of-band information.
|
|
||||||
- Full set of color keywords. Also, a way to add onto them without
|
|
||||||
finalizing the configuration object.
|
|
||||||
- Write a var_export and memcached DefinitionCache - Denis
|
|
||||||
- Allow restriction of allowed class values
|
|
||||||
|
|
||||||
Maintenance related (slightly boring)
|
Requested
|
||||||
# CHMOD install script for PEAR installs
|
|
||||||
! Factor out command line parser into its own class, and unit test it
|
|
||||||
! Nested configuration namespaces
|
|
||||||
- Distinguish between default settings and explicitly set settings, so
|
|
||||||
configurations can be merged
|
|
||||||
- Time PHPT tests
|
|
||||||
|
|
||||||
ChildDef related (very boring)
|
|
||||||
- Abstract ChildDef_BlockQuote to work with all elements that only
|
|
||||||
allow blocks in them, required or optional
|
|
||||||
- Implement lenient <ruby> child validation
|
|
||||||
|
|
||||||
Wontfix
|
Wontfix
|
||||||
- Non-lossy smart alternate character encoding transformations (unless
|
- Non-lossy smart alternate character encoding transformations (unless
|
||||||
patch provided)
|
patch provided)
|
||||||
- Pretty-printing HTML: users can use Tidy on the output on entire page
|
- Pretty-printing HTML: users can use Tidy on the output on entire page
|
||||||
- Native content compression, whitespace stripping: use gzip if this is
|
- Native content compression, whitespace stripping (don't rely on Tidy, make
|
||||||
|
sure we don't remove from <pre> or related tags): use gzip if this is
|
||||||
really important
|
really important
|
||||||
|
13
WHATSNEW
13
WHATSNEW
@@ -1,6 +1,7 @@
|
|||||||
HTML Purifier 3.2.0 is an amalgamation of new features and fixes that
|
Security and bugfix release 2.1.5 is a backport that fixes two vulnerabilities
|
||||||
have accumulated over a four month period. Some notable features
|
related to CSS, one of which only occurs under Shift_JIS. It also improves
|
||||||
include %AutoFormat.RemoveEmpty, column tracking for tokens,
|
imagecrash protection (percent CSS width and height is now disabled for
|
||||||
%AutoFormat.DisplayLinkURI and %Attr.DefaultImageAlt. There were also
|
images, and you can control the bounds with %CSS.MaxImgLength and
|
||||||
major improvements to the test suite interface, error collection output
|
%HTML.MaxImgLength). Finally, there are number of bug fixes, most notably
|
||||||
and the auto-formatter framework.
|
support for text-decoration: none, improved adherence to Unicode and increased
|
||||||
|
percent encoding checks.
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
chdir(dirname(__FILE__));
|
|
||||||
|
|
||||||
//require_once '../library/HTMLPurifier.path.php';
|
|
||||||
shell_exec('php ../maintenance/generate-schema-cache.php');
|
|
||||||
require_once '../library/HTMLPurifier.path.php';
|
|
||||||
require_once 'HTMLPurifier.includes.php';
|
|
||||||
|
|
||||||
$begin = xdebug_memory_usage();
|
|
||||||
|
|
||||||
$schema = HTMLPurifier_ConfigSchema::makeFromSerial();
|
|
||||||
|
|
||||||
echo xdebug_memory_usage() - $begin;
|
|
@@ -1,11 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once '../library/HTMLPurifier.auto.php';
|
// emulates inserting a dir called HTMLPurifier into your class dir
|
||||||
|
set_include_path(get_include_path() . PATH_SEPARATOR . '../library/');
|
||||||
|
|
||||||
@include_once '../test-settings.php';
|
@include_once '../test-settings.php';
|
||||||
|
|
||||||
// PEAR
|
require_once 'HTMLPurifier/ConfigSchema.php';
|
||||||
require_once 'Benchmark/Timer.php'; // to do the timing
|
require_once 'HTMLPurifier/Config.php';
|
||||||
require_once 'Text/Password.php'; // for generating random input
|
require_once 'HTMLPurifier/Context.php';
|
||||||
|
|
||||||
$LEXERS = array();
|
$LEXERS = array();
|
||||||
$RUNS = isset($GLOBALS['HTMLPurifierTest']['Runs'])
|
$RUNS = isset($GLOBALS['HTMLPurifierTest']['Runs'])
|
||||||
@@ -14,11 +16,22 @@ $RUNS = isset($GLOBALS['HTMLPurifierTest']['Runs'])
|
|||||||
require_once 'HTMLPurifier/Lexer/DirectLex.php';
|
require_once 'HTMLPurifier/Lexer/DirectLex.php';
|
||||||
$LEXERS['DirectLex'] = new HTMLPurifier_Lexer_DirectLex();
|
$LEXERS['DirectLex'] = new HTMLPurifier_Lexer_DirectLex();
|
||||||
|
|
||||||
|
if (!empty($GLOBALS['HTMLPurifierTest']['PEAR'])) {
|
||||||
|
require_once 'HTMLPurifier/Lexer/PEARSax3.php';
|
||||||
|
$LEXERS['PEARSax3'] = new HTMLPurifier_Lexer_PEARSax3();
|
||||||
|
} else {
|
||||||
|
exit('PEAR required to perform benchmark.');
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '5', '>=')) {
|
if (version_compare(PHP_VERSION, '5', '>=')) {
|
||||||
require_once 'HTMLPurifier/Lexer/DOMLex.php';
|
require_once 'HTMLPurifier/Lexer/DOMLex.php';
|
||||||
$LEXERS['DOMLex'] = new HTMLPurifier_Lexer_DOMLex();
|
$LEXERS['DOMLex'] = new HTMLPurifier_Lexer_DOMLex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PEAR
|
||||||
|
require_once 'Benchmark/Timer.php'; // to do the timing
|
||||||
|
require_once 'Text/Password.php'; // for generating random input
|
||||||
|
|
||||||
// custom class to aid unit testing
|
// custom class to aid unit testing
|
||||||
class RowTimer extends Benchmark_Timer
|
class RowTimer extends Benchmark_Timer
|
||||||
{
|
{
|
||||||
|
17
benchmarks/ProfileDirectLex.php
Normal file
17
benchmarks/ProfileDirectLex.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
set_include_path(get_include_path() . PATH_SEPARATOR . '../library/');
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/ConfigSchema.php';
|
||||||
|
require_once 'HTMLPurifier/Config.php';
|
||||||
|
require_once 'HTMLPurifier/Lexer/DirectLex.php';
|
||||||
|
require_once 'HTMLPurifier/Context.php';
|
||||||
|
|
||||||
|
$input = file_get_contents('samples/Lexer/4.html');
|
||||||
|
$lexer = new HTMLPurifier_Lexer_DirectLex();
|
||||||
|
$config = HTMLPurifier_Config::createDefault();
|
||||||
|
$context = new HTMLPurifier_Context();
|
||||||
|
|
||||||
|
for ($i = 0; $i < 10; $i++) {
|
||||||
|
$tokens = $lexer->tokenizeHTML($input, $config, $context);
|
||||||
|
}
|
@@ -3,11 +3,6 @@
|
|||||||
ini_set('xdebug.trace_format', 1);
|
ini_set('xdebug.trace_format', 1);
|
||||||
ini_set('xdebug.show_mem_delta', true);
|
ini_set('xdebug.show_mem_delta', true);
|
||||||
|
|
||||||
if (file_exists('Trace.xt')) {
|
|
||||||
echo "Previous trace Trace.xt must be removed before this script can be run.";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
xdebug_start_trace(dirname(__FILE__) . '/Trace');
|
xdebug_start_trace(dirname(__FILE__) . '/Trace');
|
||||||
require_once '../library/HTMLPurifier.auto.php';
|
require_once '../library/HTMLPurifier.auto.php';
|
||||||
|
|
||||||
@@ -15,5 +10,3 @@ $purifier = new HTMLPurifier();
|
|||||||
|
|
||||||
$data = $purifier->purify(file_get_contents('samples/Lexer/4.html'));
|
$data = $purifier->purify(file_get_contents('samples/Lexer/4.html'));
|
||||||
xdebug_stop_trace();
|
xdebug_stop_trace();
|
||||||
|
|
||||||
echo "Trace finished.";
|
|
||||||
|
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates XML and HTML documents describing configuration.
|
* Generates XML and HTML documents describing configuration.
|
||||||
* @note PHP 5.2+ only!
|
* @note PHP 5 only!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
- make XML format richer
|
- make XML format richer (see XMLSerializer_ConfigSchema)
|
||||||
- extend XSLT transformation (see the corresponding XSLT file)
|
- extend XSLT transformation (see the corresponding XSLT file)
|
||||||
- allow generation of packaged docs that can be easily moved
|
- allow generation of packaged docs that can be easily moved
|
||||||
- multipage documentation
|
- multipage documentation
|
||||||
@@ -15,45 +15,29 @@ TODO:
|
|||||||
- add blurbs to ToC
|
- add blurbs to ToC
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '5.2', '<')) exit('PHP 5.2+ required.');
|
if (version_compare('5', PHP_VERSION, '>')) exit('Requires PHP 5 or higher.');
|
||||||
error_reporting(E_ALL | E_STRICT);
|
error_reporting(E_ALL); // probably not possible to use E_STRICT
|
||||||
|
|
||||||
chdir(dirname(__FILE__));
|
define('HTMLPURIFIER_SCHEMA_STRICT', true); // description data needs to be collected
|
||||||
|
|
||||||
// load dual-libraries
|
// load dual-libraries
|
||||||
require_once '../extras/HTMLPurifierExtras.auto.php';
|
|
||||||
require_once '../library/HTMLPurifier.auto.php';
|
require_once '../library/HTMLPurifier.auto.php';
|
||||||
|
require_once 'library/ConfigDoc.auto.php';
|
||||||
|
|
||||||
// setup HTML Purifier singleton
|
$purifier = HTMLPurifier::getInstance(array(
|
||||||
HTMLPurifier::getInstance(array(
|
|
||||||
'AutoFormat.PurifierLinkify' => true
|
'AutoFormat.PurifierLinkify' => true
|
||||||
));
|
));
|
||||||
|
|
||||||
$interchange = HTMLPurifier_ConfigSchema_InterchangeBuilder::buildFromDirectory();
|
$schema = HTMLPurifier_ConfigSchema::instance();
|
||||||
$interchange->validate();
|
$style = 'plain'; // use $_GET in the future
|
||||||
|
$configdoc = new ConfigDoc();
|
||||||
$style = 'plain'; // use $_GET in the future, careful to validate!
|
$output = $configdoc->generate($schema, $style);
|
||||||
$configdoc_xml = 'configdoc.xml';
|
|
||||||
|
|
||||||
$xml_builder = new HTMLPurifier_ConfigSchema_Builder_Xml();
|
|
||||||
$xml_builder->openURI($configdoc_xml);
|
|
||||||
$xml_builder->build($interchange);
|
|
||||||
unset($xml_builder); // free handle
|
|
||||||
|
|
||||||
$xslt = new ConfigDoc_HTMLXSLTProcessor();
|
|
||||||
$xslt->importStylesheet(dirname(__FILE__) . "/styles/$style.xsl");
|
|
||||||
$output = $xslt->transformToHTML($configdoc_xml);
|
|
||||||
|
|
||||||
if (!$output) {
|
|
||||||
echo "Error in generating files\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write out
|
// write out
|
||||||
file_put_contents("$style.html", $output);
|
file_put_contents("$style.html", $output);
|
||||||
|
|
||||||
if (php_sapi_name() != 'cli') {
|
if (php_sapi_name() != 'cli') {
|
||||||
// output (instant feedback if it's a browser)
|
// output = instant feedback
|
||||||
echo $output;
|
echo $output;
|
||||||
} else {
|
} else {
|
||||||
echo 'Files generated successfully.';
|
echo 'Files generated successfully.';
|
||||||
|
@@ -5,5 +5,5 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||||
require_once 'HTMLPurifierExtras.php';
|
require_once 'ConfigDoc.php';
|
||||||
require_once 'HTMLPurifierExtras.autoload.php';
|
|
38
configdoc/library/ConfigDoc.php
Normal file
38
configdoc/library/ConfigDoc.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'ConfigDoc/HTMLXSLTProcessor.php';
|
||||||
|
require_once 'ConfigDoc/XMLSerializer/Types.php';
|
||||||
|
require_once 'ConfigDoc/XMLSerializer/ConfigSchema.php';
|
||||||
|
|
||||||
|
class ConfigDoc
|
||||||
|
{
|
||||||
|
|
||||||
|
function generate($schema, $xsl_stylesheet_name = 'plain', $parameters = array()) {
|
||||||
|
// generate types document, describing type constraints
|
||||||
|
$types_serializer = new ConfigDoc_XMLSerializer_Types();
|
||||||
|
$types_document = $types_serializer->serialize($schema);
|
||||||
|
$types_document->save(dirname(__FILE__) . '/../types.xml'); // only ONE
|
||||||
|
|
||||||
|
// generate configdoc.xml, documents configuration directives
|
||||||
|
$schema_serializer = new ConfigDoc_XMLSerializer_ConfigSchema();
|
||||||
|
$schema_document = $schema_serializer->serialize($schema);
|
||||||
|
$schema_document->save('configdoc.xml');
|
||||||
|
|
||||||
|
// setup transformation
|
||||||
|
$xsl_stylesheet = dirname(__FILE__) . "/../styles/$xsl_stylesheet_name.xsl";
|
||||||
|
$xslt_processor = new ConfigDoc_HTMLXSLTProcessor();
|
||||||
|
$xslt_processor->setParameters($parameters);
|
||||||
|
$xslt_processor->importStylesheet($xsl_stylesheet);
|
||||||
|
|
||||||
|
return $xslt_processor->transformToHTML($schema_document);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove any generated files
|
||||||
|
*/
|
||||||
|
function cleanup() {
|
||||||
|
unlink('configdoc.xml');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -1,23 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorator/extender XSLT processor specifically for HTML documents.
|
* Special XSLTProcessor specifically for HTML documents. Loosely
|
||||||
|
* based off of XSLTProcessor, but not really
|
||||||
*/
|
*/
|
||||||
class ConfigDoc_HTMLXSLTProcessor
|
class ConfigDoc_HTMLXSLTProcessor
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* Instance of XSLTProcessor
|
|
||||||
*/
|
|
||||||
protected $xsltProcessor;
|
protected $xsltProcessor;
|
||||||
|
|
||||||
public function __construct($proc = false) {
|
public function __construct() {
|
||||||
if ($proc === false) $proc = new XSLTProcessor();
|
$this->xsltProcessor = new XSLTProcessor();
|
||||||
$this->xsltProcessor = $proc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note Allows a string $xsl filename to be passed
|
* Imports stylesheet for processor to use
|
||||||
|
* @param $xsl XSLT DOM tree, or filename of the XSL transformation
|
||||||
*/
|
*/
|
||||||
public function importStylesheet($xsl) {
|
public function importStylesheet($xsl) {
|
||||||
if (is_string($xsl)) {
|
if (is_string($xsl)) {
|
||||||
@@ -29,25 +27,16 @@ class ConfigDoc_HTMLXSLTProcessor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms an XML file into compatible XHTML based on the stylesheet
|
* Transforms an XML file into HTML based on the stylesheet
|
||||||
* @param $xml XML DOM tree, or string filename
|
* @param $xml XML DOM tree
|
||||||
* @return string HTML output
|
|
||||||
* @todo Rename to transformToXHTML, as transformToHTML is misleading
|
|
||||||
*/
|
*/
|
||||||
public function transformToHTML($xml) {
|
public function transformToHTML($xml) {
|
||||||
if (is_string($xml)) {
|
$out = $this->xsltProcessor->transformToXML($xml);
|
||||||
$dom = new DOMDocument();
|
|
||||||
$dom->load($xml);
|
|
||||||
} else {
|
|
||||||
$dom = $xml;
|
|
||||||
}
|
|
||||||
$out = $this->xsltProcessor->transformToXML($dom);
|
|
||||||
|
|
||||||
// fudges for HTML backwards compatibility
|
// fudges for HTML backwards compatibility
|
||||||
// assumes that document is XHTML
|
|
||||||
$out = str_replace('/>', ' />', $out); // <br /> not <br/>
|
$out = str_replace('/>', ' />', $out); // <br /> not <br/>
|
||||||
$out = str_replace(' xmlns=""', '', $out); // rm unnecessary xmlns
|
$out = str_replace(' xmlns=""', '', $out); // rm unnecessary xmlns
|
||||||
|
$out = str_replace(' xmlns="http://www.w3.org/1999/xhtml"', '', $out); // rm unnecessary xmlns
|
||||||
if (class_exists('Tidy')) {
|
if (class_exists('Tidy')) {
|
||||||
// cleanup output
|
// cleanup output
|
||||||
$config = array(
|
$config = array(
|
||||||
@@ -60,26 +49,14 @@ class ConfigDoc_HTMLXSLTProcessor
|
|||||||
$tidy->cleanRepair();
|
$tidy->cleanRepair();
|
||||||
$out = (string) $tidy;
|
$out = (string) $tidy;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) {
|
foreach ($options as $name => $value) {
|
||||||
$this->xsltProcessor->setParameter('', $name, $value);
|
$this->xsltProcessor->setParameter('', $name, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Forward any other calls to the XSLT processor
|
|
||||||
*/
|
|
||||||
public function __call($name, $arguments) {
|
|
||||||
call_user_func_array(array($this->xsltProcessor, $name), $arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
25
configdoc/library/ConfigDoc/XMLSerializer.php
Normal file
25
configdoc/library/ConfigDoc/XMLSerializer.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XMLSerializer hierarchy of classes consist of classes that take
|
||||||
|
* objects and serialize them into XML, specifically DOM, form; this
|
||||||
|
* super-class contains convenience functions for those classes.
|
||||||
|
*/
|
||||||
|
class ConfigDoc_XMLSerializer
|
||||||
|
{
|
||||||
|
|
||||||
|
protected function appendHTMLDiv($document, $node, $html) {
|
||||||
|
$purifier = HTMLPurifier::getInstance();
|
||||||
|
$html = $purifier->purify($html);
|
||||||
|
$dom_html = $document->createDocumentFragment();
|
||||||
|
$dom_html->appendXML($html);
|
||||||
|
|
||||||
|
$dom_div = $document->createElement('div');
|
||||||
|
$dom_div->setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
|
||||||
|
$dom_div->appendChild($dom_html);
|
||||||
|
|
||||||
|
$node->appendChild($dom_div);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
123
configdoc/library/ConfigDoc/XMLSerializer/ConfigSchema.php
Normal file
123
configdoc/library/ConfigDoc/XMLSerializer/ConfigSchema.php
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'ConfigDoc/XMLSerializer.php';
|
||||||
|
|
||||||
|
class ConfigDoc_XMLSerializer_ConfigSchema extends ConfigDoc_XMLSerializer
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a schema into DOM form
|
||||||
|
* @todo Split into sub-serializers
|
||||||
|
* @param $schema HTMLPurifier_ConfigSchema to serialize
|
||||||
|
*/
|
||||||
|
public function serialize($schema) {
|
||||||
|
$dom_document = new DOMDocument('1.0', 'UTF-8');
|
||||||
|
$dom_root = $dom_document->createElement('configdoc');
|
||||||
|
$dom_document->appendChild($dom_root);
|
||||||
|
$dom_document->formatOutput = true;
|
||||||
|
|
||||||
|
// add the name of the application
|
||||||
|
$dom_root->appendChild($dom_document->createElement('title', 'HTML Purifier'));
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO for XML format:
|
||||||
|
- create a definition (DTD or other) once interface stabilizes
|
||||||
|
*/
|
||||||
|
|
||||||
|
foreach($schema->info as $namespace_name => $namespace_info) {
|
||||||
|
|
||||||
|
$dom_namespace = $dom_document->createElement('namespace');
|
||||||
|
$dom_root->appendChild($dom_namespace);
|
||||||
|
|
||||||
|
$dom_namespace->setAttribute('id', $namespace_name);
|
||||||
|
$dom_namespace->appendChild(
|
||||||
|
$dom_document->createElement('name', $namespace_name)
|
||||||
|
);
|
||||||
|
$dom_namespace_description = $dom_document->createElement('description');
|
||||||
|
$dom_namespace->appendChild($dom_namespace_description);
|
||||||
|
$this->appendHTMLDiv($dom_document, $dom_namespace_description,
|
||||||
|
$schema->info_namespace[$namespace_name]->description);
|
||||||
|
|
||||||
|
foreach ($namespace_info as $name => $info) {
|
||||||
|
|
||||||
|
if ($info->class == 'alias') continue;
|
||||||
|
|
||||||
|
$dom_directive = $dom_document->createElement('directive');
|
||||||
|
$dom_namespace->appendChild($dom_directive);
|
||||||
|
|
||||||
|
$dom_directive->setAttribute('id', $namespace_name . '.' . $name);
|
||||||
|
$dom_directive->appendChild(
|
||||||
|
$dom_document->createElement('name', $name)
|
||||||
|
);
|
||||||
|
|
||||||
|
$dom_aliases = $dom_document->createElement('aliases');
|
||||||
|
$dom_directive->appendChild($dom_aliases);
|
||||||
|
foreach ($info->directiveAliases as $alias) {
|
||||||
|
$dom_aliases->appendChild($dom_document->createElement('alias', $alias));
|
||||||
|
}
|
||||||
|
|
||||||
|
$dom_constraints = $dom_document->createElement('constraints');
|
||||||
|
$dom_directive->appendChild($dom_constraints);
|
||||||
|
|
||||||
|
$dom_type = $dom_document->createElement('type', $info->type);
|
||||||
|
if ($info->allow_null) {
|
||||||
|
$dom_type->setAttribute('allow-null', 'yes');
|
||||||
|
}
|
||||||
|
$dom_constraints->appendChild($dom_type);
|
||||||
|
|
||||||
|
if ($info->allowed !== true) {
|
||||||
|
$dom_allowed = $dom_document->createElement('allowed');
|
||||||
|
$dom_constraints->appendChild($dom_allowed);
|
||||||
|
foreach ($info->allowed as $allowed => $bool) {
|
||||||
|
$dom_allowed->appendChild(
|
||||||
|
$dom_document->createElement('value', $allowed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw_default = $schema->defaults[$namespace_name][$name];
|
||||||
|
if (is_bool($raw_default)) {
|
||||||
|
$default = $raw_default ? 'true' : 'false';
|
||||||
|
} elseif (is_string($raw_default)) {
|
||||||
|
$default = "\"$raw_default\"";
|
||||||
|
} elseif (is_null($raw_default)) {
|
||||||
|
$default = 'null';
|
||||||
|
} else {
|
||||||
|
$default = print_r(
|
||||||
|
$schema->defaults[$namespace_name][$name], true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dom_default = $dom_document->createElement('default', $default);
|
||||||
|
|
||||||
|
// remove this once we get a DTD
|
||||||
|
$dom_default->setAttribute('xml:space', 'preserve');
|
||||||
|
|
||||||
|
$dom_constraints->appendChild($dom_default);
|
||||||
|
|
||||||
|
$dom_descriptions = $dom_document->createElement('descriptions');
|
||||||
|
$dom_directive->appendChild($dom_descriptions);
|
||||||
|
|
||||||
|
foreach ($info->descriptions as $file => $file_descriptions) {
|
||||||
|
foreach ($file_descriptions as $line => $description) {
|
||||||
|
$dom_description = $dom_document->createElement('description');
|
||||||
|
// refuse to write $file if it's a full path
|
||||||
|
if (str_replace('\\', '/', realpath($file)) != $file) {
|
||||||
|
$dom_description->setAttribute('file', $file);
|
||||||
|
$dom_description->setAttribute('line', $line);
|
||||||
|
}
|
||||||
|
$this->appendHTMLDiv($dom_document, $dom_description, $description);
|
||||||
|
$dom_descriptions->appendChild($dom_description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dom_document;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
26
configdoc/library/ConfigDoc/XMLSerializer/Types.php
Normal file
26
configdoc/library/ConfigDoc/XMLSerializer/Types.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'ConfigDoc/XMLSerializer.php';
|
||||||
|
|
||||||
|
class ConfigDoc_XMLSerializer_Types extends ConfigDoc_XMLSerializer
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the types in a schema into DOM form
|
||||||
|
* @param $schema HTMLPurifier_ConfigSchema owner of types to serialize
|
||||||
|
*/
|
||||||
|
public function serialize($schema) {
|
||||||
|
$types_document = new DOMDocument('1.0', 'UTF-8');
|
||||||
|
$types_root = $types_document->createElement('types');
|
||||||
|
$types_document->appendChild($types_root);
|
||||||
|
$types_document->formatOutput = true;
|
||||||
|
foreach ($schema->types as $name => $expanded_name) {
|
||||||
|
$types_type = $types_document->createElement('type', $expanded_name);
|
||||||
|
$types_type->setAttribute('id', $name);
|
||||||
|
$types_root->appendChild($types_type);
|
||||||
|
}
|
||||||
|
return $types_document;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -1,30 +1,16 @@
|
|||||||
|
|
||||||
body {margin:0;padding:0;}
|
body {margin:1em 4em;}
|
||||||
#content {
|
|
||||||
margin:1em auto;
|
|
||||||
max-width: 47em;
|
|
||||||
width: expression(document.body.clientWidth >
|
|
||||||
85 * parseInt(document.body.currentStyle.fontSize) ?
|
|
||||||
"54em": "auto");
|
|
||||||
}
|
|
||||||
|
|
||||||
table {border-collapse:collapse;}
|
table {border-collapse:collapse;}
|
||||||
table td, table th {padding:0.2em;}
|
table td, table th {padding:0.2em;}
|
||||||
|
|
||||||
table.constraints {margin:0 0 1em;}
|
table.constraints {margin:0 0 1em;}
|
||||||
table.constraints th {
|
table.constraints th {text-align:left;padding-left:0.4em;}
|
||||||
text-align:right;padding-left:0.4em;padding-right:0.4em;background:#EEE;
|
table.constraints td {padding-right:0.4em;}
|
||||||
width:8em;vertical-align:top;}
|
|
||||||
table.constraints td {padding-right:0.4em; padding-left: 1em;}
|
|
||||||
table.constraints td ul {padding:0; margin:0; list-style:none;}
|
|
||||||
table.constraints td pre {margin:0;}
|
table.constraints td pre {margin:0;}
|
||||||
|
|
||||||
#tocContainer {position:relative;}
|
#toc {list-style-type:none; font-weight:bold;}
|
||||||
#toc {list-style-type:none; font-weight:bold; font-size:1em; margin-bottom:1em;}
|
#toc ul {list-style-type:disc; font-weight:normal;}
|
||||||
#toc li {position:relative; line-height: 1.2em;}
|
|
||||||
#toc .col-2 {margin-left:50%;}
|
|
||||||
#toc .col-l {float:left;}
|
|
||||||
#toc ul {list-style-type:disc; font-weight:normal; padding-bottom:1.2em;}
|
|
||||||
|
|
||||||
.description p {margin-top:0;margin-bottom:1em;}
|
.description p {margin-top:0;margin-bottom:1em;}
|
||||||
|
|
||||||
@@ -33,10 +19,6 @@ table.constraints td pre {margin:0;}
|
|||||||
#library {font-size:1em;}
|
#library {font-size:1em;}
|
||||||
h1 {margin-top:0;}
|
h1 {margin-top:0;}
|
||||||
h2 {border-bottom:1px solid #CCC; font-family:sans-serif; font-weight:normal;
|
h2 {border-bottom:1px solid #CCC; font-family:sans-serif; font-weight:normal;
|
||||||
font-size:1.3em; clear:both;}
|
font-size:1.3em;}
|
||||||
h3 {font-family:sans-serif; font-size:1.1em; font-weight:bold; }
|
h3 {font-family:sans-serif; font-size:1.1em; font-weight:bold; }
|
||||||
h4 {font-family:sans-serif; font-size:0.9em; font-weight:bold; }
|
h4 {font-family:sans-serif; font-size:0.9em; font-weight:bold; }
|
||||||
|
|
||||||
.deprecated {color: #CCC;}
|
|
||||||
.deprecated table.constraints th {background:#FFF;}
|
|
||||||
.deprecated-notice {color: #000; text-align:center; margin-bottom: 1em;}
|
|
||||||
|
@@ -15,11 +15,7 @@
|
|||||||
<xsl:param name="css" select="'styles/plain.css'"/>
|
<xsl:param name="css" select="'styles/plain.css'"/>
|
||||||
<xsl:param name="title" select="'Configuration Documentation'"/>
|
<xsl:param name="title" select="'Configuration Documentation'"/>
|
||||||
|
|
||||||
<xsl:variable name="typeLookup" select="document('../types.xml')/types" />
|
<xsl:variable name="typeLookup" select="document('../types.xml')" />
|
||||||
<xsl:variable name="usageLookup" select="document('../usage.xml')/usage" />
|
|
||||||
|
|
||||||
<!-- Twiddle this variable to get the columns as even as possible -->
|
|
||||||
<xsl:variable name="maxNumberAdjust" select="2" />
|
|
||||||
|
|
||||||
<xsl:template match="/">
|
<xsl:template match="/">
|
||||||
<html lang="en" xml:lang="en">
|
<html lang="en" xml:lang="en">
|
||||||
@@ -29,95 +25,55 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="{$css}" />
|
<link rel="stylesheet" type="text/css" href="{$css}" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="content">
|
<div id="library"><xsl:value-of select="/configdoc/title" /></div>
|
||||||
<div id="library"><xsl:value-of select="/configdoc/title" /></div>
|
<h1><xsl:value-of select="$title" /></h1>
|
||||||
<h1><xsl:value-of select="$title" /></h1>
|
<h2>Table of Contents</h2>
|
||||||
<div id="tocContainer">
|
<ul id="toc">
|
||||||
<h2>Table of Contents</h2>
|
<xsl:apply-templates mode="toc" />
|
||||||
<ul id="toc">
|
</ul>
|
||||||
<xsl:apply-templates mode="toc">
|
<xsl:apply-templates />
|
||||||
<xsl:with-param name="overflowNumber" select="round(count(/configdoc/namespace) div 2) + $maxNumberAdjust" />
|
|
||||||
</xsl:apply-templates>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<xsl:apply-templates />
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="title" mode="toc" />
|
<xsl:template match="title" mode="toc" />
|
||||||
<xsl:template match="namespace" mode="toc">
|
<xsl:template match="namespace" mode="toc">
|
||||||
<xsl:param name="overflowNumber" />
|
|
||||||
<xsl:variable name="number"><xsl:number level="single" /></xsl:variable>
|
|
||||||
<xsl:variable name="directiveNumber"><xsl:number level="any" count="directive" /></xsl:variable>
|
|
||||||
<xsl:if test="count(directive)>0">
|
<xsl:if test="count(directive)>0">
|
||||||
<li>
|
<li>
|
||||||
<!-- BEGIN multicolumn code -->
|
|
||||||
<xsl:if test="$number >= $overflowNumber">
|
|
||||||
<xsl:attribute name="class">col-2</xsl:attribute>
|
|
||||||
</xsl:if>
|
|
||||||
<xsl:if test="$number = $overflowNumber">
|
|
||||||
<xsl:attribute name="style">margin-top:-<xsl:value-of select="($number * 2 + $directiveNumber - 3) * 1.2" />em</xsl:attribute>
|
|
||||||
</xsl:if>
|
|
||||||
<!-- END multicolumn code -->
|
|
||||||
<a href="#{@id}"><xsl:value-of select="name" /></a>
|
<a href="#{@id}"><xsl:value-of select="name" /></a>
|
||||||
<ul>
|
<ul>
|
||||||
<xsl:apply-templates select="directive" mode="toc">
|
<xsl:apply-templates select="directive" mode="toc" />
|
||||||
<xsl:with-param name="overflowNumber" select="$overflowNumber" />
|
|
||||||
</xsl:apply-templates>
|
|
||||||
</ul>
|
</ul>
|
||||||
<xsl:if test="$number + 1 = $overflowNumber">
|
|
||||||
<div class="col-l" />
|
|
||||||
</xsl:if>
|
|
||||||
</li>
|
</li>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="directive" mode="toc">
|
<xsl:template match="directive" mode="toc">
|
||||||
<xsl:variable name="number">
|
<li><a href="#{@id}"><xsl:value-of select="name" /></a></li>
|
||||||
<xsl:number level="any" count="directive|namespace" />
|
|
||||||
</xsl:variable>
|
|
||||||
<xsl:if test="not(deprecated)">
|
|
||||||
<li>
|
|
||||||
<a href="#{@id}"><xsl:value-of select="name" /></a>
|
|
||||||
</li>
|
|
||||||
</xsl:if>
|
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="title" />
|
<xsl:template match="title" />
|
||||||
|
|
||||||
<xsl:template match="namespace">
|
<xsl:template match="namespace">
|
||||||
<div class="namespace">
|
<xsl:apply-templates />
|
||||||
<xsl:apply-templates />
|
<xsl:if test="count(directive)=0">
|
||||||
<xsl:if test="count(directive)=0">
|
<p>No configuration directives defined for this namespace.</p>
|
||||||
<p>No configuration directives defined for this namespace.</p>
|
</xsl:if>
|
||||||
</xsl:if>
|
|
||||||
</div>
|
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="namespace/name">
|
<xsl:template match="namespace/name">
|
||||||
<h2 id="{../@id}"><xsl:value-of select="." /></h2>
|
<h2 id="{../@id}"><xsl:value-of select="." /></h2>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="namespace/description">
|
<xsl:template match="namespace/description">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<xsl:copy-of xmlns:xhtml="http://www.w3.org/1999/xhtml" select="xhtml:div/node()" />
|
<xsl:copy-of select="div/node()" />
|
||||||
</div>
|
</div>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="directive">
|
<xsl:template match="directive">
|
||||||
<div>
|
<xsl:apply-templates />
|
||||||
<xsl:attribute name="class"><!--
|
|
||||||
-->directive<!--
|
|
||||||
--><xsl:if test="deprecated"> deprecated</xsl:if><!--
|
|
||||||
--></xsl:attribute>
|
|
||||||
<xsl:apply-templates>
|
|
||||||
<xsl:with-param name="id" select="@id" />
|
|
||||||
</xsl:apply-templates>
|
|
||||||
</div>
|
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="directive/name">
|
<xsl:template match="directive/name">
|
||||||
<xsl:param name="id" />
|
|
||||||
<xsl:apply-templates select="../aliases/alias" mode="anchor" />
|
<xsl:apply-templates select="../aliases/alias" mode="anchor" />
|
||||||
<h3 id="{$id}"><xsl:value-of select="$id" /></h3>
|
<h3 id="{../@id}"><xsl:value-of select="../@id" /></h3>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="alias" mode="anchor">
|
<xsl:template match="alias" mode="anchor">
|
||||||
<a id="{.}"></a>
|
<a id="{.}"></a>
|
||||||
@@ -127,72 +83,47 @@
|
|||||||
<xsl:template match="alias"></xsl:template>
|
<xsl:template match="alias"></xsl:template>
|
||||||
|
|
||||||
<xsl:template match="directive/constraints">
|
<xsl:template match="directive/constraints">
|
||||||
<xsl:param name="id" />
|
|
||||||
<table class="constraints">
|
<table class="constraints">
|
||||||
<xsl:apply-templates />
|
<xsl:apply-templates />
|
||||||
|
<!-- Calculated other values -->
|
||||||
|
<xsl:if test="../descriptions/description[@file]">
|
||||||
|
<tr>
|
||||||
|
<th>Used by:</th>
|
||||||
|
<td>
|
||||||
|
<xsl:for-each select="../descriptions/description">
|
||||||
|
<xsl:if test="position()>1">, </xsl:if>
|
||||||
|
<xsl:value-of select="@file" />
|
||||||
|
</xsl:for-each>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</xsl:if>
|
||||||
<xsl:if test="../aliases/alias">
|
<xsl:if test="../aliases/alias">
|
||||||
<xsl:apply-templates select="../aliases" mode="constraints" />
|
<xsl:apply-templates select="../aliases" mode="constraints" />
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:apply-templates select="$usageLookup/directive[@id=$id]" />
|
|
||||||
</table>
|
</table>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="directive/aliases" mode="constraints">
|
<xsl:template match="directive/aliases" mode="constraints">
|
||||||
<tr>
|
<th>Aliases:</th>
|
||||||
<th>Aliases</th>
|
<td>
|
||||||
<td>
|
<xsl:for-each select="alias">
|
||||||
<xsl:for-each select="alias">
|
|
||||||
<xsl:if test="position()>1">, </xsl:if>
|
|
||||||
<xsl:value-of select="." />
|
|
||||||
</xsl:for-each>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="directive/description">
|
|
||||||
<div class="description">
|
|
||||||
<xsl:copy-of xmlns:xhtml="http://www.w3.org/1999/xhtml" select="xhtml:div/node()" />
|
|
||||||
</div>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="directive/deprecated">
|
|
||||||
<div class="deprecated-notice">
|
|
||||||
<strong>Warning:</strong>
|
|
||||||
This directive was deprecated in version <xsl:value-of select="version" />.
|
|
||||||
<a href="#{use}">%<xsl:value-of select="use" /></a> should be used instead.
|
|
||||||
</div>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="usage/directive">
|
|
||||||
<tr>
|
|
||||||
<th>Used in</th>
|
|
||||||
<td>
|
|
||||||
<ul>
|
|
||||||
<xsl:apply-templates />
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="usage/directive/file">
|
|
||||||
<li>
|
|
||||||
<em><xsl:value-of select="@name" /></em> on line<xsl:if test="count(line)>1">s</xsl:if>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:for-each select="line">
|
|
||||||
<xsl:if test="position()>1">, </xsl:if>
|
<xsl:if test="position()>1">, </xsl:if>
|
||||||
<xsl:value-of select="." />
|
<xsl:value-of select="." />
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
</li>
|
</td>
|
||||||
|
</xsl:template>
|
||||||
|
<xsl:template match="directive//description">
|
||||||
|
<div class="description">
|
||||||
|
<xsl:copy-of select="div/node()" />
|
||||||
|
</div>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="constraints/version">
|
|
||||||
<tr>
|
|
||||||
<th>Version added</th>
|
|
||||||
<td><xsl:value-of select="." /></td>
|
|
||||||
</tr>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="constraints/type">
|
<xsl:template match="constraints/type">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Type</th>
|
<th>Type:</th>
|
||||||
<td>
|
<td>
|
||||||
<xsl:variable name="type" select="text()" />
|
<xsl:variable name="type" select="text()" />
|
||||||
<xsl:attribute name="class">type type-<xsl:value-of select="$type" /></xsl:attribute>
|
<xsl:attribute name="class">type type-<xsl:value-of select="$type" /></xsl:attribute>
|
||||||
<xsl:value-of select="$typeLookup/type[@id=$type]/text()" />
|
<xsl:value-of select="$typeLookup/types/type[@id=$type]/text()" />
|
||||||
<xsl:if test="@allow-null='yes'">
|
<xsl:if test="@allow-null='yes'">
|
||||||
(or null)
|
(or null)
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
@@ -201,7 +132,7 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="constraints/allowed">
|
<xsl:template match="constraints/allowed">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Allowed values</th>
|
<th>Allowed values:</th>
|
||||||
<td>
|
<td>
|
||||||
<xsl:for-each select="value"><!--
|
<xsl:for-each select="value"><!--
|
||||||
--><xsl:if test="position()>1">, </xsl:if>
|
--><xsl:if test="position()>1">, </xsl:if>
|
||||||
@@ -212,22 +143,9 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="constraints/default">
|
<xsl:template match="constraints/default">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Default</th>
|
<th>Default:</th>
|
||||||
<td><pre><xsl:value-of select="." xml:space="preserve" /></pre></td>
|
<td><pre><xsl:value-of select="." xml:space="preserve" /></pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
<xsl:template match="constraints/external">
|
|
||||||
<tr>
|
|
||||||
<th>External deps</th>
|
|
||||||
<td>
|
|
||||||
<ul>
|
|
||||||
<xsl:apply-templates />
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="constraints/external/project">
|
|
||||||
<li><xsl:value-of select="." /></li>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<types>
|
|
||||||
<type id="string">String</type>
|
|
||||||
<type id="istring">Case-insensitive string</type>
|
|
||||||
<type id="text">Text</type>
|
|
||||||
<type id="itext">Case-insensitive text</type>
|
|
||||||
<type id="int">Integer</type>
|
|
||||||
<type id="float">Float</type>
|
|
||||||
<type id="bool">Boolean</type>
|
|
||||||
<type id="lookup">Lookup array</type>
|
|
||||||
<type id="list">Array list</type>
|
|
||||||
<type id="hash">Associative array</type>
|
|
||||||
<type id="mixed">Mixed</type>
|
|
||||||
</types>
|
|
@@ -1,402 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<usage>
|
|
||||||
<directive id="Core.CollectErrors">
|
|
||||||
<file name="HTMLPurifier.php">
|
|
||||||
<line>131</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
|
||||||
<line>81</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
|
||||||
<line>53</line>
|
|
||||||
<line>73</line>
|
|
||||||
<line>348</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
|
||||||
<line>47</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="CSS.MaxImgLength">
|
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
|
||||||
<line>157</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="CSS.Proprietary">
|
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
|
||||||
<line>214</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="CSS.AllowTricky">
|
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
|
||||||
<line>218</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="CSS.AllowImportant">
|
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
|
||||||
<line>222</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="CSS.AllowedProperties">
|
|
||||||
<file name="HTMLPurifier/CSSDefinition.php">
|
|
||||||
<line>274</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Cache.DefinitionImpl">
|
|
||||||
<file name="HTMLPurifier/DefinitionCacheFactory.php">
|
|
||||||
<line>49</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.Doctype">
|
|
||||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
|
||||||
<line>83</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.CustomDoctype">
|
|
||||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
|
||||||
<line>85</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.XHTML">
|
|
||||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
|
||||||
<line>88</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.Strict">
|
|
||||||
<file name="HTMLPurifier/DoctypeRegistry.php">
|
|
||||||
<line>93</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.Encoding">
|
|
||||||
<file name="HTMLPurifier/Encoder.php">
|
|
||||||
<line>267</line>
|
|
||||||
<line>300</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Test.ForceNoIconv">
|
|
||||||
<file name="HTMLPurifier/Encoder.php">
|
|
||||||
<line>272</line>
|
|
||||||
<line>308</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.EscapeNonASCIICharacters">
|
|
||||||
<file name="HTMLPurifier/Encoder.php">
|
|
||||||
<line>304</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Output.CommentScriptContents">
|
|
||||||
<file name="HTMLPurifier/Generator.php">
|
|
||||||
<line>45</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Output.SortAttr">
|
|
||||||
<file name="HTMLPurifier/Generator.php">
|
|
||||||
<line>46</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Output.TidyFormat">
|
|
||||||
<file name="HTMLPurifier/Generator.php">
|
|
||||||
<line>75</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Output.Newline">
|
|
||||||
<file name="HTMLPurifier/Generator.php">
|
|
||||||
<line>89</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.BlockWrapper">
|
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
|
||||||
<line>222</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.Parent">
|
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
|
||||||
<line>230</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.AllowedElements">
|
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
|
||||||
<line>247</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.AllowedAttributes">
|
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
|
||||||
<line>248</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.Allowed">
|
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
|
||||||
<line>251</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.ForbiddenElements">
|
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
|
||||||
<line>337</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.ForbiddenAttributes">
|
|
||||||
<file name="HTMLPurifier/HTMLDefinition.php">
|
|
||||||
<line>338</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.Trusted">
|
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
|
||||||
<line>202</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
|
||||||
<line>258</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/HTMLModule/Image.php">
|
|
||||||
<line>27</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
|
||||||
<line>36</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
|
||||||
<line>23</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.AllowedModules">
|
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
|
||||||
<line>209</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.CoreModules">
|
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
|
||||||
<line>210</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.Proprietary">
|
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
|
||||||
<line>221</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.SafeObject">
|
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
|
||||||
<line>226</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.SafeEmbed">
|
|
||||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
|
||||||
<line>229</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.IDBlacklist">
|
|
||||||
<file name="HTMLPurifier/IDAccumulator.php">
|
|
||||||
<line>26</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.Language">
|
|
||||||
<file name="HTMLPurifier/LanguageFactory.php">
|
|
||||||
<line>88</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.LexerImpl">
|
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
|
||||||
<line>76</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.MaintainLineNumbers">
|
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
|
||||||
<line>80</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
|
||||||
<line>48</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.ConvertDocumentToFragment">
|
|
||||||
<file name="HTMLPurifier/Lexer.php">
|
|
||||||
<line>267</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.Host">
|
|
||||||
<file name="HTMLPurifier/URIDefinition.php">
|
|
||||||
<line>64</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.Base">
|
|
||||||
<file name="HTMLPurifier/URIDefinition.php">
|
|
||||||
<line>65</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.DefaultScheme">
|
|
||||||
<file name="HTMLPurifier/URIDefinition.php">
|
|
||||||
<line>72</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.AllowedSchemes">
|
|
||||||
<file name="HTMLPurifier/URISchemeRegistry.php">
|
|
||||||
<line>42</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.OverrideAllowedSchemes">
|
|
||||||
<file name="HTMLPurifier/URISchemeRegistry.php">
|
|
||||||
<line>43</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.Disable">
|
|
||||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
|
||||||
<line>28</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.ColorKeywords">
|
|
||||||
<file name="HTMLPurifier/AttrDef/CSS/Color.php">
|
|
||||||
<line>12</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/AttrDef/HTML/Color.php">
|
|
||||||
<line>12</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.AllowedFrameTargets">
|
|
||||||
<file name="HTMLPurifier/AttrDef/HTML/FrameTarget.php">
|
|
||||||
<line>15</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.EnableID">
|
|
||||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
|
||||||
<line>20</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.IDPrefix">
|
|
||||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
|
||||||
<line>26</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.IDPrefixLocal">
|
|
||||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
|
||||||
<line>28</line>
|
|
||||||
<line>31</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.IDBlacklistRegexp">
|
|
||||||
<file name="HTMLPurifier/AttrDef/HTML/ID.php">
|
|
||||||
<line>54</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.DefaultTextDir">
|
|
||||||
<file name="HTMLPurifier/AttrTransform/BdoDir.php">
|
|
||||||
<line>13</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.RemoveInvalidImg">
|
|
||||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
|
||||||
<line>18</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
|
||||||
<line>20</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.DefaultInvalidImage">
|
|
||||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
|
||||||
<line>19</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.DefaultImageAlt">
|
|
||||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
|
||||||
<line>25</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Attr.DefaultInvalidImageAlt">
|
|
||||||
<file name="HTMLPurifier/AttrTransform/ImgRequired.php">
|
|
||||||
<line>32</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.EscapeInvalidChildren">
|
|
||||||
<file name="HTMLPurifier/ChildDef/Required.php">
|
|
||||||
<line>55</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Cache.SerializerPath">
|
|
||||||
<file name="HTMLPurifier/DefinitionCache/Serializer.php">
|
|
||||||
<line>91</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="FilterParam.ExtractStyleBlocksTidyImpl">
|
|
||||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
|
||||||
<line>41</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="FilterParam.ExtractStyleBlocksScope">
|
|
||||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
|
||||||
<line>65</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="FilterParam.ExtractStyleBlocksEscaping">
|
|
||||||
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
|
|
||||||
<line>123</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.MaxImgLength">
|
|
||||||
<file name="HTMLPurifier/HTMLModule/Image.php">
|
|
||||||
<line>14</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/HTMLModule/SafeEmbed.php">
|
|
||||||
<line>13</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/HTMLModule/SafeObject.php">
|
|
||||||
<line>19</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.TidyLevel">
|
|
||||||
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
|
||||||
<line>45</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.TidyAdd">
|
|
||||||
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
|
||||||
<line>49</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="HTML.TidyRemove">
|
|
||||||
<file name="HTMLPurifier/HTMLModule/Tidy.php">
|
|
||||||
<line>50</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="AutoFormatParam.PurifierLinkifyDocURL">
|
|
||||||
<file name="HTMLPurifier/Injector/PurifierLinkify.php">
|
|
||||||
<line>15</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.AggressivelyFixLt">
|
|
||||||
<file name="HTMLPurifier/Lexer/DOMLex.php">
|
|
||||||
<line>44</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.DirectLexLineNumberSyncInterval">
|
|
||||||
<file name="HTMLPurifier/Lexer/DirectLex.php">
|
|
||||||
<line>70</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.EscapeInvalidTags">
|
|
||||||
<file name="HTMLPurifier/Strategy/MakeWellFormed.php">
|
|
||||||
<line>45</line>
|
|
||||||
</file>
|
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
|
||||||
<line>19</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.RemoveScriptContents">
|
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
|
||||||
<line>25</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.HiddenElements">
|
|
||||||
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
|
|
||||||
<line>26</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.HostBlacklist">
|
|
||||||
<file name="HTMLPurifier/URIFilter/HostBlacklist.php">
|
|
||||||
<line>8</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.MungeResources">
|
|
||||||
<file name="HTMLPurifier/URIFilter/Munge.php">
|
|
||||||
<line>14</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="URI.MungeSecretKey">
|
|
||||||
<file name="HTMLPurifier/URIFilter/Munge.php">
|
|
||||||
<line>15</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
</usage>
|
|
@@ -3,7 +3,7 @@
|
|||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<meta name="description" content="Specification for HTML Purifier's advanced API for defining custom filtering behavior." />
|
<meta name="description" content="Functional specification for HTML Purifier's advanced API for defining custom filtering behavior." />
|
||||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||||
|
|
||||||
<title>Advanced API - HTML Purifier</title>
|
<title>Advanced API - HTML Purifier</title>
|
||||||
@@ -16,11 +16,6 @@
|
|||||||
<div id="index">Return to the <a href="index.html">index</a>.</div>
|
<div id="index">Return to the <a href="index.html">index</a>.</div>
|
||||||
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>Warning:</strong> This document may be out-of-date. When in doubt,
|
|
||||||
consult the source code documentation.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>HTML Purifier currently natively supports only a subset of HTML's
|
<p>HTML Purifier currently natively supports only a subset of HTML's
|
||||||
allowed elements, attributes, and behavior; specifically, this subset
|
allowed elements, attributes, and behavior; specifically, this subset
|
||||||
is the set of elements that are safe for untrusted users to use.
|
is the set of elements that are safe for untrusted users to use.
|
||||||
@@ -213,4 +208,6 @@ the usual things required are:</p>
|
|||||||
|
|
||||||
<p>See <code>HTMLPurifier/HTMLModule.php</code> for details.</p>
|
<p>See <code>HTMLPurifier/HTMLModule.php</code> for details.</p>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -17,6 +17,7 @@ a lot of strtolower() calls, no legit casing
|
|||||||
URI - multiple regular expressions; missing validation for parts (?)
|
URI - multiple regular expressions; missing validation for parts (?)
|
||||||
CSS - parser doesn't accept advanced CSS (fringe)
|
CSS - parser doesn't accept advanced CSS (fringe)
|
||||||
Number - constructor interface inconsistent with Integer
|
Number - constructor interface inconsistent with Integer
|
||||||
|
ConfigSchema - redefinition is a mess
|
||||||
Strategy
|
Strategy
|
||||||
FixNesting - cannot bubble nodes out of structures, duplicated checks
|
FixNesting - cannot bubble nodes out of structures, duplicated checks
|
||||||
for special-case parent node
|
for special-case parent node
|
||||||
|
@@ -1,374 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<meta name="description" content="Describes config schema framework in HTML Purifier." />
|
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css" />
|
|
||||||
<title>Config Schema - HTML Purifier</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h1>Config Schema</h1>
|
|
||||||
|
|
||||||
<div id="filing">Filed under Development</div>
|
|
||||||
<div id="index">Return to the <a href="index.html">index</a>.</div>
|
|
||||||
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
HTML Purifier has a fairly complex system for configuration. Users
|
|
||||||
interact with a <code>HTMLPurifier_Config</code> object to
|
|
||||||
set configuration directives. The values they set are validated according
|
|
||||||
to a configuration schema, <code>HTMLPurifier_ConfigSchema</code>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The schema is mostly transparent to end-users, but if you're doing development
|
|
||||||
work for HTML Purifier and need to define a new configuration directive,
|
|
||||||
you'll need to interact with it. We'll also talk about how to define
|
|
||||||
userspace configuration directives at the very end.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Write a directive file</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Directive files define configuration directives to be used by
|
|
||||||
HTML Purifier. They are placed in <code>library/HTMLPurifier/ConfigSchema/schema/</code>
|
|
||||||
in the form <code><em>Namespace</em>.<em>Directive</em>.txt</code> (I
|
|
||||||
couldn't think of a more descriptive file extension.)
|
|
||||||
Directive files are actually what we call <code>StringHash</code>es,
|
|
||||||
i.e. associative arrays represented in a string form reminiscent of
|
|
||||||
<a href="http://qa.php.net/write-test.php">PHPT</a> tests. Here's a
|
|
||||||
sample directive file, <code>Test.Sample.txt</code>:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>Test.Sample
|
|
||||||
TYPE: string/null
|
|
||||||
DEFAULT: NULL
|
|
||||||
ALLOWED: 'foo', 'bar'
|
|
||||||
VALUE-ALIASES: 'baz' => 'bar'
|
|
||||||
VERSION: 3.1.0
|
|
||||||
--DESCRIPTION--
|
|
||||||
This is a sample configuration directive for the purposes of the
|
|
||||||
<code>dev-config-schema.html<code> documentation.
|
|
||||||
--ALIASES--
|
|
||||||
Test.Example</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Each of these segments has a specific meaning:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Key</th>
|
|
||||||
<th>Example</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>ID</td>
|
|
||||||
<td>Test.Sample</td>
|
|
||||||
<td>The name of the directive, in the form Namespace.Directive
|
|
||||||
(implicitly the first line)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>TYPE</td>
|
|
||||||
<td>string/null</td>
|
|
||||||
<td>The type of variable this directive accepts. See below for
|
|
||||||
details. You can also add <code>/null</code> to the end of
|
|
||||||
any basic type to allow null values too.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>DEFAULT</td>
|
|
||||||
<td>NULL</td>
|
|
||||||
<td>A parseable PHP expression of the default value.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>DESCRIPTION</td>
|
|
||||||
<td>This is a...</td>
|
|
||||||
<td>An HTML description of what this directive does.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>VERSION</td>
|
|
||||||
<td>3.1.0</td>
|
|
||||||
<td><em>Recommended</em>. The version of HTML Purifier this directive was added.
|
|
||||||
Directives that have been around since 1.0.0 don't have this,
|
|
||||||
but any new ones should.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>ALIASES</td>
|
|
||||||
<td>Test.Example</td>
|
|
||||||
<td><em>Optional</em>. A comma separated list of aliases for this directive.
|
|
||||||
This is most useful for backwards compatibility and should
|
|
||||||
not be used otherwise.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>ALLOWED</td>
|
|
||||||
<td>'foo', 'bar'</td>
|
|
||||||
<td><em>Optional</em>. Set of allowed value for a directive,
|
|
||||||
a comma separated list of parseable PHP expressions. This
|
|
||||||
is only allowed string, istring, text and itext TYPEs.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>VALUE-ALIASES</td>
|
|
||||||
<td>'baz' => 'bar'</td>
|
|
||||||
<td><em>Optional</em>. Mapping of one value to another, and
|
|
||||||
should be a comma separated list of keypair duples. This
|
|
||||||
is only allowed string, istring, text and itext TYPEs.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>DEPRECATED-VERSION</td>
|
|
||||||
<td>3.1.0</td>
|
|
||||||
<td><em>Not shown</em>. Indicates that the directive was
|
|
||||||
deprecated this version.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>DEPRECATED-USE</td>
|
|
||||||
<td>Test.NewDirective</td>
|
|
||||||
<td><em>Not shown</em>. Indicates what new directive should be
|
|
||||||
used instead. Note that the directives will functionally be
|
|
||||||
different, although they should offer the same functionality.
|
|
||||||
If they are identical, use an alias instead.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>EXTERNAL</td>
|
|
||||||
<td>CSSTidy</td>
|
|
||||||
<td><em>Not shown</em>. Indicates if there is an external library
|
|
||||||
the user will need to download and install to use this configuration
|
|
||||||
directive. As of right now, this is merely a Google-able name; future
|
|
||||||
versions may also provide links and instructions.</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Some notes on format and style:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Each of these keys can be expressed in the short format
|
|
||||||
(<code>KEY: Value</code>) or the long format
|
|
||||||
(<code>--KEY--</code> with value beneath). You must use the
|
|
||||||
long format if multiple lines are needed, or if a long format
|
|
||||||
has been used already (that's why <code>ALIASES</code> in our
|
|
||||||
example is in the long format); otherwise, it's user preference.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The HTML descriptions should be wrapped at about 80 columns; do
|
|
||||||
not rely on editor word-wrapping.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Also, as promised, here is the set of possible types:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Type</th>
|
|
||||||
<th>Example</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>string</td>
|
|
||||||
<td>'Foo'</td>
|
|
||||||
<td><a href="http://docs.php.net/manual/en/language.types.string.php">String</a> without newlines</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>istring</td>
|
|
||||||
<td>'foo'</td>
|
|
||||||
<td>Case insensitive ASCII string without newlines</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>text</td>
|
|
||||||
<td>"A<em>\n</em>b"</td>
|
|
||||||
<td>String with newlines</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>itext</td>
|
|
||||||
<td>"a<em>\n</em>b"</td>
|
|
||||||
<td>Case insensitive ASCII string without newlines</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>int</td>
|
|
||||||
<td>23</td>
|
|
||||||
<td>Integer</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>float</td>
|
|
||||||
<td>3.0</td>
|
|
||||||
<td>Floating point number</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>bool</td>
|
|
||||||
<td>true</td>
|
|
||||||
<td>Boolean</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>lookup</td>
|
|
||||||
<td>array('key' => true)</td>
|
|
||||||
<td>Lookup array, used with <code>isset($var[$key])</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>list</td>
|
|
||||||
<td>array('f', 'b')</td>
|
|
||||||
<td>List array, with ordered numerical indexes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>hash</td>
|
|
||||||
<td>array('key' => 'val')</td>
|
|
||||||
<td>Associative array of keys to values</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>mixed</td>
|
|
||||||
<td>new stdclass</td>
|
|
||||||
<td>Any PHP variable is fine</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The examples represent what will be returned out of the configuration
|
|
||||||
object; users have a little bit of leeway when setting configuration
|
|
||||||
values (for example, a lookup value can be specified as a list;
|
|
||||||
HTML Purifier will flip it as necessary.) These types are defined
|
|
||||||
in <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/VarParser.php">
|
|
||||||
library/HTMLPurifier/VarParser.php</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
For more information on what values are allowed, and how they are parsed,
|
|
||||||
consult <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
|
||||||
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>, as well
|
|
||||||
as <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/Interchange/Directive.php">
|
|
||||||
library/HTMLPurifier/ConfigSchema/Interchange/Directive.php</a> for
|
|
||||||
the semantics of the parsed values.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Refreshing the cache</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
You may have noticed that your directive file isn't doing anything
|
|
||||||
yet. That's because it hasn't been added to the runtime
|
|
||||||
<code>HTMLPurifier_ConfigSchema</code> instance. Run
|
|
||||||
<code>maintenance/generate-schema-cache.php</code> to fix this.
|
|
||||||
If there were no errors, you're good to go! Don't forget to add
|
|
||||||
some unit tests for your functionality!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you ever make changes to your configuration directives, you
|
|
||||||
will need to run this script again.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Errors</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
All directive files go through a rigorous validation process
|
|
||||||
through <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/Validator.php">
|
|
||||||
library/HTMLPurifier/ConfigSchema/Validator.php</a>, as well
|
|
||||||
as some basic checks during building. While
|
|
||||||
listing every error out here is out-of-scope for this document, we
|
|
||||||
can give some general tips for interpreting error messages.
|
|
||||||
There are two types of errors: builder errors and validation errors.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Builder errors</h3>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<p>
|
|
||||||
<strong>Exception:</strong> Expected type string, got
|
|
||||||
integer in DEFAULT in directive hash 'Ns.Dir'
|
|
||||||
</p>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
You can identify a builder error by the keyword "directive hash."
|
|
||||||
These are the easiest to deal with, because they directly correspond
|
|
||||||
with your directive file. Find the offending directive file (which
|
|
||||||
is the directive hash plus the .txt extension), find the
|
|
||||||
offending index ("in DEFAULT" means the DEFAULT key) and fix the error.
|
|
||||||
This particular error would occur if your default value is not the same
|
|
||||||
type as TYPE.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Validation errors</h3>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<p>
|
|
||||||
<strong>Exception:</strong> Alias 3 in valueAliases in directive
|
|
||||||
'Ns.Dir' must be a string
|
|
||||||
</p>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
These are a little trickier, because we're not actually validating
|
|
||||||
your directive file, or even the direct string hash representation.
|
|
||||||
We're validating an Interchange object, and the error messages do
|
|
||||||
not mention any string hash keys.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Nevertheless, it's not difficult to figure out what went wrong.
|
|
||||||
Read the "context" statements in reverse:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<dl>
|
|
||||||
<dt>in directive 'Ns.Dir'</dt>
|
|
||||||
<dd>This means we need to look at the directive file <code>Ns.Dir.txt</code></dd>
|
|
||||||
<dt>in valueAliases</dt>
|
|
||||||
<dd>There's no key actually called this, but there's one that's close:
|
|
||||||
VALUE-ALIASES. Indeed, that's where to look.</dd>
|
|
||||||
<dt>Alias 3</dt>
|
|
||||||
<dd>The value alias that is equal to 3 is the culprit.</dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
In this particular case, you're not allowed to alias integers values to
|
|
||||||
strings values.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The most difficult part is translating the Interchange member variable (valueAliases)
|
|
||||||
into a directive file key (VALUE-ALIASES), but there's a one-to-one
|
|
||||||
correspondence currently. If the two formats diverge, any discrepancies
|
|
||||||
will be described in <a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php">
|
|
||||||
library/HTMLPurifier/ConfigSchema/InterchangeBuilder.php</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Internals</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Much of the configuration schema framework's codebase deals with
|
|
||||||
shuffling data from one format to another, and doing validation on this
|
|
||||||
data.
|
|
||||||
The keystone of all of this is the <code>HTMLPurifier_ConfigSchema_Interchange</code>
|
|
||||||
class, which represents the purest, parsed representation of the schema.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Hand-writing this data is unwieldy, however, so we write directive files.
|
|
||||||
These directive files are parsed by <code>HTMLPurifier_StringHashParser</code>
|
|
||||||
into <code>HTMLPurifier_StringHash</code>es, which then
|
|
||||||
are run through <code>HTMLPurifier_ConfigSchema_InterchangeBuilder</code>
|
|
||||||
to construct the interchange object.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
From the interchange object, the data can be siphoned into other forms
|
|
||||||
using <code>HTMLPurifier_ConfigSchema_Builder</code> subclasses.
|
|
||||||
For example, <code>HTMLPurifier_ConfigSchema_Builder_ConfigSchema</code>
|
|
||||||
generates a runtime <code>HTMLPurifier_ConfigSchema</code> object,
|
|
||||||
which <code>HTMLPurifier_Config</code> uses to validate its incoming
|
|
||||||
data. There is also an XML serializer, which is used to build documentation.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@@ -1,65 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<meta name="description" content="Discusses when to flush HTML Purifier's various caches." />
|
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css" />
|
|
||||||
<title>Flushing the Purifier - HTML Purifier</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h1>Flushing the Purifier</h1>
|
|
||||||
|
|
||||||
<div id="filing">Filed under Development</div>
|
|
||||||
<div id="index">Return to the <a href="index.html">index</a>.</div>
|
|
||||||
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you've been poking around the various folders in HTML Purifier,
|
|
||||||
you may have noticed the <code>maintenance</code> directory. Almost
|
|
||||||
all of these scripts are devoted to flushing out the various caches
|
|
||||||
HTML Purifier uses. Normal users don't have to worry about this:
|
|
||||||
regular library usage is transparent. However, when doing development
|
|
||||||
work on HTML Purifier, you may find you have to flush one of the
|
|
||||||
caches.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
As a general rule of thumb, run <code>flush.php</code> whenever you make
|
|
||||||
any <em>major</em> changes, or when tests start mysteriously failing.
|
|
||||||
In more detail, run this script if:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
You added new source files to HTML Purifier's main library.
|
|
||||||
(see <code>generate-includes.php</code>)
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
You modified the configuration schema (see
|
|
||||||
<code>generate-schema-cache.php</code>). This usually means
|
|
||||||
adding or modifying files in <code>HTMLPurifier/ConfigSchema/schema/</code>,
|
|
||||||
although in rare cases modifying <code>HTMLPurifier/ConfigSchema.php</code>
|
|
||||||
will also require this.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
You modified a Definition, or its subsystems. The most usual candidate
|
|
||||||
is <code>HTMLPurifier/HTMLDefinition.php</code>, which also encompasses
|
|
||||||
the files in <code>HTMLPurifier/HTMLModule/</code> as well as if you've
|
|
||||||
<a href="enduser-customize.html">customizing definitions</a> without
|
|
||||||
the cache disabled. (see <code>flush-generation-cache.php</code>)
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
You modified source files, and have been using the standalone
|
|
||||||
version from the full installation. (see <code>generate-standalone.php</code>)
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
You can check out the corresponding scripts for more information on what they
|
|
||||||
do.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</body></html>
|
|
@@ -1,279 +0,0 @@
|
|||||||
|
|
||||||
INCLUDES, AUTOLOAD, BYTECODE CACHES and OPTIMIZATION
|
|
||||||
|
|
||||||
The Problem
|
|
||||||
-----------
|
|
||||||
|
|
||||||
HTML Purifier contains a number of extra components that are not used all
|
|
||||||
of the time, only if the user explicitly specifies that we should use
|
|
||||||
them.
|
|
||||||
|
|
||||||
Some of these optional components are optionally included (Filter,
|
|
||||||
Language, Lexer, Printer), while others are included all the time
|
|
||||||
(Injector, URIFilter, HTMLModule, URIScheme). We will stipulate that these
|
|
||||||
are all developer specified: it is conceivable that certain Tokens are not
|
|
||||||
used, but this is user-dependent and should not be trusted.
|
|
||||||
|
|
||||||
We should come up with a consistent way to handle these things and ensure
|
|
||||||
that we get the maximum performance when there is bytecode caches and
|
|
||||||
when there are not. Unfortunately, these two goals seem contrary to each
|
|
||||||
other.
|
|
||||||
|
|
||||||
A peripheral issue is the performance of ConfigSchema, which has been
|
|
||||||
shown take a large, constant amount of initialization time, and is
|
|
||||||
intricately linked to the issue of includes due to its pervasive use
|
|
||||||
in our plugin architecture.
|
|
||||||
|
|
||||||
Pros and Cons
|
|
||||||
-------------
|
|
||||||
|
|
||||||
We will assume that user-based extensions will be included by them.
|
|
||||||
|
|
||||||
Conditional includes:
|
|
||||||
Pros:
|
|
||||||
- User management is simplified; only a single directive needs to be set
|
|
||||||
- Only necessary code is included
|
|
||||||
Cons:
|
|
||||||
- Doesn't play nicely with opcode caches
|
|
||||||
- Adds complexity to standalone version
|
|
||||||
- Optional configuration directives are not exposed without a little
|
|
||||||
extra coaxing (not implemented yet)
|
|
||||||
|
|
||||||
Include it all:
|
|
||||||
Pros:
|
|
||||||
- User management is still simple
|
|
||||||
- Plays nicely with opcode caches and standalone version
|
|
||||||
- All configuration directives are present
|
|
||||||
Cons:
|
|
||||||
- Lots of (how much?) extra code is included
|
|
||||||
- Classes that inherit from external libraries will cause compile
|
|
||||||
errors
|
|
||||||
|
|
||||||
Build an include stub (Let's do this!):
|
|
||||||
Pros:
|
|
||||||
- Only necessary code is included
|
|
||||||
- Plays nicely with opcode caches and standalone version
|
|
||||||
- require (without once) can be used, see above
|
|
||||||
- Could further extend as a compilation to one file
|
|
||||||
Cons:
|
|
||||||
- Not implemented yet
|
|
||||||
- Requires user intervention and use of a command line script
|
|
||||||
- Standalone script must be chained to this
|
|
||||||
- More complex and compiled-language-like
|
|
||||||
- Requires a whole new class of system-wide configuration directives,
|
|
||||||
as configuration objects can be reused
|
|
||||||
- Determining what needs to be included can be complex (see above)
|
|
||||||
- No way of autodetecting dynamically instantiated classes
|
|
||||||
- Might be slow
|
|
||||||
|
|
||||||
Include stubs
|
|
||||||
-------------
|
|
||||||
|
|
||||||
This solution may be "just right" for users who are heavily oriented
|
|
||||||
towards performance. However, there are a number of picky implementation
|
|
||||||
details to work out beforehand.
|
|
||||||
|
|
||||||
The number one concern is how to make the HTML Purifier files "work
|
|
||||||
out of the box", while still being able to easily get them into a form
|
|
||||||
that works with this setup. As the codebase stands right now, it would
|
|
||||||
be necessary to strip out all of the require_once calls. The only way
|
|
||||||
we could get rid of the require_once calls is to use __autoload or
|
|
||||||
use the stub for all cases (which might not be a bad idea).
|
|
||||||
|
|
||||||
Aside
|
|
||||||
-----
|
|
||||||
An important thing to remember, however, is that these require_once's
|
|
||||||
are valuable data about what classes a file needs. Unfortunately, there's
|
|
||||||
no distinction between whether or not the file is needed all the time,
|
|
||||||
or whether or not it is one of our "optional" files. Thus, it is
|
|
||||||
effectively useless.
|
|
||||||
|
|
||||||
Deprecated
|
|
||||||
----------
|
|
||||||
One of the things I'd like to do is have the code search for any classes
|
|
||||||
that are explicitly mentioned in the code. If a class isn't mentioned, I
|
|
||||||
get to assume that it is "optional," i.e. included via introspection.
|
|
||||||
The choice is either to use PHP's tokenizer or use regexps; regexps would
|
|
||||||
be faster but a tokenizer would be more correct. If this ends up being
|
|
||||||
unfeasible, adding dependency comments isn't a bad idea. (This could
|
|
||||||
even be done automatically by search/replacing require_once, although
|
|
||||||
we'd have to manually inspect the results for the optional requires.)
|
|
||||||
|
|
||||||
NOTE: This ends up not being necessary, as we're going to make the user
|
|
||||||
figure out all the extra classes they need, and only include the core
|
|
||||||
which is predetermined.
|
|
||||||
|
|
||||||
Using the autoload framework with include stubs works nicely with
|
|
||||||
introspective classes: instead of having to have require_once inside
|
|
||||||
the function, we can let autoload do the work; we simply need to
|
|
||||||
new $class or accept the object straight from the caller. Handling filters
|
|
||||||
becomes a simple matter of ticking off configuration directives, and
|
|
||||||
if ConfigSchema spits out errors, adding the necessary includes. We could
|
|
||||||
also use the autoload framework as a fallback, in case the user forgets
|
|
||||||
to make the include, but doesn't really care about performance.
|
|
||||||
|
|
||||||
Insight
|
|
||||||
-------
|
|
||||||
All of this talk is merely a natural extension of what our current
|
|
||||||
standalone functionality does. However, instead of having our code
|
|
||||||
perform the includes, or attempting to inline everything that possibly
|
|
||||||
could be used, we boot the issue to the user, making them include
|
|
||||||
everything or setup the fallback autoload handler.
|
|
||||||
|
|
||||||
Configuration Schema
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
A common deficiency for all of the conditional include setups (including
|
|
||||||
the dynamically built include PHP stub) is that if one of this
|
|
||||||
conditionally included files includes a configuration directive, it
|
|
||||||
is not accessible to configdoc. A stopgap solution for this problem is
|
|
||||||
to have it piggy-back off of the data in the merge-library.php script
|
|
||||||
to figure out what extra files it needs to include, but if the file also
|
|
||||||
inherits classes that don't exist, we're in big trouble.
|
|
||||||
|
|
||||||
I think it's high time we centralized the configuration documentation.
|
|
||||||
However, the type checking has been a great boon for the library, and
|
|
||||||
I'd like to keep that. The compromise is to use some other source, and
|
|
||||||
then parse it into the ConfigSchema internal format (sans all of those
|
|
||||||
nasty documentation strings which we really don't need at runtime) and
|
|
||||||
serialize that for future use.
|
|
||||||
|
|
||||||
The next question is that of format. XML is very verbose, and the prospect
|
|
||||||
of setting defaults in it gives me willies. However, this may be necessary.
|
|
||||||
Splitting up the file into manageable chunks may alleviate this trouble,
|
|
||||||
and we may be even want to create our own format optimized for specifying
|
|
||||||
configuration. It might look like (based off the PHPT format, which is
|
|
||||||
nicely compact yet unambiguous and human-readable):
|
|
||||||
|
|
||||||
Core.HiddenElements
|
|
||||||
TYPE: lookup
|
|
||||||
DEFAULT: array('script', 'style') // auto-converted during processing
|
|
||||||
--ALIASES--
|
|
||||||
Core.InvisibleElements, Core.StupidElements
|
|
||||||
--DESCRIPTION--
|
|
||||||
<p>
|
|
||||||
Blah blah
|
|
||||||
</p>
|
|
||||||
|
|
||||||
The first line is the directive name, the lines after that prior to the
|
|
||||||
first --HEADER-- block are single-line values, and then after that
|
|
||||||
the multiline values are there. No value is restricted to a particular
|
|
||||||
format: DEFAULT could very well be multiline if that would be easier.
|
|
||||||
This would make it insanely easy, also, to add arbitrary extra parameters,
|
|
||||||
like:
|
|
||||||
|
|
||||||
VERSION: 3.0.0
|
|
||||||
ALLOWED: 'none', 'light', 'medium', 'heavy' // this is wrapped in array()
|
|
||||||
EXTERNAL: CSSTidy // this would be documented somewhere else with a URL
|
|
||||||
|
|
||||||
The final loss would be that you wouldn't know what file the directive
|
|
||||||
was used in; with some clever regexps it should be possible to
|
|
||||||
figure out where $config->get($ns, $d); occurs. Reflective calls to
|
|
||||||
the configuration object is mitigated by the fact that getBatch is
|
|
||||||
used, so we can simply talk about that in the namespace definition page.
|
|
||||||
This might be slow, but it would only happen when we are creating
|
|
||||||
the documentation for consumption, and is sugar.
|
|
||||||
|
|
||||||
We can put this in a schema/ directory, outside of HTML Purifier. The serialized
|
|
||||||
data gets treated like entities.ser.
|
|
||||||
|
|
||||||
The final thing that needs to be handled is user defined configurations.
|
|
||||||
They can be added at runtime using ConfigSchema::registerDirectory()
|
|
||||||
which globs the directory and grabs all of the directives to be incorporated
|
|
||||||
in. Then, the result is saved. We may want to take advantage of the
|
|
||||||
DefinitionCache framework, although it is not altogether certain what
|
|
||||||
configuration directives would be used to generate our key (meta-directives!)
|
|
||||||
|
|
||||||
Further thoughts
|
|
||||||
----------------
|
|
||||||
Our master configuration schema will only need to be updated once
|
|
||||||
every new version, so it's easily versionable. User specified
|
|
||||||
schema files are far more volatile, but it's far too expensive
|
|
||||||
to check the filemtimes of all the files, so a DefinitionRev style
|
|
||||||
mechanism works better. However, we can uniquely identify the
|
|
||||||
schema based on the directories they loaded, so there's no need
|
|
||||||
for a DefinitionId until we give them full programmatic control.
|
|
||||||
|
|
||||||
These variables should be directly incorporated into ConfigSchema,
|
|
||||||
and ConfigSchema should handle serialization. Some refactoring will be
|
|
||||||
necessary for the DefinitionCache classes, as they are built with
|
|
||||||
Config in mind. If the user changes something, the cache file gets
|
|
||||||
rebuilt. If the version changes, the cache file gets rebuilt. Since
|
|
||||||
our unit tests flush the caches before we start, and the operation is
|
|
||||||
pretty fast, this will not negatively impact unit testing.
|
|
||||||
|
|
||||||
One last thing: certain configuration directives require that files
|
|
||||||
get added. They may even be specified dynamically. It is not a good idea
|
|
||||||
for the HTMLPurifier_Config object to be used directly for such matters.
|
|
||||||
Instead, the userland code should explicitly perform the includes. We may
|
|
||||||
put in something like:
|
|
||||||
|
|
||||||
REQUIRES: HTMLPurifier_Filter_ExtractStyleBlocks
|
|
||||||
|
|
||||||
To indicate that if that class doesn't exist, and the user is attempting
|
|
||||||
to use the directive, we should fatally error out. The stub includes the core files,
|
|
||||||
and the user includes everything else. Any reflective things like new
|
|
||||||
$class would be required to tie in with the configuration.
|
|
||||||
|
|
||||||
It would work very well with rarely used configuration options, but it
|
|
||||||
wouldn't be so good for "core" parts that can be disabled. In such cases
|
|
||||||
the core include file would need to be modified, and the only way
|
|
||||||
to properly do this is use the configuration object. Once again, our
|
|
||||||
ability to create cache keys saves the day again: we can create arbitrary
|
|
||||||
stub files for arbitrary configurations and include those. They could
|
|
||||||
even be the single file affairs. The only thing we'd need to include,
|
|
||||||
then, would be HTMLPurifier_Config! Then, the configuration object would
|
|
||||||
load the library.
|
|
||||||
|
|
||||||
An aside...
|
|
||||||
-----------
|
|
||||||
One questions, however, the wisdom of letting PHP files write other PHP
|
|
||||||
files. It seems like a recipe for disaster, or at least lots of headaches
|
|
||||||
in highly secured setups, where PHP does not have the ability to write
|
|
||||||
to its root. In such cases, we could use sticky bits or tell the user
|
|
||||||
to manually generate the file.
|
|
||||||
|
|
||||||
The other troublesome bit is actually doing the calculations necessary.
|
|
||||||
For certain cases, it's simple (such as URIScheme), but for AttrDef
|
|
||||||
and HTMLModule the dependency trees are very complex in relation to
|
|
||||||
%HTML.Allowed and friends. I think that this idea should be shelved
|
|
||||||
and looked at a later, less insane date.
|
|
||||||
|
|
||||||
An interesting dilemma presents itself when a configuration form is offered
|
|
||||||
to the user. Normally, the configuration object is not accessible without
|
|
||||||
editing PHP code; this facility changes thing. The sensible thing to do
|
|
||||||
is stipulate that all classes required by the directives you allow must
|
|
||||||
be included.
|
|
||||||
|
|
||||||
Unit testing
|
|
||||||
------------
|
|
||||||
|
|
||||||
Setting up the parsing and translation into our existing format would not
|
|
||||||
be difficult to do. It might represent a good time for us to rethink our
|
|
||||||
tests for these facilities; as creative as they are, they are often hacky
|
|
||||||
and require public visibility for things that ought to be protected.
|
|
||||||
This is especially applicable for our DefinitionCache tests.
|
|
||||||
|
|
||||||
Migration
|
|
||||||
---------
|
|
||||||
|
|
||||||
Because we are not *adding* anything essentially new, it should be trivial
|
|
||||||
to write a script to take our existing data and dump it into the new format.
|
|
||||||
Well, not trivial, but fairly easy to accomplish. Primary implementation
|
|
||||||
difficulties would probably involve formatting the file nicely.
|
|
||||||
|
|
||||||
Backwards-compatibility
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
I expect that the ConfigSchema methods should stick around for a little bit,
|
|
||||||
but display E_USER_NOTICE warnings that they are deprecated. This will
|
|
||||||
require documentation!
|
|
||||||
|
|
||||||
New stuff
|
|
||||||
---------
|
|
||||||
|
|
||||||
VERSION: Version number directive was introduced
|
|
||||||
DEPRECATED-VERSION: If the directive was deprecated, when was it deprecated?
|
|
||||||
DEPRECATED-USE: If the directive was deprecated, what should the user use now?
|
|
||||||
REQUIRES: What classes does this configuration directive require, but are
|
|
||||||
not part of the HTML Purifier core?
|
|
@@ -77,4 +77,6 @@ help you find the correct functionality more quickly. Here they are:</p>
|
|||||||
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -23,8 +23,11 @@ that itch, put it here!</p>
|
|||||||
<ul>
|
<ul>
|
||||||
<li>Make Tokens Flyweights (may prove problematic, probably not worth it)</li>
|
<li>Make Tokens Flyweights (may prove problematic, probably not worth it)</li>
|
||||||
<li>Rewrite regexps into PHP code</li>
|
<li>Rewrite regexps into PHP code</li>
|
||||||
|
<li>Serialize the Definition object</li>
|
||||||
<li>Batch regexp validation (do as many per function call as possible)</li>
|
<li>Batch regexp validation (do as many per function call as possible)</li>
|
||||||
<li>Parallelize strategies</li>
|
<li>Parallelize strategies</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -34,11 +34,6 @@ thead th {text-align:left;padding:0.1em;background-color:#EEE;}
|
|||||||
<div id="index">Return to the <a href="index.html">index</a>.</div>
|
<div id="index">Return to the <a href="index.html">index</a>.</div>
|
||||||
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
<div id="home"><a href="http://htmlpurifier.org/">HTML Purifier</a> End-User Documentation</div>
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>Warning:</strong> This table is kept for historical purposes and
|
|
||||||
is not being actively updated.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Key</h2>
|
<h2>Key</h2>
|
||||||
|
|
||||||
<table cellspacing="0"><tbody>
|
<table cellspacing="0"><tbody>
|
||||||
@@ -153,7 +148,7 @@ thead th {text-align:left;padding:0.1em;background-color:#EEE;}
|
|||||||
Depends on background-image</td></tr>
|
Depends on background-image</td></tr>
|
||||||
<tr class="css1 impl-yes"><td>background-position</td><td>Depends on background-image</td></tr>
|
<tr class="css1 impl-yes"><td>background-position</td><td>Depends on background-image</td></tr>
|
||||||
<tr class="danger impl-no"><td>cursor</td><td>Dangerous but fluffy</td></tr>
|
<tr class="danger impl-no"><td>cursor</td><td>Dangerous but fluffy</td></tr>
|
||||||
<tr class="danger impl-yes"><td>display</td><td>ENUM(...), Dangerous but interesting;
|
<tr class="danger css1"><td>display</td><td>ENUM(...), Dangerous but interesting;
|
||||||
will not implement list-item, run-in (Opera only) or table (no IE);
|
will not implement list-item, run-in (Opera only) or table (no IE);
|
||||||
inline-block has incomplete IE6 support and requires -moz-inline-box
|
inline-block has incomplete IE6 support and requires -moz-inline-box
|
||||||
for Mozilla. Unknown target milestone.</td></tr>
|
for Mozilla. Unknown target milestone.</td></tr>
|
||||||
@@ -172,7 +167,7 @@ thead th {text-align:left;padding:0.1em;background-color:#EEE;}
|
|||||||
Mostly supported. Unknown target milestone.</td></tr>
|
Mostly supported. Unknown target milestone.</td></tr>
|
||||||
<tr><td>page-break-inside</td><td>ENUM(avoid, auto), Opera only. Unknown target milestone.</td></tr>
|
<tr><td>page-break-inside</td><td>ENUM(avoid, auto), Opera only. Unknown target milestone.</td></tr>
|
||||||
<tr class="impl-no"><td>quotes</td><td>May be dropped from CSS2, fairly useless for inline context</td></tr>
|
<tr class="impl-no"><td>quotes</td><td>May be dropped from CSS2, fairly useless for inline context</td></tr>
|
||||||
<tr class="danger impl-yes"><td>visibility</td><td>ENUM(visible, hidden, collapse),
|
<tr class="impl-no"><td>visibility</td><td>ENUM(visible, hidden, collapse),
|
||||||
Dangerous</td></tr>
|
Dangerous</td></tr>
|
||||||
<tr class="css1 feature impl-partial"><td>white-space</td><td>ENUM(normal, pre, nowrap, pre-wrap,
|
<tr class="css1 feature impl-partial"><td>white-space</td><td>ENUM(normal, pre, nowrap, pre-wrap,
|
||||||
pre-line), Spotty implementation:
|
pre-line), Spotty implementation:
|
||||||
@@ -303,4 +298,6 @@ Mozilla on inside and needs -moz-outline, no IE support.</td></tr>
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -158,7 +158,7 @@
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
$def = $config->getHTMLDefinition(true);</pre>
|
$def =& $config->getHTMLDefinition(true);</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Assuming that HTML Purifier has already been properly loaded (hint:
|
Assuming that HTML Purifier has already been properly loaded (hint:
|
||||||
@@ -213,8 +213,8 @@ $def = $config->getHTMLDefinition(true);</pre>
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
<strong>$config->set('Cache', 'DefinitionImpl', null); // remove this later!</strong>
|
<strong>$config->set('Core', 'DefinitionCache', null); // remove this later!</strong>
|
||||||
$def = $config->getHTMLDefinition(true);</pre>
|
$def =& $config->getHTMLDefinition(true);</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A few things should be mentioned about the caching mechanism before
|
A few things should be mentioned about the caching mechanism before
|
||||||
@@ -269,8 +269,8 @@ $def = $config->getHTMLDefinition(true);</pre>
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
$config->set('Cache', 'DefinitionImpl', null); // remove this later!
|
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
||||||
$def = $config->getHTMLDefinition(true);
|
$def =& $config->getHTMLDefinition(true);
|
||||||
<strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong></pre>
|
<strong>$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');</strong></pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -372,10 +372,10 @@ $def = $config->getHTMLDefinition(true);
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
For a complete list, consult
|
For a complete list, consult
|
||||||
<a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/AttrTypes.php"><code>library/HTMLPurifier/AttrTypes.php</code></a>;
|
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/AttrTypes.php"><code>library/HTMLPurifier/AttrTypes.php</code></a>;
|
||||||
more information on attributes that accept parameters can be found on their
|
more information on attributes that accept parameters can be found on their
|
||||||
respective includes in
|
respective includes in
|
||||||
<a href="http://repo.or.cz/w/htmlpurifier.git?a=tree;hb=HEAD;f=library/HTMLPurifier/AttrDef"><code>library/HTMLPurifier/AttrDef</code></a>.
|
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/AttrDef/"><code>library/HTMLPurifier/AttrDef</code></a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -387,8 +387,8 @@ $def = $config->getHTMLDefinition(true);
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
$config->set('Cache', 'DefinitionImpl', null); // remove this later!
|
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
||||||
$def = $config->getHTMLDefinition(true);
|
$def =& $config->getHTMLDefinition(true);
|
||||||
<strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
<strong>$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||||
array('_blank','_self','_target','_top')
|
array('_blank','_self','_target','_top')
|
||||||
));</strong></pre>
|
));</strong></pre>
|
||||||
@@ -734,12 +734,12 @@ $def = $config->getHTMLDefinition(true);
|
|||||||
<pre>$config = HTMLPurifier_Config::createDefault();
|
<pre>$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
$config->set('HTML', 'DefinitionID', 'enduser-customize.html tutorial');
|
||||||
$config->set('HTML', 'DefinitionRev', 1);
|
$config->set('HTML', 'DefinitionRev', 1);
|
||||||
$config->set('Cache', 'DefinitionImpl', null); // remove this later!
|
$config->set('Core', 'DefinitionCache', null); // remove this later!
|
||||||
$def = $config->getHTMLDefinition(true);
|
$def =& $config->getHTMLDefinition(true);
|
||||||
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
|
||||||
array('_blank','_self','_target','_top')
|
array('_blank','_self','_target','_top')
|
||||||
));
|
));
|
||||||
<strong>$form = $def->addElement(
|
<strong>$form =& $def->addElement(
|
||||||
'form', // name
|
'form', // name
|
||||||
'Block', // content set
|
'Block', // content set
|
||||||
'Flow', // allowed children
|
'Flow', // allowed children
|
||||||
@@ -764,7 +764,7 @@ $form->excludes = array('form' => true);</strong></pre>
|
|||||||
<p>
|
<p>
|
||||||
And that's all there is to it! Implementing the rest of the form
|
And that's all there is to it! Implementing the rest of the form
|
||||||
module is left as an exercise to the user; to see more examples
|
module is left as an exercise to the user; to see more examples
|
||||||
check the <a href="http://repo.or.cz/w/htmlpurifier.git?a=tree;hb=HEAD;f=library/HTMLPurifier/HTMLModule"><code>library/HTMLPurifier/HTMLModule/</code></a> directory
|
check the <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/HTMLModule/"><code>library/HTMLPurifier/HTMLModule/</code></a> directory
|
||||||
in your local HTML Purifier installation.
|
in your local HTML Purifier installation.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -789,8 +789,10 @@ $form->excludes = array('form' => true);</strong></pre>
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/HTMLModule.php"><code>library/HTMLPurifier/HTMLModule.php</code></a></li>
|
<li><a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/HTMLModule.php"><code>library/HTMLPurifier/HTMLModule.php</code></a></li>
|
||||||
<li><a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/ElementDef.php"><code>library/HTMLPurifier/ElementDef.php</code></a></li>
|
<li><a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/ElementDef.php"><code>library/HTMLPurifier/ElementDef.php</code></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<div id="version">$Id: enduser-tidy.html 1158 2007-06-18 19:26:29Z Edward $</div>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -141,5 +141,7 @@ anchors is beyond me.</p>
|
|||||||
|
|
||||||
<p>Don't come crying to me when your page mysteriously stops validating, though.</p>
|
<p>Don't come crying to me when your page mysteriously stops validating, though.</p>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -225,4 +225,6 @@ and if that still doesn't satisfy your appetite, do some fine-tuning.
|
|||||||
Other than that, don't worry about it: this all works silently and
|
Other than that, don't worry about it: this all works silently and
|
||||||
effectively in the background.</p>
|
effectively in the background.</p>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -33,9 +33,9 @@
|
|||||||
|
|
||||||
<pre>class HTMLPurifier_URIFilter_<strong>NameOfFilter</strong> extends HTMLPurifier_URIFilter
|
<pre>class HTMLPurifier_URIFilter_<strong>NameOfFilter</strong> extends HTMLPurifier_URIFilter
|
||||||
{
|
{
|
||||||
public $name = '<strong>NameOfFilter</strong>';
|
var $name = '<strong>NameOfFilter</strong>';
|
||||||
public function prepare($config) {}
|
function prepare($config) {}
|
||||||
public function filter(&$uri, $config, $context) {}
|
function filter(&$uri, $config, &$context) {}
|
||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -56,12 +56,12 @@
|
|||||||
|
|
||||||
<pre>class HTMLPurifier_URI
|
<pre>class HTMLPurifier_URI
|
||||||
{
|
{
|
||||||
public $scheme, $userinfo, $host, $port, $path, $query, $fragment;
|
var $scheme, $userinfo, $host, $port, $path, $query, $fragment;
|
||||||
public function HTMLPurifier_URI($scheme, $userinfo, $host, $port, $path, $query, $fragment);
|
function HTMLPurifier_URI($scheme, $userinfo, $host, $port, $path, $query, $fragment);
|
||||||
public function toString();
|
function toString();
|
||||||
public function copy();
|
function copy();
|
||||||
public function getSchemeObj($config, $context);
|
function getSchemeObj($config, &$context);
|
||||||
public function validate($config, $context);
|
function validate($config, &$context);
|
||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -130,26 +130,30 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Let's suppose I wanted to write a filter that converted links with a
|
Let's suppose I wanted to write a filter that de-internationalized domain
|
||||||
custom <code>image</code> scheme to its corresponding real path on
|
names by converting them to <a href="http://en.wikipedia.org/wiki/Punycode">Punycode</a>.
|
||||||
our website:
|
Assuming that <code>punycode_encode($input)</code> converts <code>$input</code> to
|
||||||
|
Punycode and returns <code>false</code> on failure:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>class HTMLPurifier_URIFilter_TransformImageScheme extends HTMLPurifier_URIFilter
|
<pre>class HTMLPurifier_URIFilter_ConvertIDNToPunycode extends HTMLPurifier_URIFilter
|
||||||
{
|
{
|
||||||
public $name = 'TransformImageScheme';
|
var $name = 'ConvertIDNToPunycode';
|
||||||
public function filter(&$uri, $config, $context) {
|
function filter(&$uri, $config, &$context) {
|
||||||
if ($uri->scheme !== 'image') return true;
|
if (is_null($uri->host)) return true;
|
||||||
$img_name = $uri->path;
|
if ($uri->host == utf8_decode($uri->host)) {
|
||||||
// Overwrite the previous URI object
|
// is ASCII, abort
|
||||||
$uri = new HTMLPurifier_URI('http', null, null, null, '/img/' . $img_name . '.png', null, null);
|
return true;
|
||||||
|
}
|
||||||
|
$host = punycode_encode($uri->host);
|
||||||
|
if ($host === false) return false;
|
||||||
|
$uri->host = $host;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Notice I did not <code>return $uri;</code>. This filter would turn
|
Notice I did not <code>return $uri;</code>.
|
||||||
<code>image:Foo</code> into <code>/img/Foo.png</code>.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Activating your filter</h2>
|
<h2>Activating your filter</h2>
|
||||||
@@ -159,7 +163,7 @@
|
|||||||
to use it. Fortunately, this part's simple:
|
to use it. Fortunately, this part's simple:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>$uri = $config->getDefinition('URI');
|
<pre>$uri =& $config->getDefinition('URI');
|
||||||
$uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pre>
|
$uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -173,7 +177,7 @@ $uri->addFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());</pr
|
|||||||
'URI', '<strong>NameOfFilter</strong>', false, 'bool',
|
'URI', '<strong>NameOfFilter</strong>', false, 'bool',
|
||||||
'<strong>What your filter does.</strong>'
|
'<strong>What your filter does.</strong>'
|
||||||
);
|
);
|
||||||
$uri = $config->getDefinition('URI', true);
|
$uri =& $config->getDefinition('URI', true);
|
||||||
$uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());
|
$uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>());
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -182,33 +186,16 @@ $uri->registerFilter(new HTMLPurifier_URIFilter_<strong>NameOfFilter</strong>())
|
|||||||
is set to true.
|
is set to true.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Post-filter</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Remember our TransformImageScheme filter? That filter acted before we had
|
|
||||||
performed scheme validation; otherwise, the URI would have been filtered
|
|
||||||
out when it was discovered that there was no image scheme. Well, a post-filter
|
|
||||||
is run after scheme specific validation, so it's ideal for bulk
|
|
||||||
post-processing of URIs, including munging. To specify a URI as a post-filter,
|
|
||||||
set the <code>$post</code> member variable to TRUE.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>class HTMLPurifier_URIFilter_MyPostFilter extends HTMLPurifier_URIFilter
|
|
||||||
{
|
|
||||||
public $name = 'MyPostFilter';
|
|
||||||
public $post = true;
|
|
||||||
// ... extra code here
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h2>Examples</h2>
|
<h2>Examples</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Check the
|
Check the
|
||||||
<a href="http://repo.or.cz/w/htmlpurifier.git?a=tree;hb=HEAD;f=library/HTMLPurifier/URIFilter">URIFilter</a>
|
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/URIFilter/">URIFilter</a>
|
||||||
directory for more implementation examples, and see <a href="proposal-new-directives.txt">the
|
directory for more implementation examples, and see <a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/docs/proposal-new-directives.txt">the
|
||||||
new directives proposal document</a> for ideas on what could be implemented
|
new directives proposal document</a> for ideas on what could be implemented
|
||||||
as a filter.
|
as a filter.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<meta name="description" content="Describes the rationale for using UTF-8, the ramifications otherwise, and how to make the switch." />
|
<meta name="description" content="Describes the rationale for using UTF-8, the ramifications otherwise, and how to make the switch." />
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css" />
|
<link rel="stylesheet" type="text/css" href="./style.css" />
|
||||||
|
<script defer="defer" type="text/javascript" src="./toc-gen.js"></script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.minor td {font-style:italic;}
|
.minor td {font-style:italic;}
|
||||||
</style>
|
</style>
|
||||||
@@ -118,8 +119,9 @@ there are now many character encodings floating around.</p>
|
|||||||
see a page on the web, chances are it's encoded in one
|
see a page on the web, chances are it's encoded in one
|
||||||
of these encodings.</li>
|
of these encodings.</li>
|
||||||
<li><strong>Unicode-based encodings</strong> implement the
|
<li><strong>Unicode-based encodings</strong> implement the
|
||||||
Unicode standard and include UTF-8, UTF-16 and UTF-32/UCS-4.
|
Unicode standard and include UTF-8, UCS-2 and UTF-16.
|
||||||
They go beyond 8-bits and support almost
|
They go beyond 8-bits (the first two are variable length,
|
||||||
|
while the second one uses 16-bits), and support almost
|
||||||
every language in the world. UTF-8 is gaining traction
|
every language in the world. UTF-8 is gaining traction
|
||||||
as the dominant international encoding of the web.</li>
|
as the dominant international encoding of the web.</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -589,10 +591,8 @@ looks something like: <code>%C3%86</code>. There is no official way of
|
|||||||
determining the character encoding of such a request, since the percent
|
determining the character encoding of such a request, since the percent
|
||||||
encoding operates on a byte level, so it is usually assumed that it
|
encoding operates on a byte level, so it is usually assumed that it
|
||||||
is the same as the encoding the page containing the form was submitted
|
is the same as the encoding the page containing the form was submitted
|
||||||
in. (<a href="http://tools.ietf.org/html/rfc3986#section-2.5">RFC 3986</a>
|
in. You'll run into very few problems if you only use characters in
|
||||||
recommends that textual identifiers be translated to UTF-8; however, browser
|
the character encoding you chose.</p>
|
||||||
compliance is spotty.) You'll run into very few problems
|
|
||||||
if you only use characters in the character encoding you chose.</p>
|
|
||||||
|
|
||||||
<p>However, once you start adding characters outside of your encoding
|
<p>However, once you start adding characters outside of your encoding
|
||||||
(and this is a lot more common than you may think: take curly
|
(and this is a lot more common than you may think: take curly
|
||||||
|
@@ -70,12 +70,14 @@ into your documents. YouTube's code goes like this:</p>
|
|||||||
class="embed-youtube">AyPzM5WK8ys</span></code> your
|
class="embed-youtube">AyPzM5WK8ys</span></code> your
|
||||||
application can reconstruct the full object from this small snippet that
|
application can reconstruct the full object from this small snippet that
|
||||||
passes through HTML Purifier <em>unharmed</em>.
|
passes through HTML Purifier <em>unharmed</em>.
|
||||||
<a href="http://repo.or.cz/w/htmlpurifier.git?a=blob;hb=HEAD;f=library/HTMLPurifier/Filter/YouTube.php">Show me the code!</a></p>
|
<a href="http://htmlpurifier.org/svnroot/htmlpurifier/trunk/library/HTMLPurifier/Filter/YouTube.php">Show me the code!</a></p>
|
||||||
|
|
||||||
<p>And the corresponding usage:</p>
|
<p>And the corresponding usage:</p>
|
||||||
|
|
||||||
<pre><?php
|
<pre><?php
|
||||||
$config->set('Filter', 'YouTube', true);
|
// assuming $purifier is an instance of HTMLPurifier
|
||||||
|
require_once 'HTMLPurifier/Filter/YouTube.php';
|
||||||
|
$purifier->addFilter(new HTMLPurifier_Filter_YouTube());
|
||||||
?></pre>
|
?></pre>
|
||||||
|
|
||||||
<p>There is a bit going in the two code snippets, so let's explain.</p>
|
<p>There is a bit going in the two code snippets, so let's explain.</p>
|
||||||
|
@@ -60,16 +60,10 @@ conventions.</p>
|
|||||||
<dt><a href="dev-optimization.html">Optimization</a></dt>
|
<dt><a href="dev-optimization.html">Optimization</a></dt>
|
||||||
<dd>Discusses possible methods of optimizing HTML Purifier.</dd>
|
<dd>Discusses possible methods of optimizing HTML Purifier.</dd>
|
||||||
|
|
||||||
<dt><a href="dev-flush.html">Flushing the Purifier</a></dt>
|
|
||||||
<dd>Discusses when to flush HTML Purifier's various caches.</dd>
|
|
||||||
|
|
||||||
<dt><a href="dev-advanced-api.html">Advanced API</a></dt>
|
<dt><a href="dev-advanced-api.html">Advanced API</a></dt>
|
||||||
<dd>Specification for HTML Purifier's advanced API for defining
|
<dd>Functional specification for HTML Purifier's advanced API for defining
|
||||||
custom filtering behavior.</dd>
|
custom filtering behavior.</dd>
|
||||||
|
|
||||||
<dt><a href="dev-config-schema.html">Config Schema</a></dt>
|
|
||||||
<dd>Describes config schema framework in HTML Purifier.</dd>
|
|
||||||
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h2>Proposals</h2>
|
<h2>Proposals</h2>
|
||||||
@@ -98,8 +92,8 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
|
|
||||||
<thead><tr>
|
<thead><tr>
|
||||||
<th style="width:10%">Type</th>
|
<th width="10%">Type</th>
|
||||||
<th style="width:20%">Name</th>
|
<th width="20%">Name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
|
|
||||||
@@ -119,7 +113,7 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Development</td>
|
<td>Development</td>
|
||||||
<td><a href="dev-code-quality.txt">Code Quality Issues</a></td>
|
<td><a href="enduser-code-quality.txt">Code Quality Issues</a></td>
|
||||||
<td>Enumerates code quality issues and places that need to be refactored.</td>
|
<td>Enumerates code quality issues and places that need to be refactored.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -141,12 +135,6 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
|||||||
<td>Assorted configuration options that could be implemented.</td>
|
<td>Assorted configuration options that could be implemented.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>Proposal</td>
|
|
||||||
<td><a href="proposal-css-extraction.txt">CSS extraction</a></td>
|
|
||||||
<td>Taking the inline CSS out of documents and into <code>style</code>.</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Reference</td>
|
<td>Reference</td>
|
||||||
<td><a href="ref-content-models.txt">Handling Content Model Changes</a></td>
|
<td><a href="ref-content-models.txt">Handling Content Model Changes</a></td>
|
||||||
@@ -175,5 +163,6 @@ the code. They may be upgraded to HTML files or stay as TXT scratchpads.</p>
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -42,5 +42,7 @@ into the mix.</li>
|
|||||||
something like that?</li>
|
something like that?</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
Extracting inline CSS from HTML Purifier
|
|
||||||
voodoofied: Assigning semantics to elements
|
|
||||||
|
|
||||||
Sander Tekelenburg brought to my attention the poor programming style of
|
|
||||||
inline CSS in HTML documents. In an ideal world, we wouldn't be using inline
|
|
||||||
CSS at all: everything would be assigned using semantic class attributes
|
|
||||||
from an external stylesheet.
|
|
||||||
|
|
||||||
With ExtractStyleBlocks and CSSTidy, this is now possible (when allowed, users
|
|
||||||
can specify a style element which gets extracted from the user-submitted HTML, which
|
|
||||||
the application can place in the head of the HTML document). But there still
|
|
||||||
is the issue of inline CSS that refuses to go away.
|
|
||||||
|
|
||||||
The basic idea behind this feature is assign every element a unique identifier,
|
|
||||||
and then move all of the CSS data to a style-sheet. This HTML:
|
|
||||||
|
|
||||||
<div style="text-align:center">Big <span style="color:red;">things</span>!</div>
|
|
||||||
|
|
||||||
into
|
|
||||||
|
|
||||||
<div id="hp-12345">Big <span id="hp-12346">things</span>!</div>
|
|
||||||
|
|
||||||
and a stylesheet that is:
|
|
||||||
|
|
||||||
#hp-12345 {text-align:center;}
|
|
||||||
#hp-12346 {color:red;}
|
|
||||||
|
|
||||||
Beyond that, HTML Purifier can magically merge common CSS values together,
|
|
||||||
and a whole manner of other heuristic things. HTML Purifier should also
|
|
||||||
make it easy for an admin to re-style the HTML semantically. Speed is not
|
|
||||||
an issue. Also, better WYSIWYG editors are needed.
|
|
@@ -1,209 +0,0 @@
|
|||||||
Considerations for ErrorCollection
|
|
||||||
|
|
||||||
Presently, HTML Purifier takes a code-execution centric approach to handling
|
|
||||||
errors. Errors are organized and grouped according to which segment of the
|
|
||||||
code triggers them, not necessarily the portion of the input document that
|
|
||||||
triggered the error. This means that errors are pseudo-sorted by category,
|
|
||||||
rather than location in the document.
|
|
||||||
|
|
||||||
One easy way to "fix" this problem would be to re-sort according to line number.
|
|
||||||
However, the "category" style information we derive from naively following
|
|
||||||
program execution is still useful. After all, each of the strategies which
|
|
||||||
can report errors still process the document mostly linearly. Furthermore,
|
|
||||||
not only do they process linearly, but the way they pass off operations to
|
|
||||||
sub-systems mirrors that of the document. For example, AttrValidator will
|
|
||||||
linearly proceed through elements, and on each element will use AttrDef to
|
|
||||||
validate those contents. From there, the attribute might have more
|
|
||||||
sub-components, which have execution passed off accordingly.
|
|
||||||
|
|
||||||
In fact, each strategy handles a very specific class of "error."
|
|
||||||
|
|
||||||
RemoveForeignElements - element tokens
|
|
||||||
MakeWellFormed - element token ordering
|
|
||||||
FixNesting - element token ordering
|
|
||||||
ValidateAttributes - attributes of elements
|
|
||||||
|
|
||||||
The crucial point is that while we care about the hierarchy governing these
|
|
||||||
different errors, we *don't* care about any other information about what actually
|
|
||||||
happens to the elements. This brings up another point: if HTML Purifier fixes
|
|
||||||
something, this is not really a notice/warning/error; it's really a suggestion
|
|
||||||
of a way to fix the aforementioned defects.
|
|
||||||
|
|
||||||
In short, the refactoring to take this into account kinda sucks.
|
|
||||||
|
|
||||||
Errors should not be recorded in order that they are reported. Instead, they
|
|
||||||
should be bound to the line (and preferably element) in which they were found.
|
|
||||||
This means we need some way to uniquely identify every element in the document,
|
|
||||||
which doesn't presently exist. An easy way of adding this would be to track
|
|
||||||
line columns. An important ramification of this is that we *must* use the
|
|
||||||
DirectLex implementation.
|
|
||||||
|
|
||||||
1. Implement column numbers for DirectLex [DONE!]
|
|
||||||
2. Disable error collection when not using DirectLex [DONE!]
|
|
||||||
|
|
||||||
Next, we need to re-orient all of the error declarations to place CurrentToken
|
|
||||||
at utmost important. Since this is passed via Context, it's not always clear
|
|
||||||
if that's available. ErrorCollector should complain HARD if it isn't available.
|
|
||||||
There are some locations when we don't have a token available. These include:
|
|
||||||
|
|
||||||
* Lexing - this can actually have a row and column, but NOT correspond to
|
|
||||||
a token
|
|
||||||
* End of document errors - bump this to the end
|
|
||||||
|
|
||||||
Actually, we *don't* have to complain if CurrentToken isn't available; we just
|
|
||||||
set it as a document-wide error. And actually, nothing needs to be done here.
|
|
||||||
|
|
||||||
Something interesting to consider is whether or not we care about the locations
|
|
||||||
of attributes and CSS properties, i.e. the sub-objects that compose these things.
|
|
||||||
In terms of consistency, at the very least attributes should have column/line
|
|
||||||
numbers attached to them. However, this may be overkill, as attributes are
|
|
||||||
uniquely identifiable. You could go even further, with CSS, but they are also
|
|
||||||
uniquely identifiable.
|
|
||||||
|
|
||||||
Bottom-line is, however, this information must be available, in form of the
|
|
||||||
CurrentAttribute and CurrentCssProperty (theoretical) context variables, and
|
|
||||||
it must be used to organize the errors that the sub-processes may throw.
|
|
||||||
There is also a hierarchy of sorts that may make merging this into one context
|
|
||||||
variable more sense, if it hadn't been for HTML's reasonably rigid structure.
|
|
||||||
A CSS property will never contain an HTML attribute. So we won't ever get
|
|
||||||
recursive relations, and having multiple depths won't ever make sense. Leave
|
|
||||||
this be.
|
|
||||||
|
|
||||||
We already have this information, and consequently, using start and end is
|
|
||||||
*unnecessary*, so long as the context variables are set appropriately. We don't
|
|
||||||
care if an error was thrown by an attribute transform or an attribute definition;
|
|
||||||
to the end user these are the same (for a developer, they are different, but
|
|
||||||
they're better off with a stack trace (which we should add support for) in such
|
|
||||||
cases).
|
|
||||||
|
|
||||||
3. Remove start()/end() code. Don't get rid of recursion, though [DONE]
|
|
||||||
4. Setup ErrorCollector to use context information to setup hierarchies.
|
|
||||||
This may require a different internal format. Use objects if it gets
|
|
||||||
complex. [DONE]
|
|
||||||
|
|
||||||
ASIDE
|
|
||||||
More on this topic: since we are now binding errors to lines
|
|
||||||
and columns, a particular error can have three relationships to that
|
|
||||||
specific location:
|
|
||||||
|
|
||||||
1. The token at that location directly
|
|
||||||
RemoveForeignElements
|
|
||||||
AttrValidator (transforms)
|
|
||||||
MakeWellFormed
|
|
||||||
2. A "component" of that token (i.e. attribute)
|
|
||||||
AttrValidator (removals)
|
|
||||||
3. A modification to that node (i.e. contents from start to end
|
|
||||||
token) as a whole
|
|
||||||
FixNesting
|
|
||||||
|
|
||||||
This needs to be marked accordingly. In the presentation, it might
|
|
||||||
make sense keep (3) separate, have (2) a sublist of (1). (1) can
|
|
||||||
be a closing tag, in which case (3) makes no sense at all, OR it
|
|
||||||
should be related with its opening tag (this may not necessarily
|
|
||||||
be possible before MakeWellFormed is run).
|
|
||||||
|
|
||||||
So, the line and column counts as our identifier, so:
|
|
||||||
|
|
||||||
$errors[$line][$col] = ...
|
|
||||||
|
|
||||||
Then, we need to identify case 1, 2 or 3. They are identified as
|
|
||||||
such:
|
|
||||||
|
|
||||||
1. Need some sort of semaphore in RemoveForeignElements, etc.
|
|
||||||
2. If CurrentAttr/CurrentCssProperty is non-null
|
|
||||||
3. Default (FixNesting, MakeWellFormed)
|
|
||||||
|
|
||||||
One consideration about (1) is that it usually is actually a
|
|
||||||
(3) modification, but we have no way of knowing about that because
|
|
||||||
of various optimizations. However, they can probably be treated
|
|
||||||
the same. The other difficulty is that (3) is never a line and
|
|
||||||
column; rather, it is a range (i.e. a duple) and telling the user
|
|
||||||
the very start of the range may confuse them. For example,
|
|
||||||
|
|
||||||
<b>Foo<div>bar</div></b>
|
|
||||||
^ ^
|
|
||||||
|
|
||||||
The node being operated on is <b>, so the error would be assigned
|
|
||||||
to the first caret, with a "node reorganized" error. Then, the
|
|
||||||
ChildDef would have submitted its own suggestions and errors with
|
|
||||||
regard to what's going in the internals. So I suppose this is
|
|
||||||
ok. :-)
|
|
||||||
|
|
||||||
Now, the structure of the earlier mentioned ... would be something
|
|
||||||
like this:
|
|
||||||
|
|
||||||
object {
|
|
||||||
type = (token|attr|property),
|
|
||||||
value, // appropriate for type
|
|
||||||
errors => array(),
|
|
||||||
sub-errors = [recursive],
|
|
||||||
}
|
|
||||||
|
|
||||||
This helps us keep things agnostic. It is also sufficiently complex
|
|
||||||
enough to warrant an object.
|
|
||||||
|
|
||||||
So, more wanking about the object format is in order. The way HTML Purifier is
|
|
||||||
currently setup, the only possible hierarchy is:
|
|
||||||
|
|
||||||
token -> attr -> css property
|
|
||||||
|
|
||||||
These relations do not exist all of the time; a comment or end token would not
|
|
||||||
ever have any attributes, and non-style attributes would never have CSS properties
|
|
||||||
associated with them.
|
|
||||||
|
|
||||||
I believe that it is worth supporting multiple paths. At some point, we might
|
|
||||||
have a hierarchy like:
|
|
||||||
|
|
||||||
* -> syntax
|
|
||||||
-> token -> attr -> css property
|
|
||||||
-> url
|
|
||||||
-> css stylesheet <style>
|
|
||||||
|
|
||||||
et cetera. Now, one of the practical implications of this is that every "node"
|
|
||||||
on our tree is well-defined, so in theory it should be possible to either 1.
|
|
||||||
create a separate class for each error struct, or 2. embed this information
|
|
||||||
directly into HTML Purifier's token stream. Embedding the information in the
|
|
||||||
token stream is not a terribly good idea, since tokens can be removed, etc.
|
|
||||||
So that leaves us with 1... and if we use a generic interface we can cut down
|
|
||||||
on a lot of code we might need. So let's leave it like this.
|
|
||||||
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
Then we setup suggestions.
|
|
||||||
|
|
||||||
5. Setup a separate error class which tells the user any modifications
|
|
||||||
HTML Purifier made.
|
|
||||||
|
|
||||||
Some information about this:
|
|
||||||
|
|
||||||
Our current paradigm is to tell the user what HTML Purifier did to the HTML.
|
|
||||||
This is the most natural mode of operation, since that's what HTML Purifier
|
|
||||||
is all about; it was not meant to be a validator.
|
|
||||||
|
|
||||||
However, most other people have experience dealing with a validator. In cases
|
|
||||||
where HTML Purifier unambiguously does the right thing, simply giving the user
|
|
||||||
the correct version isn't a bad idea, but problems arise when:
|
|
||||||
|
|
||||||
- The user has such bad HTML we do something odd, when we should have just
|
|
||||||
flagged the HTML as an error. Such examples are when we do things like
|
|
||||||
remove text from directly inside a <table> tag. It was probably meant to
|
|
||||||
be in a <td> tag or be outside the table, but we're not smart enough to
|
|
||||||
realize this so we just remove it. In such a case, we should tell the user
|
|
||||||
that there was foreign data in the table, but then we shouldn't "demand"
|
|
||||||
the user remove the data; it's more of a "here's a possible way of
|
|
||||||
rectifying the problem"
|
|
||||||
|
|
||||||
- Giving line context for input is hard enough, but feasible; giving output
|
|
||||||
line context will be extremely difficult due to shifting lines; we'd probably
|
|
||||||
have to track what the tokens are and then find the appropriate out context
|
|
||||||
and it's not guaranteed to work etc etc etc.
|
|
||||||
|
|
||||||
````````````
|
|
||||||
|
|
||||||
Don't forget to spruce up output.
|
|
||||||
|
|
||||||
6. Output needs to automatically give line and column numbers, basically
|
|
||||||
"at line" on steroids. Look at W3C's output; it's ok. [PARTIALLY DONE]
|
|
||||||
|
|
||||||
- We need a standard CSS to apply (check demo.css for some starting
|
|
||||||
styling; some buttons would also be hip)
|
|
@@ -40,5 +40,6 @@ the development of this library in these forum threads:</p>
|
|||||||
|
|
||||||
<p>...as well as any I may have forgotten.</p>
|
<p>...as well as any I may have forgotten.</p>
|
||||||
|
|
||||||
|
<div id="version">$Id$</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
The Modularization of HTMLDefinition in HTML Purifier
|
The Modularization of HTMLDefinition in HTML Purifier
|
||||||
|
|
||||||
WARNING: This document was drafted before the implementation of this
|
Todo for XHTML 1.1 support <http://www.w3.org/TR/xhtml11/changes.html>
|
||||||
system, and some implementation details may have evolved over time.
|
1. Support Ruby <http://www.w3.org/TR/2001/REC-ruby-20010531/>
|
||||||
|
|
||||||
HTML Purifier uses the modularization of XHTML
|
HTML Purifier uses the modularization of XHTML
|
||||||
<http://www.w3.org/TR/xhtml-modularization/> to organize the internals
|
<http://www.w3.org/TR/xhtml-modularization/> to organize the internals
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
Licensing of Specimens
|
Licensing of Specimens
|
||||||
|
|
||||||
Some files in this directory have different licenses:
|
Some files in this directory have different licenses:
|
||||||
|
|
||||||
windows-live-mail-desktop-beta.html - donated by laacz, public domain
|
windows-live-mail-desktop-beta.html - donated by laacz, public domain
|
||||||
img.png - LGPL, from <http://commons.wikimedia.org/wiki/Image:Pastille_chrome.png>
|
img.png - LGPL, from <http://commons.wikimedia.org/wiki/Image:Pastille_chrome.png>
|
||||||
|
|
||||||
All other files are by me, and are licensed under LGPL.
|
All other files are by me, and are licensed under LGPL.
|
@@ -1,129 +0,0 @@
|
|||||||
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
|
|
||||||
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
|
|
||||||
<!--[if !mso]>
|
|
||||||
<style>
|
|
||||||
v\:* {behavior:url(#default#VML);}
|
|
||||||
o\:* {behavior:url(#default#VML);}
|
|
||||||
w\:* {behavior:url(#default#VML);}
|
|
||||||
..shape {behavior:url(#default#VML);}
|
|
||||||
</style>
|
|
||||||
<![endif]-->
|
|
||||||
<style>
|
|
||||||
<!--
|
|
||||||
/* Font Definitions */
|
|
||||||
@font-face
|
|
||||||
{font-family:"Cambria Math";
|
|
||||||
panose-1:2 4 5 3 5 4 6 3 2 4;}
|
|
||||||
@font-face
|
|
||||||
{font-family:Calibri;
|
|
||||||
panose-1:2 15 5 2 2 2 4 3 2 4;}
|
|
||||||
@font-face
|
|
||||||
{font-family:Tahoma;
|
|
||||||
panose-1:2 11 6 4 3 5 4 4 2 4;}
|
|
||||||
@font-face
|
|
||||||
{font-family:Verdana;
|
|
||||||
panose-1:2 11 6 4 3 5 4 4 2 4;}
|
|
||||||
/* Style Definitions */
|
|
||||||
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
|
||||||
{margin:0cm;
|
|
||||||
margin-bottom:.0001pt;
|
|
||||||
font-size:10.0pt;
|
|
||||||
font-family:"Verdana","sans-serif";}
|
|
||||||
a:link, span.MsoHyperlink
|
|
||||||
{mso-style-priority:99;
|
|
||||||
color:blue;
|
|
||||||
text-decoration:underline;}
|
|
||||||
a:visited, span.MsoHyperlinkFollowed
|
|
||||||
{mso-style-priority:99;
|
|
||||||
color:purple;
|
|
||||||
text-decoration:underline;}
|
|
||||||
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
|
|
||||||
{mso-style-priority:99;
|
|
||||||
mso-style-link:"Balloon Text Char";
|
|
||||||
margin:0cm;
|
|
||||||
margin-bottom:.0001pt;
|
|
||||||
font-size:8.0pt;
|
|
||||||
font-family:"Tahoma","sans-serif";}
|
|
||||||
span.EmailStyle17
|
|
||||||
{mso-style-type:personal-compose;
|
|
||||||
font-family:"Verdana","sans-serif";
|
|
||||||
color:windowtext;}
|
|
||||||
span.BalloonTextChar
|
|
||||||
{mso-style-name:"Balloon Text Char";
|
|
||||||
mso-style-priority:99;
|
|
||||||
mso-style-link:"Balloon Text";
|
|
||||||
font-family:"Tahoma","sans-serif";}
|
|
||||||
..MsoChpDefault
|
|
||||||
{mso-style-type:export-only;}
|
|
||||||
@page Section1
|
|
||||||
{size:612.0pt 792.0pt;
|
|
||||||
margin:70.85pt 70.85pt 70.85pt 70.85pt;}
|
|
||||||
div.Section1
|
|
||||||
{page:Section1;}
|
|
||||||
-->
|
|
||||||
</style>
|
|
||||||
<!--[if gte mso 9]><xml>
|
|
||||||
<o:shapedefaults v:ext="edit" spidmax="2050" />
|
|
||||||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
|
||||||
<o:shapelayout v:ext="edit">
|
|
||||||
<o:idmap v:ext="edit" data="1" />
|
|
||||||
</o:shapelayout></xml><![endif]-->
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body lang=NL link=blue vlink=purple>
|
|
||||||
|
|
||||||
<div class=Section1>
|
|
||||||
|
|
||||||
<p class=MsoNormal><img width=1277 height=994 id="Picture_x0020_1"
|
|
||||||
src="cid:image001.png@01C8CBDF.5D1BAEE0"><o:p></o:p></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><o:p> </o:p></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><b>Name<o:p></o:p></b></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal>E-mail : <a href="mailto:mail@example.com"><span
|
|
||||||
style='color:windowtext'>mail@example.com</span></a><o:p></o:p></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><o:p> </o:p></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><b>Company<o:p></o:p></b></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal>Address 1<o:p></o:p></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal>Address 2<o:p></o:p></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><o:p> </o:p></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal>Telefoon : +xx xx xxx xxx xx <span style='color:black'><o:p></o:p></span></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><span lang=EN-US style='color:black'>Fax : +xx xx xxx xx xx<o:p></o:p></span></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><span lang=EN-US style='color:black'>Internet : </span><span
|
|
||||||
style='color:black'><a href="http://www.example.com/"><span lang=EN-US
|
|
||||||
style='color:black'>http://www.example.com</span></a></span><span
|
|
||||||
lang=EN-US style='color:black'><o:p></o:p></span></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><span lang=EN-US style='color:black'>Kamer van koophandel
|
|
||||||
xxxxxxxxx<o:p></o:p></span></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><span lang=EN-US style='color:black'><o:p> </o:p></span></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><span lang=EN-US style='font-size:7.5pt;color:black'>Op deze
|
|
||||||
e-mail is een disclaimer van toepassing, ga naar </span><span lang=EN-US
|
|
||||||
style='font-size:7.5pt'><a
|
|
||||||
href="http://www.example.com/disclaimer"><span
|
|
||||||
style='color:black'>www.example.com/disclaimer</span></a><br>
|
|
||||||
<span style='color:black'>A disclaimer is applicable to this email, please
|
|
||||||
refer to </span><a href="http://www.example.com/disclaimer"><span
|
|
||||||
style='color:black'>www.example.com/disclaimer</span></a><o:p></o:p></span></p>
|
|
||||||
|
|
||||||
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@@ -1,155 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filesystem tools not provided by default; can recursively create, copy
|
|
||||||
* and delete folders. Some template methods are provided for extensibility.
|
|
||||||
*
|
|
||||||
* @note This class must be instantiated to be used, although it does
|
|
||||||
* not maintain state.
|
|
||||||
*/
|
|
||||||
class FSTools
|
|
||||||
{
|
|
||||||
|
|
||||||
private static $singleton;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a global instance of FSTools
|
|
||||||
*/
|
|
||||||
static public function singleton() {
|
|
||||||
if (empty(FSTools::$singleton)) FSTools::$singleton = new FSTools();
|
|
||||||
return FSTools::$singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets our global singleton to something else; useful for overloading
|
|
||||||
* functions.
|
|
||||||
*/
|
|
||||||
static public function setSingleton($singleton) {
|
|
||||||
FSTools::$singleton = $singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively creates a directory
|
|
||||||
* @param string $folder Name of folder to create
|
|
||||||
* @note Adapted from the PHP manual comment 76612
|
|
||||||
*/
|
|
||||||
public function mkdirr($folder) {
|
|
||||||
$folders = preg_split("#[\\\\/]#", $folder);
|
|
||||||
$base = '';
|
|
||||||
for($i = 0, $c = count($folders); $i < $c; $i++) {
|
|
||||||
if(empty($folders[$i])) {
|
|
||||||
if (!$i) {
|
|
||||||
// special case for root level
|
|
||||||
$base .= DIRECTORY_SEPARATOR;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$base .= $folders[$i];
|
|
||||||
if(!is_dir($base)){
|
|
||||||
$this->mkdir($base);
|
|
||||||
}
|
|
||||||
$base .= DIRECTORY_SEPARATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy a file, or recursively copy a folder and its contents; modified
|
|
||||||
* 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) {
|
|
||||||
// Simple copy for a file
|
|
||||||
if (is_file($source)) {
|
|
||||||
return $this->copy($source, $dest);
|
|
||||||
}
|
|
||||||
// Make destination directory
|
|
||||||
if (!is_dir($dest)) {
|
|
||||||
$this->mkdir($dest);
|
|
||||||
}
|
|
||||||
// Loop through the folder
|
|
||||||
$dir = $this->dir($source);
|
|
||||||
while ( false !== ($entry = $dir->read()) ) {
|
|
||||||
// Skip pointers
|
|
||||||
if ($entry == '.' || $entry == '..') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!$this->copyable($entry)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Deep copy directories
|
|
||||||
if ($dest !== "$source/$entry") {
|
|
||||||
$this->copyr("$source/$entry", "$dest/$entry");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Clean up
|
|
||||||
$dir->close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overloadable function that tests a filename for copyability. By
|
|
||||||
* default, everything should be copied; you can restrict things to
|
|
||||||
* ignore hidden files, unreadable files, etc. This function
|
|
||||||
* applies to copyr().
|
|
||||||
*/
|
|
||||||
public function copyable($file) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a file, or a folder and its contents
|
|
||||||
* @note Adapted from http://aidanlister.com/repos/v/function.rmdirr.php
|
|
||||||
*/
|
|
||||||
public function rmdirr($dirname)
|
|
||||||
{
|
|
||||||
// Sanity check
|
|
||||||
if (!$this->file_exists($dirname)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simple delete for a file
|
|
||||||
if ($this->is_file($dirname) || $this->is_link($dirname)) {
|
|
||||||
return $this->unlink($dirname);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through the folder
|
|
||||||
$dir = $this->dir($dirname);
|
|
||||||
while (false !== $entry = $dir->read()) {
|
|
||||||
// Skip pointers
|
|
||||||
if ($entry == '.' || $entry == '..') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Recurse
|
|
||||||
$this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
$dir->close();
|
|
||||||
return $this->rmdir($dirname);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively globs a directory.
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
if ($sub_dirs === false) $sub_dirs = array();
|
|
||||||
foreach ($sub_dirs as $sub_dir) {
|
|
||||||
$sub_files = $this->globr($sub_dir, $pattern, $flags);
|
|
||||||
$files = array_merge($files, $sub_files);
|
|
||||||
}
|
|
||||||
return $files;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows for PHP functions to be called and be stubbed.
|
|
||||||
* @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) {
|
|
||||||
return call_user_func_array($name, $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,124 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a file in the filesystem
|
|
||||||
*
|
|
||||||
* @warning Be sure to distinguish between get() and write() versus
|
|
||||||
* read() and put(), the former operates on the entire file, while
|
|
||||||
* the latter operates on a handle.
|
|
||||||
*/
|
|
||||||
class FSTools_File
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Filename of file this object represents */
|
|
||||||
protected $name;
|
|
||||||
|
|
||||||
/** Handle for the file */
|
|
||||||
protected $handle = false;
|
|
||||||
|
|
||||||
/** Instance of FSTools for interfacing with filesystem */
|
|
||||||
protected $fs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filename of file you wish to instantiate.
|
|
||||||
* @note This file need not exist
|
|
||||||
*/
|
|
||||||
public function __construct($name, $fs = false) {
|
|
||||||
$this->name = $name;
|
|
||||||
$this->fs = $fs ? $fs : FSTools::singleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the filename of the file. */
|
|
||||||
public function getName() {return $this->name;}
|
|
||||||
|
|
||||||
/** Returns directory of the file without trailing slash */
|
|
||||||
public function getDirectory() {return $this->fs->dirname($this->name);}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the contents of a file
|
|
||||||
* @todo Throw an exception if file doesn't exist
|
|
||||||
*/
|
|
||||||
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) {
|
|
||||||
return $this->fs->file_put_contents($this->name, $contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Deletes the file */
|
|
||||||
public function delete() {
|
|
||||||
return $this->fs->unlink($this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if file exists and is a file. */
|
|
||||||
public function exists() {
|
|
||||||
return $this->fs->is_file($this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns last file modification time */
|
|
||||||
public function getMTime() {
|
|
||||||
return $this->fs->filemtime($this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Chmod a file
|
|
||||||
* @note We ignore errors because of some weird owner trickery due
|
|
||||||
* to SVN duality
|
|
||||||
*/
|
|
||||||
public function chmod($octal_code) {
|
|
||||||
return @$this->fs->chmod($this->name, $octal_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Opens file's handle */
|
|
||||||
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() {
|
|
||||||
if (!$this->handle) return false;
|
|
||||||
$status = $this->fs->fclose($this->handle);
|
|
||||||
$this->handle = false;
|
|
||||||
return $status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieves a line from an open file, with optional max length $length */
|
|
||||||
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() {
|
|
||||||
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) {
|
|
||||||
if (!$this->handle) $this->open('r');
|
|
||||||
return $this->fs->fread($this->handle, $length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Writes to an open file */
|
|
||||||
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() {
|
|
||||||
if (!$this->handle) return true;
|
|
||||||
return $this->fs->feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __destruct() {
|
|
||||||
if ($this->handle) $this->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Convenience file that registers autoload handler for HTML Purifier.
|
|
||||||
*
|
|
||||||
* @warning
|
|
||||||
* This autoloader does not contain the compatibility code seen in
|
|
||||||
* HTMLPurifier_Bootstrap; the user is expected to make any necessary
|
|
||||||
* changes to use this library.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (function_exists('spl_autoload_register')) {
|
|
||||||
spl_autoload_register(array('HTMLPurifierExtras', 'autoload'));
|
|
||||||
if (function_exists('__autoload')) {
|
|
||||||
// Be polite and ensure that userland autoload gets retained
|
|
||||||
spl_autoload_register('__autoload');
|
|
||||||
}
|
|
||||||
} elseif (!function_exists('__autoload')) {
|
|
||||||
function __autoload($class) {
|
|
||||||
return HTMLPurifierExtras::autoload($class);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Meta-class for HTML Purifier's extra class hierarchies, similar to
|
|
||||||
* HTMLPurifier_Bootstrap.
|
|
||||||
*/
|
|
||||||
class HTMLPurifierExtras
|
|
||||||
{
|
|
||||||
|
|
||||||
public static function autoload($class) {
|
|
||||||
$path = HTMLPurifierExtras::getPath($class);
|
|
||||||
if (!$path) return false;
|
|
||||||
require $path;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPath($class) {
|
|
||||||
if (
|
|
||||||
strncmp('FSTools', $class, 7) !== 0 &&
|
|
||||||
strncmp('ConfigDoc', $class, 9) !== 0
|
|
||||||
) return false;
|
|
||||||
// Custom implementations can go here
|
|
||||||
// Standard implementation:
|
|
||||||
return str_replace('_', '/', $class) . '.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,30 +0,0 @@
|
|||||||
|
|
||||||
HTML Purifier Extras
|
|
||||||
The Method Behind The Madness!
|
|
||||||
|
|
||||||
The extras/ folder in HTML Purifier contains--you guessed it--extra things
|
|
||||||
for HTML Purifier. Specifically, these are two extra libraries called
|
|
||||||
FSTools and ConfigSchema. They're extra for a reason: you don't need them
|
|
||||||
if you're using HTML Purifier for normal usage: filtering HTML. However,
|
|
||||||
if you're a developer, and would like to test HTML Purifier, or need to
|
|
||||||
use one of HTML Purifier's maintenance scripts, chances are they'll need
|
|
||||||
these libraries. Who knows: maybe you'll find them useful too!
|
|
||||||
|
|
||||||
Here are the libraries:
|
|
||||||
|
|
||||||
|
|
||||||
FSTools
|
|
||||||
-------
|
|
||||||
|
|
||||||
Short for File System Tools, this is a poor-man's object-oriented wrapper for
|
|
||||||
the filesystem. It currently consists of two classes:
|
|
||||||
|
|
||||||
- FSTools: This is a singleton that contains a manner of useful functions
|
|
||||||
such as recursive glob, directory removal, etc, as well as the ability
|
|
||||||
to call arbitrary native PHP functions through it like $FS->fopen(...).
|
|
||||||
This makes it a lot simpler to mock these filesystem calls for unit testing.
|
|
||||||
|
|
||||||
- FSTools_File: This object represents a single file, and has almost any
|
|
||||||
method imaginable one would need.
|
|
||||||
|
|
||||||
Check the files themselves for more information.
|
|
@@ -5,5 +5,5 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||||
require_once 'HTMLPurifier/Bootstrap.php';
|
require_once 'HTMLPurifier.php';
|
||||||
require_once 'HTMLPurifier.autoload.php';
|
|
||||||
|
@@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Convenience file that registers autoload handler for HTML Purifier.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (function_exists('spl_autoload_register') && function_exists('spl_autoload_unregister')) {
|
|
||||||
// We need unregister for our pre-registering functionality
|
|
||||||
HTMLPurifier_Bootstrap::registerAutoload();
|
|
||||||
if (function_exists('__autoload')) {
|
|
||||||
// Be polite and ensure that userland autoload gets retained
|
|
||||||
spl_autoload_register('__autoload');
|
|
||||||
}
|
|
||||||
} elseif (!function_exists('__autoload')) {
|
|
||||||
function __autoload($class) {
|
|
||||||
return HTMLPurifier_Bootstrap::autoload($class);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,20 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* Function wrapper for HTML Purifier for quick use.
|
||||||
* Defines a function wrapper for HTML Purifier for quick use.
|
* @note This function only includes the library when it is called. While
|
||||||
|
* this is efficient for instances when you only use HTML Purifier
|
||||||
|
* on a few of your pages, it murders bytecode caching. You still
|
||||||
|
* need to add HTML Purifier to your path.
|
||||||
* @note ''HTMLPurifier()'' is NOT the same as ''new HTMLPurifier()''
|
* @note ''HTMLPurifier()'' is NOT the same as ''new HTMLPurifier()''
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Purify HTML.
|
|
||||||
* @param $html String HTML to purify
|
|
||||||
* @param $config Configuration to use, can be any value accepted by
|
|
||||||
* HTMLPurifier_Config::create()
|
|
||||||
*/
|
|
||||||
function HTMLPurifier($html, $config = null) {
|
function HTMLPurifier($html, $config = null) {
|
||||||
static $purifier = false;
|
static $purifier = false;
|
||||||
if (!$purifier) {
|
if (!$purifier) {
|
||||||
|
require_once 'HTMLPurifier.php';
|
||||||
$purifier = new HTMLPurifier();
|
$purifier = new HTMLPurifier();
|
||||||
}
|
}
|
||||||
return $purifier->purify($html, $config);
|
return $purifier->purify($html, $config);
|
||||||
|
@@ -1,204 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* This file was auto-generated by generate-includes.php and includes all of
|
|
||||||
* the core files required by HTML Purifier. Use this if performance is a
|
|
||||||
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
|
|
||||||
* FILE, changes will be overwritten the next time the script is run.
|
|
||||||
*
|
|
||||||
* @version 3.2.0
|
|
||||||
*
|
|
||||||
* @warning
|
|
||||||
* You must *not* include any other HTML Purifier files before this file,
|
|
||||||
* because 'require' not 'require_once' is used.
|
|
||||||
*
|
|
||||||
* @warning
|
|
||||||
* This file requires that the include path contains the HTML Purifier
|
|
||||||
* library directory; this is not auto-set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
require 'HTMLPurifier.php';
|
|
||||||
require 'HTMLPurifier/AttrCollections.php';
|
|
||||||
require 'HTMLPurifier/AttrDef.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform.php';
|
|
||||||
require 'HTMLPurifier/AttrTypes.php';
|
|
||||||
require 'HTMLPurifier/AttrValidator.php';
|
|
||||||
require 'HTMLPurifier/Bootstrap.php';
|
|
||||||
require 'HTMLPurifier/Definition.php';
|
|
||||||
require 'HTMLPurifier/CSSDefinition.php';
|
|
||||||
require 'HTMLPurifier/ChildDef.php';
|
|
||||||
require 'HTMLPurifier/Config.php';
|
|
||||||
require 'HTMLPurifier/ConfigSchema.php';
|
|
||||||
require 'HTMLPurifier/ContentSets.php';
|
|
||||||
require 'HTMLPurifier/Context.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCache.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCacheFactory.php';
|
|
||||||
require 'HTMLPurifier/Doctype.php';
|
|
||||||
require 'HTMLPurifier/DoctypeRegistry.php';
|
|
||||||
require 'HTMLPurifier/ElementDef.php';
|
|
||||||
require 'HTMLPurifier/Encoder.php';
|
|
||||||
require 'HTMLPurifier/EntityLookup.php';
|
|
||||||
require 'HTMLPurifier/EntityParser.php';
|
|
||||||
require 'HTMLPurifier/ErrorCollector.php';
|
|
||||||
require 'HTMLPurifier/ErrorStruct.php';
|
|
||||||
require 'HTMLPurifier/Exception.php';
|
|
||||||
require 'HTMLPurifier/Filter.php';
|
|
||||||
require 'HTMLPurifier/Generator.php';
|
|
||||||
require 'HTMLPurifier/HTMLDefinition.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule.php';
|
|
||||||
require 'HTMLPurifier/HTMLModuleManager.php';
|
|
||||||
require 'HTMLPurifier/IDAccumulator.php';
|
|
||||||
require 'HTMLPurifier/Injector.php';
|
|
||||||
require 'HTMLPurifier/Language.php';
|
|
||||||
require 'HTMLPurifier/LanguageFactory.php';
|
|
||||||
require 'HTMLPurifier/Length.php';
|
|
||||||
require 'HTMLPurifier/Lexer.php';
|
|
||||||
require 'HTMLPurifier/PercentEncoder.php';
|
|
||||||
require 'HTMLPurifier/Strategy.php';
|
|
||||||
require 'HTMLPurifier/StringHash.php';
|
|
||||||
require 'HTMLPurifier/StringHashParser.php';
|
|
||||||
require 'HTMLPurifier/TagTransform.php';
|
|
||||||
require 'HTMLPurifier/Token.php';
|
|
||||||
require 'HTMLPurifier/TokenFactory.php';
|
|
||||||
require 'HTMLPurifier/URI.php';
|
|
||||||
require 'HTMLPurifier/URIDefinition.php';
|
|
||||||
require 'HTMLPurifier/URIFilter.php';
|
|
||||||
require 'HTMLPurifier/URIParser.php';
|
|
||||||
require 'HTMLPurifier/URIScheme.php';
|
|
||||||
require 'HTMLPurifier/URISchemeRegistry.php';
|
|
||||||
require 'HTMLPurifier/UnitConverter.php';
|
|
||||||
require 'HTMLPurifier/VarParser.php';
|
|
||||||
require 'HTMLPurifier/VarParserException.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/Enum.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/Integer.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/Lang.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/Switch.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/Text.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/URI.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Number.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/AlphaValue.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Background.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Border.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Color.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Composite.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Font.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Length.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/CSS/URI.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/Bool.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/Color.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/ID.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/Pixels.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/Length.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/LinkTypes.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/URI/Email.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/URI/Host.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/URI/IPv6.php';
|
|
||||||
require 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/Background.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/BdoDir.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/BgColor.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/BoolToCSS.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/Border.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/EnumToCSS.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/ImgRequired.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/ImgSpace.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/Input.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/Lang.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/Length.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/Name.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/SafeEmbed.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/SafeObject.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/SafeParam.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
|
|
||||||
require 'HTMLPurifier/AttrTransform/Textarea.php';
|
|
||||||
require 'HTMLPurifier/ChildDef/Chameleon.php';
|
|
||||||
require 'HTMLPurifier/ChildDef/Custom.php';
|
|
||||||
require 'HTMLPurifier/ChildDef/Empty.php';
|
|
||||||
require 'HTMLPurifier/ChildDef/Required.php';
|
|
||||||
require 'HTMLPurifier/ChildDef/Optional.php';
|
|
||||||
require 'HTMLPurifier/ChildDef/StrictBlockquote.php';
|
|
||||||
require 'HTMLPurifier/ChildDef/Table.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCache/Decorator.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCache/Null.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCache/Serializer.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
|
|
||||||
require 'HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Bdo.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/CommonAttributes.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Edit.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Forms.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Hypertext.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Image.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Legacy.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/List.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Name.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Object.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Presentation.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Proprietary.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Ruby.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/SafeEmbed.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/SafeObject.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Scripting.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tables.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Target.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Text.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Name.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
|
||||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
|
||||||
require 'HTMLPurifier/Injector/AutoParagraph.php';
|
|
||||||
require 'HTMLPurifier/Injector/DisplayLinkURI.php';
|
|
||||||
require 'HTMLPurifier/Injector/Linkify.php';
|
|
||||||
require 'HTMLPurifier/Injector/PurifierLinkify.php';
|
|
||||||
require 'HTMLPurifier/Injector/RemoveEmpty.php';
|
|
||||||
require 'HTMLPurifier/Injector/SafeObject.php';
|
|
||||||
require 'HTMLPurifier/Lexer/DOMLex.php';
|
|
||||||
require 'HTMLPurifier/Lexer/DirectLex.php';
|
|
||||||
require 'HTMLPurifier/Strategy/Composite.php';
|
|
||||||
require 'HTMLPurifier/Strategy/Core.php';
|
|
||||||
require 'HTMLPurifier/Strategy/FixNesting.php';
|
|
||||||
require 'HTMLPurifier/Strategy/MakeWellFormed.php';
|
|
||||||
require 'HTMLPurifier/Strategy/RemoveForeignElements.php';
|
|
||||||
require 'HTMLPurifier/Strategy/ValidateAttributes.php';
|
|
||||||
require 'HTMLPurifier/TagTransform/Font.php';
|
|
||||||
require 'HTMLPurifier/TagTransform/Simple.php';
|
|
||||||
require 'HTMLPurifier/Token/Comment.php';
|
|
||||||
require 'HTMLPurifier/Token/Tag.php';
|
|
||||||
require 'HTMLPurifier/Token/Empty.php';
|
|
||||||
require 'HTMLPurifier/Token/End.php';
|
|
||||||
require 'HTMLPurifier/Token/Start.php';
|
|
||||||
require 'HTMLPurifier/Token/Text.php';
|
|
||||||
require 'HTMLPurifier/URIFilter/DisableExternal.php';
|
|
||||||
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
|
|
||||||
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
|
|
||||||
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
|
|
||||||
require 'HTMLPurifier/URIFilter/Munge.php';
|
|
||||||
require 'HTMLPurifier/URIScheme/ftp.php';
|
|
||||||
require 'HTMLPurifier/URIScheme/http.php';
|
|
||||||
require 'HTMLPurifier/URIScheme/https.php';
|
|
||||||
require 'HTMLPurifier/URIScheme/mailto.php';
|
|
||||||
require 'HTMLPurifier/URIScheme/news.php';
|
|
||||||
require 'HTMLPurifier/URIScheme/nntp.php';
|
|
||||||
require 'HTMLPurifier/VarParser/Flexible.php';
|
|
||||||
require 'HTMLPurifier/VarParser/Native.php';
|
|
@@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Emulation layer for code that used kses(), substituting in HTML Purifier.
|
|
||||||
*/
|
|
||||||
|
|
||||||
require_once dirname(__FILE__) . '/HTMLPurifier.auto.php';
|
|
||||||
|
|
||||||
function kses($string, $allowed_html, $allowed_protocols = null) {
|
|
||||||
$config = HTMLPurifier_Config::createDefault();
|
|
||||||
$allowed_elements = array();
|
|
||||||
$allowed_attributes = array();
|
|
||||||
foreach ($allowed_html as $element => $attributes) {
|
|
||||||
$allowed_elements[$element] = true;
|
|
||||||
foreach ($attributes as $attribute => $x) {
|
|
||||||
$allowed_attributes["$element.$attribute"] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$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);
|
|
||||||
}
|
|
||||||
$purifier = new HTMLPurifier($config);
|
|
||||||
return $purifier->purify($string);
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Convenience stub file that adds HTML Purifier's library file to the path
|
|
||||||
* without any other side-effects.
|
|
||||||
*/
|
|
||||||
|
|
||||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
|
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*! @mainpage
|
/*!
|
||||||
|
* @mainpage
|
||||||
*
|
*
|
||||||
* HTML Purifier is an HTML filter that will take an arbitrary snippet of
|
* HTML Purifier is an HTML filter that will take an arbitrary snippet of
|
||||||
* HTML and rigorously test, validate and filter it into a version that
|
* HTML and rigorously test, validate and filter it into a version that
|
||||||
@@ -15,12 +16,14 @@
|
|||||||
* -# Generating HTML from the purified tokens.
|
* -# Generating HTML from the purified tokens.
|
||||||
*
|
*
|
||||||
* However, most users will only need to interface with the HTMLPurifier
|
* However, most users will only need to interface with the HTMLPurifier
|
||||||
* and HTMLPurifier_Config.
|
* class, so this massive amount of infrastructure is usually concealed.
|
||||||
|
* If you plan on working with the internals, be sure to include
|
||||||
|
* HTMLPurifier_ConfigSchema and HTMLPurifier_Config.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
HTML Purifier 3.2.0 - Standards Compliant HTML Filtering
|
HTML Purifier 2.1.5 - Standards Compliant HTML Filtering
|
||||||
Copyright (C) 2006-2008 Edward Z. Yang
|
Copyright (C) 2006-2007 Edward Z. Yang
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -37,6 +40,32 @@
|
|||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// constants are slow, but we'll make one exception
|
||||||
|
define('HTMLPURIFIER_PREFIX', dirname(__FILE__));
|
||||||
|
|
||||||
|
// every class has an undocumented dependency to these, must be included!
|
||||||
|
require_once 'HTMLPurifier/ConfigSchema.php'; // fatal errors if not included
|
||||||
|
require_once 'HTMLPurifier/Config.php';
|
||||||
|
require_once 'HTMLPurifier/Context.php';
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/Lexer.php';
|
||||||
|
require_once 'HTMLPurifier/Generator.php';
|
||||||
|
require_once 'HTMLPurifier/Strategy/Core.php';
|
||||||
|
require_once 'HTMLPurifier/Encoder.php';
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/ErrorCollector.php';
|
||||||
|
require_once 'HTMLPurifier/LanguageFactory.php';
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Core', 'CollectErrors', false, 'bool', '
|
||||||
|
Whether or not to collect errors found while filtering the document. This
|
||||||
|
is a useful way to give feedback to your users. <strong>Warning:</strong>
|
||||||
|
Currently this feature is very patchy and experimental, with lots of
|
||||||
|
possible error messages not yet implemented. It will not cause any problems,
|
||||||
|
but it may not help your users either. This directive has been available
|
||||||
|
since 2.0.0.
|
||||||
|
');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Facade that coordinates HTML Purifier's subsystems in order to purify HTML.
|
* Facade that coordinates HTML Purifier's subsystems in order to purify HTML.
|
||||||
*
|
*
|
||||||
@@ -46,36 +75,27 @@
|
|||||||
* -# Instance: new HTMLPurifier($config)
|
* -# Instance: new HTMLPurifier($config)
|
||||||
* -# Invocation: purify($html, $config)
|
* -# Invocation: purify($html, $config)
|
||||||
* These configurations are entirely independent of each other and
|
* These configurations are entirely independent of each other and
|
||||||
* are *not* merged (this behavior may change in the future).
|
* are *not* merged.
|
||||||
*
|
*
|
||||||
* @todo We need an easier way to inject strategies using the configuration
|
* @todo We need an easier way to inject strategies, it'll probably end
|
||||||
* object.
|
* up getting done through config though.
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier
|
class HTMLPurifier
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Version of HTML Purifier */
|
var $version = '2.1.5';
|
||||||
public $version = '3.2.0';
|
|
||||||
|
|
||||||
/** Constant with version of HTML Purifier */
|
var $config;
|
||||||
const VERSION = '3.2.0';
|
var $filters = array();
|
||||||
|
|
||||||
/** Global configuration object */
|
var $strategy, $generator;
|
||||||
public $config;
|
|
||||||
|
|
||||||
/** Array of extra HTMLPurifier_Filter objects to run on HTML, for backwards compatibility */
|
|
||||||
private $filters = array();
|
|
||||||
|
|
||||||
/** Single instance of HTML Purifier */
|
|
||||||
private static $instance;
|
|
||||||
|
|
||||||
protected $strategy, $generator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resultant HTMLPurifier_Context of last run purification. Is an array
|
* Resultant HTMLPurifier_Context of last run purification. Is an array
|
||||||
* of contexts if the last called method was purifyArray().
|
* of contexts if the last called method was purifyArray().
|
||||||
|
* @public
|
||||||
*/
|
*/
|
||||||
public $context;
|
var $context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the purifier.
|
* Initializes the purifier.
|
||||||
@@ -85,11 +105,12 @@ class HTMLPurifier
|
|||||||
* The parameter can also be any type that
|
* The parameter can also be any type that
|
||||||
* HTMLPurifier_Config::create() supports.
|
* HTMLPurifier_Config::create() supports.
|
||||||
*/
|
*/
|
||||||
public function __construct($config = null) {
|
function HTMLPurifier($config = null) {
|
||||||
|
|
||||||
$this->config = HTMLPurifier_Config::create($config);
|
$this->config = HTMLPurifier_Config::create($config);
|
||||||
|
|
||||||
$this->strategy = new HTMLPurifier_Strategy_Core();
|
$this->strategy = new HTMLPurifier_Strategy_Core();
|
||||||
|
$this->generator = new HTMLPurifier_Generator();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +118,7 @@ class HTMLPurifier
|
|||||||
* Adds a filter to process the output. First come first serve
|
* Adds a filter to process the output. First come first serve
|
||||||
* @param $filter HTMLPurifier_Filter object
|
* @param $filter HTMLPurifier_Filter object
|
||||||
*/
|
*/
|
||||||
public function addFilter($filter) {
|
function addFilter($filter) {
|
||||||
trigger_error('HTMLPurifier->addFilter() is deprecated, use configuration directives in the Filter namespace or Filter.Custom', E_USER_WARNING);
|
|
||||||
$this->filters[] = $filter;
|
$this->filters[] = $filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,9 +132,8 @@ class HTMLPurifier
|
|||||||
* that HTMLPurifier_Config::create() supports.
|
* that HTMLPurifier_Config::create() supports.
|
||||||
* @return Purified HTML
|
* @return Purified HTML
|
||||||
*/
|
*/
|
||||||
public function purify($html, $config = null) {
|
function purify($html, $config = null) {
|
||||||
|
|
||||||
// :TODO: make the config merge in, instead of replace
|
|
||||||
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
|
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
|
||||||
|
|
||||||
// implementation is partially environment dependant, partially
|
// implementation is partially environment dependant, partially
|
||||||
@@ -123,8 +142,8 @@ class HTMLPurifier
|
|||||||
|
|
||||||
$context = new HTMLPurifier_Context();
|
$context = new HTMLPurifier_Context();
|
||||||
|
|
||||||
// setup HTML generator
|
// our friendly neighborhood generator, all primed with configuration too!
|
||||||
$this->generator = new HTMLPurifier_Generator($config, $context);
|
$this->generator->generateFromTokens(array(), $config, $context);
|
||||||
$context->register('Generator', $this->generator);
|
$context->register('Generator', $this->generator);
|
||||||
|
|
||||||
// set up global context variables
|
// set up global context variables
|
||||||
@@ -145,25 +164,8 @@ class HTMLPurifier
|
|||||||
|
|
||||||
$html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
|
$html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
|
||||||
|
|
||||||
// setup filters
|
for ($i = 0, $size = count($this->filters); $i < $size; $i++) {
|
||||||
$filter_flags = $config->getBatch('Filter');
|
$html = $this->filters[$i]->preFilter($html, $config, $context);
|
||||||
$custom_filters = $filter_flags['Custom'];
|
|
||||||
unset($filter_flags['Custom']);
|
|
||||||
$filters = array();
|
|
||||||
foreach ($filter_flags as $filter => $flag) {
|
|
||||||
if (!$flag) continue;
|
|
||||||
$class = "HTMLPurifier_Filter_$filter";
|
|
||||||
$filters[] = new $class;
|
|
||||||
}
|
|
||||||
foreach ($custom_filters as $filter) {
|
|
||||||
// maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat
|
|
||||||
$filters[] = $filter;
|
|
||||||
}
|
|
||||||
$filters = array_merge($filters, $this->filters);
|
|
||||||
// maybe prepare(), but later
|
|
||||||
|
|
||||||
for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) {
|
|
||||||
$html = $filters[$i]->preFilter($html, $config, $context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// purified HTML
|
// purified HTML
|
||||||
@@ -177,11 +179,12 @@ class HTMLPurifier
|
|||||||
$html, $config, $context
|
$html, $config, $context
|
||||||
),
|
),
|
||||||
$config, $context
|
$config, $context
|
||||||
)
|
),
|
||||||
|
$config, $context
|
||||||
);
|
);
|
||||||
|
|
||||||
for ($i = $filter_size - 1; $i >= 0; $i--) {
|
for ($i = $size - 1; $i >= 0; $i--) {
|
||||||
$html = $filters[$i]->postFilter($html, $config, $context);
|
$html = $this->filters[$i]->postFilter($html, $config, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
$html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);
|
$html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);
|
||||||
@@ -195,7 +198,7 @@ class HTMLPurifier
|
|||||||
* See HTMLPurifier::purify() for more details.
|
* See HTMLPurifier::purify() for more details.
|
||||||
* @return Array of purified HTML
|
* @return Array of purified HTML
|
||||||
*/
|
*/
|
||||||
public function purifyArray($array_of_html, $config = null) {
|
function purifyArray($array_of_html, $config = null) {
|
||||||
$context_array = array();
|
$context_array = array();
|
||||||
foreach ($array_of_html as $key => $html) {
|
foreach ($array_of_html as $key => $html) {
|
||||||
$array_of_html[$key] = $this->purify($html, $config);
|
$array_of_html[$key] = $this->purify($html, $config);
|
||||||
@@ -208,27 +211,25 @@ class HTMLPurifier
|
|||||||
/**
|
/**
|
||||||
* Singleton for enforcing just one HTML Purifier in your system
|
* Singleton for enforcing just one HTML Purifier in your system
|
||||||
* @param $prototype Optional prototype HTMLPurifier instance to
|
* @param $prototype Optional prototype HTMLPurifier instance to
|
||||||
* overload singleton with, or HTMLPurifier_Config
|
* overload singleton with.
|
||||||
* instance to configure the generated version with.
|
|
||||||
*/
|
*/
|
||||||
public static function instance($prototype = null) {
|
function &instance($prototype = null) {
|
||||||
if (!self::$instance || $prototype) {
|
static $htmlpurifier;
|
||||||
if ($prototype instanceof HTMLPurifier) {
|
if (!$htmlpurifier || $prototype) {
|
||||||
self::$instance = $prototype;
|
if (is_a($prototype, 'HTMLPurifier')) {
|
||||||
|
$htmlpurifier = $prototype;
|
||||||
} elseif ($prototype) {
|
} elseif ($prototype) {
|
||||||
self::$instance = new HTMLPurifier($prototype);
|
$htmlpurifier = new HTMLPurifier($prototype);
|
||||||
} else {
|
} else {
|
||||||
self::$instance = new HTMLPurifier();
|
$htmlpurifier = new HTMLPurifier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self::$instance;
|
return $htmlpurifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function &getInstance($prototype = null) {
|
||||||
* @note Backwards compatibility, see instance()
|
|
||||||
*/
|
|
||||||
public static function getInstance($prototype = null) {
|
|
||||||
return HTMLPurifier::instance($prototype);
|
return HTMLPurifier::instance($prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,198 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* This file was auto-generated by generate-includes.php and includes all of
|
|
||||||
* the core files required by HTML Purifier. This is a convenience stub that
|
|
||||||
* includes all files using dirname(__FILE__) and require_once. PLEASE DO NOT
|
|
||||||
* EDIT THIS FILE, changes will be overwritten the next time the script is run.
|
|
||||||
*
|
|
||||||
* Changes to include_path are not necessary.
|
|
||||||
*/
|
|
||||||
|
|
||||||
$__dir = dirname(__FILE__);
|
|
||||||
|
|
||||||
require_once $__dir . '/HTMLPurifier.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrCollections.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTypes.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrValidator.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Bootstrap.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Definition.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Config.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ContentSets.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Context.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCacheFactory.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Doctype.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DoctypeRegistry.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ElementDef.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Encoder.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/EntityParser.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ErrorStruct.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Exception.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Filter.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Generator.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLDefinition.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModuleManager.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/IDAccumulator.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Injector.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Language.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Length.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/StringHash.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/StringHashParser.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/TagTransform.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Token.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/TokenFactory.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URI.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIDefinition.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIParser.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/UnitConverter.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/VarParser.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/VarParserException.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Lang.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Switch.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/Text.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/AlphaValue.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Background.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Border.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Color.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Composite.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Filter.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Font.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Length.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/LinkTypes.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Host.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Background.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BdoDir.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BgColor.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Border.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Input.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeEmbed.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Required.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/ChildDef/Table.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Null.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Edit.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Forms.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Ruby.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeEmbed.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeObject.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Name.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy/Core.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy/FixNesting.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy/MakeWellFormed.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy/RemoveForeignElements.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Strategy/ValidateAttributes.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/TagTransform/Font.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/TagTransform/Simple.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Token/Comment.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Token/Tag.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Token/Empty.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Token/End.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Token/Start.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/Token/Text.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/mailto.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/news.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/nntp.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/VarParser/Flexible.php';
|
|
||||||
require_once $__dir . '/HTMLPurifier/VarParser/Native.php';
|
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrTypes.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines common attribute collections that modules reference
|
* Defines common attribute collections that modules reference
|
||||||
*/
|
*/
|
||||||
@@ -10,7 +12,7 @@ class HTMLPurifier_AttrCollections
|
|||||||
/**
|
/**
|
||||||
* Associative array of attribute collections, indexed by name
|
* Associative array of attribute collections, indexed by name
|
||||||
*/
|
*/
|
||||||
public $info = array();
|
var $info = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs all expansions on internal data for use by other inclusions
|
* Performs all expansions on internal data for use by other inclusions
|
||||||
@@ -19,7 +21,7 @@ class HTMLPurifier_AttrCollections
|
|||||||
* @param $attr_types HTMLPurifier_AttrTypes instance
|
* @param $attr_types HTMLPurifier_AttrTypes instance
|
||||||
* @param $modules Hash array of HTMLPurifier_HTMLModule members
|
* @param $modules Hash array of HTMLPurifier_HTMLModule members
|
||||||
*/
|
*/
|
||||||
public function __construct($attr_types, $modules) {
|
function HTMLPurifier_AttrCollections($attr_types, $modules) {
|
||||||
// load extensions from the modules
|
// load extensions from the modules
|
||||||
foreach ($modules as $module) {
|
foreach ($modules as $module) {
|
||||||
foreach ($module->attr_collections as $coll_i => $coll) {
|
foreach ($module->attr_collections as $coll_i => $coll) {
|
||||||
@@ -51,7 +53,7 @@ class HTMLPurifier_AttrCollections
|
|||||||
* all inclusions specified by the zero index.
|
* all inclusions specified by the zero index.
|
||||||
* @param &$attr Reference to attribute array
|
* @param &$attr Reference to attribute array
|
||||||
*/
|
*/
|
||||||
public function performInclusions(&$attr) {
|
function performInclusions(&$attr) {
|
||||||
if (!isset($attr[0])) return;
|
if (!isset($attr[0])) return;
|
||||||
$merge = $attr[0];
|
$merge = $attr[0];
|
||||||
$seen = array(); // recursion guard
|
$seen = array(); // recursion guard
|
||||||
@@ -79,7 +81,7 @@ class HTMLPurifier_AttrCollections
|
|||||||
* @param &$attr Reference to attribute array
|
* @param &$attr Reference to attribute array
|
||||||
* @param $attr_types HTMLPurifier_AttrTypes instance
|
* @param $attr_types HTMLPurifier_AttrTypes instance
|
||||||
*/
|
*/
|
||||||
public function expandIdentifiers(&$attr, $attr_types) {
|
function expandIdentifiers(&$attr, $attr_types) {
|
||||||
|
|
||||||
// because foreach will process new elements we add, make sure we
|
// because foreach will process new elements we add, make sure we
|
||||||
// skip duplicates
|
// skip duplicates
|
||||||
|
@@ -10,29 +10,32 @@
|
|||||||
* subclasses are also responsible for cleaning the code if possible.
|
* subclasses are also responsible for cleaning the code if possible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells us whether or not an HTML attribute is minimized. Has no
|
* Tells us whether or not an HTML attribute is minimized. Has no
|
||||||
* meaning in other contexts.
|
* meaning in other contexts.
|
||||||
*/
|
*/
|
||||||
public $minimized = false;
|
var $minimized = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells us whether or not an HTML attribute is required. Has no
|
* Tells us whether or not an HTML attribute is required. Has no
|
||||||
* meaning in other contexts
|
* meaning in other contexts
|
||||||
*/
|
*/
|
||||||
public $required = false;
|
var $required = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates and cleans passed string according to a definition.
|
* Validates and cleans passed string according to a definition.
|
||||||
*
|
*
|
||||||
|
* @public
|
||||||
* @param $string String to be validated and cleaned.
|
* @param $string String to be validated and cleaned.
|
||||||
* @param $config Mandatory HTMLPurifier_Config object.
|
* @param $config Mandatory HTMLPurifier_Config object.
|
||||||
* @param $context Mandatory HTMLPurifier_AttrContext object.
|
* @param $context Mandatory HTMLPurifier_AttrContext object.
|
||||||
*/
|
*/
|
||||||
abstract public function validate($string, $config, $context);
|
function validate($string, $config, &$context) {
|
||||||
|
trigger_error('Cannot call abstract function', E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method that parses a string as if it were CDATA.
|
* Convenience method that parses a string as if it were CDATA.
|
||||||
@@ -54,8 +57,10 @@ abstract class HTMLPurifier_AttrDef
|
|||||||
* 4.7. However, note that we are NOT necessarily
|
* 4.7. However, note that we are NOT necessarily
|
||||||
* parsing XML, thus, this behavior may still be correct. We
|
* parsing XML, thus, this behavior may still be correct. We
|
||||||
* assume that newlines have been normalized.
|
* assume that newlines have been normalized.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
*/
|
*/
|
||||||
public function parseCDATA($string) {
|
function parseCDATA($string) {
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
$string = str_replace(array("\n", "\t", "\r"), ' ', $string);
|
$string = str_replace(array("\n", "\t", "\r"), ' ', $string);
|
||||||
return $string;
|
return $string;
|
||||||
@@ -65,12 +70,12 @@ abstract class HTMLPurifier_AttrDef
|
|||||||
* Factory method for creating this class from a string.
|
* Factory method for creating this class from a string.
|
||||||
* @param $string String construction info
|
* @param $string String construction info
|
||||||
* @return Created AttrDef object corresponding to $string
|
* @return Created AttrDef object corresponding to $string
|
||||||
|
* @public
|
||||||
*/
|
*/
|
||||||
public function make($string) {
|
function make($string) {
|
||||||
// default implementation, return a flyweight of this object.
|
// default implementation, return flyweight of this object
|
||||||
// If $string has an effect on the returned object (i.e. you
|
// if overloaded, it is *necessary* for you to clone the
|
||||||
// need to overload this method), it is best
|
// object (usually by instantiating a new copy) and return that
|
||||||
// to clone or instantiate new copies. (Instantiation is safer.)
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +83,7 @@ abstract class HTMLPurifier_AttrDef
|
|||||||
* Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work
|
* Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work
|
||||||
* properly. THIS IS A HACK!
|
* properly. THIS IS A HACK!
|
||||||
*/
|
*/
|
||||||
protected function mungeRgb($string) {
|
function mungeRgb($string) {
|
||||||
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
|
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/CSSDefinition.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the HTML attribute style, otherwise known as CSS.
|
* Validates the HTML attribute style, otherwise known as CSS.
|
||||||
* @note We don't implement the whole CSS specification, so it might be
|
* @note We don't implement the whole CSS specification, so it might be
|
||||||
@@ -14,7 +17,7 @@
|
|||||||
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($css, $config, $context) {
|
function validate($css, $config, &$context) {
|
||||||
|
|
||||||
$css = $this->parseCDATA($css);
|
$css = $this->parseCDATA($css);
|
||||||
|
|
||||||
@@ -29,12 +32,6 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
|||||||
$declarations = explode(';', $css);
|
$declarations = explode(';', $css);
|
||||||
$propvalues = array();
|
$propvalues = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the current CSS property being validated.
|
|
||||||
*/
|
|
||||||
$property = false;
|
|
||||||
$context->register('CurrentCSSProperty', $property);
|
|
||||||
|
|
||||||
foreach ($declarations as $declaration) {
|
foreach ($declarations as $declaration) {
|
||||||
if (!$declaration) continue;
|
if (!$declaration) continue;
|
||||||
if (!strpos($declaration, ':')) continue;
|
if (!strpos($declaration, ':')) continue;
|
||||||
@@ -67,8 +64,6 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
|||||||
$propvalues[$property] = $result;
|
$propvalues[$property] = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$context->destroy('CurrentCSSProperty');
|
|
||||||
|
|
||||||
// procedure does not write the new CSS simultaneously, so it's
|
// procedure does not write the new CSS simultaneously, so it's
|
||||||
// slightly inefficient, but it's the only way of getting rid of
|
// slightly inefficient, but it's the only way of getting rid of
|
||||||
// duplicates. Perhaps config to optimize it, but not now.
|
// duplicates. Perhaps config to optimize it, but not now.
|
||||||
|
@@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number
|
|
||||||
{
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
parent::__construct(false); // opacity is non-negative, but we will clamp it
|
|
||||||
}
|
|
||||||
|
|
||||||
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';
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/CSSDefinition.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates shorthand CSS property background.
|
* Validates shorthand CSS property background.
|
||||||
* @warning Does not support url tokens that have internal spaces.
|
* @warning Does not support url tokens that have internal spaces.
|
||||||
@@ -11,9 +14,9 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
|||||||
* Local copy of component validators.
|
* Local copy of component validators.
|
||||||
* @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
|
* @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
|
||||||
*/
|
*/
|
||||||
protected $info;
|
var $info;
|
||||||
|
|
||||||
public function __construct($config) {
|
function HTMLPurifier_AttrDef_CSS_Background($config) {
|
||||||
$def = $config->getCSSDefinition();
|
$def = $config->getCSSDefinition();
|
||||||
$this->info['background-color'] = $def->info['background-color'];
|
$this->info['background-color'] = $def->info['background-color'];
|
||||||
$this->info['background-image'] = $def->info['background-image'];
|
$this->info['background-image'] = $def->info['background-image'];
|
||||||
@@ -22,7 +25,7 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
|||||||
$this->info['background-position'] = $def->info['background-position'];
|
$this->info['background-position'] = $def->info['background-position'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
// regular pre-processing
|
// regular pre-processing
|
||||||
$string = $this->parseCDATA($string);
|
$string = $this->parseCDATA($string);
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/CSS/Length.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||||
|
|
||||||
/* W3C says:
|
/* W3C says:
|
||||||
[ // adjective and number must be in correct order, even if
|
[ // adjective and number must be in correct order, even if
|
||||||
// you could switch them without introducing ambiguity.
|
// you could switch them without introducing ambiguity.
|
||||||
@@ -44,15 +48,15 @@
|
|||||||
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $length;
|
var $length;
|
||||||
protected $percentage;
|
var $percentage;
|
||||||
|
|
||||||
public function __construct() {
|
function HTMLPurifier_AttrDef_CSS_BackgroundPosition() {
|
||||||
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
|
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
|
||||||
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
|
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
$string = $this->parseCDATA($string);
|
$string = $this->parseCDATA($string);
|
||||||
$bits = explode(' ', $string);
|
$bits = explode(' ', $string);
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the border property as defined by CSS.
|
* Validates the border property as defined by CSS.
|
||||||
*/
|
*/
|
||||||
@@ -9,16 +11,16 @@ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
|
|||||||
/**
|
/**
|
||||||
* Local copy of properties this property is shorthand for.
|
* Local copy of properties this property is shorthand for.
|
||||||
*/
|
*/
|
||||||
protected $info = array();
|
var $info = array();
|
||||||
|
|
||||||
public function __construct($config) {
|
function HTMLPurifier_AttrDef_CSS_Border($config) {
|
||||||
$def = $config->getCSSDefinition();
|
$def = $config->getCSSDefinition();
|
||||||
$this->info['border-width'] = $def->info['border-width'];
|
$this->info['border-width'] = $def->info['border-width'];
|
||||||
$this->info['border-style'] = $def->info['border-style'];
|
$this->info['border-style'] = $def->info['border-style'];
|
||||||
$this->info['border-top-color'] = $def->info['border-top-color'];
|
$this->info['border-top-color'] = $def->info['border-top-color'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
$string = $this->parseCDATA($string);
|
$string = $this->parseCDATA($string);
|
||||||
$string = $this->mungeRgb($string);
|
$string = $this->mungeRgb($string);
|
||||||
$bits = explode(' ', $string);
|
$bits = explode(' ', $string);
|
||||||
|
@@ -1,12 +1,39 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Core', 'ColorKeywords', array(
|
||||||
|
'maroon' => '#800000',
|
||||||
|
'red' => '#FF0000',
|
||||||
|
'orange' => '#FFA500',
|
||||||
|
'yellow' => '#FFFF00',
|
||||||
|
'olive' => '#808000',
|
||||||
|
'purple' => '#800080',
|
||||||
|
'fuchsia' => '#FF00FF',
|
||||||
|
'white' => '#FFFFFF',
|
||||||
|
'lime' => '#00FF00',
|
||||||
|
'green' => '#008000',
|
||||||
|
'navy' => '#000080',
|
||||||
|
'blue' => '#0000FF',
|
||||||
|
'aqua' => '#00FFFF',
|
||||||
|
'teal' => '#008080',
|
||||||
|
'black' => '#000000',
|
||||||
|
'silver' => '#C0C0C0',
|
||||||
|
'gray' => '#808080'
|
||||||
|
), 'hash', '
|
||||||
|
Lookup array of color names to six digit hexadecimal number corresponding
|
||||||
|
to color, with preceding hash mark. Used when parsing colors.
|
||||||
|
This directive has been available since 2.0.0.
|
||||||
|
');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates Color as defined by CSS.
|
* Validates Color as defined by CSS.
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($color, $config, $context) {
|
function validate($color, $config, &$context) {
|
||||||
|
|
||||||
static $colors = null;
|
static $colors = null;
|
||||||
if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
|
if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
|
||||||
|
@@ -14,18 +14,18 @@ class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* List of HTMLPurifier_AttrDef objects that may process strings
|
* List of HTMLPurifier_AttrDef objects that may process strings
|
||||||
* @todo Make protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
public $defs;
|
var $defs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $defs List of HTMLPurifier_AttrDef objects
|
* @param $defs List of HTMLPurifier_AttrDef objects
|
||||||
*/
|
*/
|
||||||
public function __construct($defs) {
|
function HTMLPurifier_AttrDef_CSS_Composite($defs) {
|
||||||
$this->defs = $defs;
|
$this->defs = $defs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
foreach ($this->defs as $i => $def) {
|
foreach ($this->defs as $i => $def) {
|
||||||
$result = $this->defs[$i]->validate($string, $config, $context);
|
$result = $this->defs[$i]->validate($string, $config, $context);
|
||||||
if ($result !== false) return $result;
|
if ($result !== false) return $result;
|
||||||
|
@@ -5,20 +5,20 @@
|
|||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
protected $def, $element;
|
var $def, $element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $def Definition to wrap
|
* @param $def Definition to wrap
|
||||||
* @param $element Element to deny
|
* @param $element Element to deny
|
||||||
*/
|
*/
|
||||||
public function __construct($def, $element) {
|
function HTMLPurifier_AttrDef_CSS_DenyElementDecorator(&$def, $element) {
|
||||||
$this->def = $def;
|
$this->def =& $def;
|
||||||
$this->element = $element;
|
$this->element = $element;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks if CurrentToken is set and equal to $this->element
|
* Checks if CurrentToken is set and equal to $this->element
|
||||||
*/
|
*/
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, $context) {
|
||||||
$token = $context->get('CurrentToken', true);
|
$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);
|
return $this->def->validate($string, $config, $context);
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Microsoft's proprietary filter: CSS property
|
|
||||||
* @note Currently supports the alpha filter. In the future, this will
|
|
||||||
* probably need an extensible framework
|
|
||||||
*/
|
|
||||||
class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $intValidator;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->intValidator = new HTMLPurifier_AttrDef_Integer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function validate($value, $config, $context) {
|
|
||||||
$value = $this->parseCDATA($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;
|
|
||||||
$cursor = $function_length + 1;
|
|
||||||
$parameters_length = strcspn($value, ')', $cursor);
|
|
||||||
$parameters = substr($value, $cursor, $parameters_length);
|
|
||||||
$params = explode(',', $parameters);
|
|
||||||
$ret_params = array();
|
|
||||||
$lookup = array();
|
|
||||||
foreach ($params as $param) {
|
|
||||||
list($key, $value) = explode('=', $param);
|
|
||||||
$key = trim($key);
|
|
||||||
$value = trim($value);
|
|
||||||
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';
|
|
||||||
$ret_params[] = "$key=$value";
|
|
||||||
$lookup[$key] = true;
|
|
||||||
}
|
|
||||||
$ret_parameters = implode(',', $ret_params);
|
|
||||||
$ret_function = "$function($ret_parameters)";
|
|
||||||
return $ret_function;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates shorthand CSS property font.
|
* Validates shorthand CSS property font.
|
||||||
*/
|
*/
|
||||||
@@ -14,9 +16,9 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
|||||||
* CSSDefinition, this wouldn't be necessary. We'd instantiate
|
* CSSDefinition, this wouldn't be necessary. We'd instantiate
|
||||||
* our own copies.
|
* our own copies.
|
||||||
*/
|
*/
|
||||||
protected $info = array();
|
var $info = array();
|
||||||
|
|
||||||
public function __construct($config) {
|
function HTMLPurifier_AttrDef_CSS_Font($config) {
|
||||||
$def = $config->getCSSDefinition();
|
$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-variant'] = $def->info['font-variant'];
|
||||||
@@ -26,7 +28,7 @@ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
|||||||
$this->info['font-family'] = $def->info['font-family'];
|
$this->info['font-family'] = $def->info['font-family'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
static $system_fonts = array(
|
static $system_fonts = array(
|
||||||
'caption' => true,
|
'caption' => true,
|
||||||
|
@@ -1,13 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
|
// whitelisting allowed fonts would be nice
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a font family list according to CSS spec
|
* Validates a font family list according to CSS spec
|
||||||
* @todo whitelisting allowed fonts would be nice
|
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
static $generic_names = array(
|
static $generic_names = array(
|
||||||
'serif' => true,
|
'serif' => true,
|
||||||
'sans-serif' => true,
|
'sans-serif' => true,
|
||||||
|
@@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decorator which enables !important to be used in CSS values.
|
|
||||||
*/
|
|
||||||
class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
|
|
||||||
{
|
|
||||||
protected $def, $allow;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $def Definition to wrap
|
|
||||||
* @param $allow Whether or not to allow !important
|
|
||||||
*/
|
|
||||||
public function __construct($def, $allow = false) {
|
|
||||||
$this->def = $def;
|
|
||||||
$this->allow = $allow;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Intercepts and removes !important if necessary
|
|
||||||
*/
|
|
||||||
public function validate($string, $config, $context) {
|
|
||||||
// test for ! and important tokens
|
|
||||||
$string = trim($string);
|
|
||||||
$is_important = false;
|
|
||||||
// :TODO: optimization: test directly for !important and ! important
|
|
||||||
if (strlen($string) >= 9 && substr($string, -9) === 'important') {
|
|
||||||
$temp = rtrim(substr($string, 0, -9));
|
|
||||||
// use a temp, because we might want to restore important
|
|
||||||
if (strlen($temp) >= 1 && substr($temp, -1) === '!') {
|
|
||||||
$string = rtrim(substr($temp, 0, -1));
|
|
||||||
$is_important = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$string = $this->def->validate($string, $config, $context);
|
|
||||||
if ($this->allow && $is_important) $string .= ' !important';
|
|
||||||
return $string;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,23 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/Length.php';
|
||||||
|
require_once 'HTMLPurifier/UnitConverter.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Length as defined by CSS.
|
* Represents a Length as defined by CSS.
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $min, $max;
|
var $min, $max;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param HTMLPurifier_Length $max Minimum length, or null for no bound. String is also acceptable.
|
* @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.
|
* @param HTMLPurifier_Length $max Maximum length, or null for no bound. String is also acceptable.
|
||||||
*/
|
*/
|
||||||
public function __construct($min = null, $max = null) {
|
function HTMLPurifier_AttrDef_CSS_Length($min = null, $max = null) {
|
||||||
$this->min = $min !== null ? HTMLPurifier_Length::make($min) : null;
|
$this->min = $min !== null ? HTMLPurifier_Length::make($min) : null;
|
||||||
$this->max = $max !== null ? HTMLPurifier_Length::make($max) : null;
|
$this->max = $max !== null ? HTMLPurifier_Length::make($max) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, $context) {
|
||||||
$string = $this->parseCDATA($string);
|
$string = $this->parseCDATA($string);
|
||||||
|
|
||||||
// Optimizations
|
// Optimizations
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates shorthand CSS property list-style.
|
* Validates shorthand CSS property list-style.
|
||||||
* @warning Does not support url tokens that have internal spaces.
|
* @warning Does not support url tokens that have internal spaces.
|
||||||
@@ -11,16 +13,16 @@ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
|
|||||||
* Local copy of component validators.
|
* Local copy of component validators.
|
||||||
* @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
|
* @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
|
||||||
*/
|
*/
|
||||||
protected $info;
|
var $info;
|
||||||
|
|
||||||
public function __construct($config) {
|
function HTMLPurifier_AttrDef_CSS_ListStyle($config) {
|
||||||
$def = $config->getCSSDefinition();
|
$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-position'] = $def->info['list-style-position'];
|
||||||
$this->info['list-style-image'] = $def->info['list-style-image'];
|
$this->info['list-style-image'] = $def->info['list-style-image'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
// regular pre-processing
|
// regular pre-processing
|
||||||
$string = $this->parseCDATA($string);
|
$string = $this->parseCDATA($string);
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Framework class for strings that involve multiple values.
|
* Framework class for strings that involve multiple values.
|
||||||
*
|
*
|
||||||
@@ -16,26 +18,24 @@ class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance of component definition to defer validation to.
|
* Instance of component definition to defer validation to.
|
||||||
* @todo Make protected
|
|
||||||
*/
|
*/
|
||||||
public $single;
|
var $single;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Max number of values allowed.
|
* Max number of values allowed.
|
||||||
* @todo Make protected
|
|
||||||
*/
|
*/
|
||||||
public $max;
|
var $max;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $single HTMLPurifier_AttrDef to multiply
|
* @param $single HTMLPurifier_AttrDef to multiply
|
||||||
* @param $max Max number of values allowed (usually four)
|
* @param $max Max number of values allowed (usually four)
|
||||||
*/
|
*/
|
||||||
public function __construct($single, $max = 4) {
|
function HTMLPurifier_AttrDef_CSS_Multiple($single, $max = 4) {
|
||||||
$this->single = $single;
|
$this->single = $single;
|
||||||
$this->max = $max;
|
$this->max = $max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
$string = $this->parseCDATA($string);
|
$string = $this->parseCDATA($string);
|
||||||
if ($string === '') return false;
|
if ($string === '') return false;
|
||||||
$parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n
|
$parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n
|
||||||
|
@@ -9,25 +9,25 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
|
|||||||
/**
|
/**
|
||||||
* Bool indicating whether or not only positive values allowed.
|
* Bool indicating whether or not only positive values allowed.
|
||||||
*/
|
*/
|
||||||
protected $non_negative = false;
|
var $non_negative = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $non_negative Bool indicating whether negatives are forbidden
|
* @param $non_negative Bool indicating whether negatives are forbidden
|
||||||
*/
|
*/
|
||||||
public function __construct($non_negative = false) {
|
function HTMLPurifier_AttrDef_CSS_Number($non_negative = false) {
|
||||||
$this->non_negative = $non_negative;
|
$this->non_negative = $non_negative;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @warning Some contexts do not pass $config, $context. These
|
* @warning Some contexts do not pass $config, $context. These
|
||||||
* variables should not be used without checking HTMLPurifier_Length
|
* variables should not be used without checking HTMLPurifier_Length.
|
||||||
|
* This might not work properly in PHP4.
|
||||||
*/
|
*/
|
||||||
public function validate($number, $config, $context) {
|
function validate($number, $config, &$context) {
|
||||||
|
|
||||||
$number = $this->parseCDATA($number);
|
$number = $this->parseCDATA($number);
|
||||||
|
|
||||||
if ($number === '') return false;
|
if ($number === '') return false;
|
||||||
if ($number === '0') return '0';
|
|
||||||
|
|
||||||
$sign = '';
|
$sign = '';
|
||||||
switch ($number[0]) {
|
switch ($number[0]) {
|
||||||
@@ -42,16 +42,13 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
|
|||||||
$number = ltrim($number, '0');
|
$number = ltrim($number, '0');
|
||||||
return $number ? $sign . $number : '0';
|
return $number ? $sign . $number : '0';
|
||||||
}
|
}
|
||||||
|
if (!strpos($number, '.')) return false;
|
||||||
// Period is the only non-numeric character allowed
|
|
||||||
if (strpos($number, '.') === false) return false;
|
|
||||||
|
|
||||||
list($left, $right) = explode('.', $number, 2);
|
list($left, $right) = explode('.', $number, 2);
|
||||||
|
|
||||||
if ($left === '' && $right === '') return false;
|
if (!ctype_digit($left)) return false;
|
||||||
if ($left !== '' && !ctype_digit($left)) return false;
|
$left = ltrim($left, '0');
|
||||||
|
|
||||||
$left = ltrim($left, '0');
|
|
||||||
$right = rtrim($right, '0');
|
$right = rtrim($right, '0');
|
||||||
|
|
||||||
if ($right === '') {
|
if ($right === '') {
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/CSS/Number.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a Percentage as defined by the CSS spec.
|
* Validates a Percentage as defined by the CSS spec.
|
||||||
*/
|
*/
|
||||||
@@ -9,16 +12,16 @@ class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef
|
|||||||
/**
|
/**
|
||||||
* Instance of HTMLPurifier_AttrDef_CSS_Number to defer number validation
|
* Instance of HTMLPurifier_AttrDef_CSS_Number to defer number validation
|
||||||
*/
|
*/
|
||||||
protected $number_def;
|
var $number_def;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bool indicating whether to forbid negative values
|
* @param Bool indicating whether to forbid negative values
|
||||||
*/
|
*/
|
||||||
public function __construct($non_negative = false) {
|
function HTMLPurifier_AttrDef_CSS_Percentage($non_negative = false) {
|
||||||
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
|
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
$string = $this->parseCDATA($string);
|
$string = $this->parseCDATA($string);
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the value for the CSS property text-decoration
|
* Validates the value for the CSS property text-decoration
|
||||||
* @note This class could be generalized into a version that acts sort of
|
* @note This class could be generalized into a version that acts sort of
|
||||||
@@ -8,7 +10,7 @@
|
|||||||
class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
static $allowed_values = array(
|
static $allowed_values = array(
|
||||||
'line-through' => true,
|
'line-through' => true,
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef/URI.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a URI in CSS syntax, which uses url('http://example.com')
|
* Validates a URI in CSS syntax, which uses url('http://example.com')
|
||||||
* @note While theoretically speaking a URI in a CSS document could
|
* @note While theoretically speaking a URI in a CSS document could
|
||||||
@@ -12,11 +14,11 @@
|
|||||||
class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
|
class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct() {
|
function HTMLPurifier_AttrDef_CSS_URI() {
|
||||||
parent::__construct(true); // always embedded
|
parent::HTMLPurifier_AttrDef_URI(true); // always embedded
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($uri_string, $config, $context) {
|
function validate($uri_string, $config, &$context) {
|
||||||
// parse the URI out of the string and then pass it onto
|
// parse the URI out of the string and then pass it onto
|
||||||
// the parent object
|
// the parent object
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
// Enum = Enumerated
|
// Enum = Enumerated
|
||||||
/**
|
/**
|
||||||
* Validates a keyword against a list of valid values.
|
* Validates a keyword against a list of valid values.
|
||||||
@@ -12,28 +14,27 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup table of valid values.
|
* Lookup table of valid values.
|
||||||
* @todo Make protected
|
|
||||||
*/
|
*/
|
||||||
public $valid_values = array();
|
var $valid_values = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bool indicating whether or not enumeration is case sensitive.
|
* Bool indicating whether or not enumeration is case sensitive.
|
||||||
* @note In general this is always case insensitive.
|
* @note In general this is always case insensitive.
|
||||||
*/
|
*/
|
||||||
protected $case_sensitive = false; // values according to W3C spec
|
var $case_sensitive = false; // values according to W3C spec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $valid_values List of valid values
|
* @param $valid_values List of valid values
|
||||||
* @param $case_sensitive Bool indicating whether or not case sensitive
|
* @param $case_sensitive Bool indicating whether or not case sensitive
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
function HTMLPurifier_AttrDef_Enum(
|
||||||
$valid_values = array(), $case_sensitive = false
|
$valid_values = array(), $case_sensitive = false
|
||||||
) {
|
) {
|
||||||
$this->valid_values = array_flip($valid_values);
|
$this->valid_values = array_flip($valid_values);
|
||||||
$this->case_sensitive = $case_sensitive;
|
$this->case_sensitive = $case_sensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
if (!$this->case_sensitive) {
|
if (!$this->case_sensitive) {
|
||||||
// we may want to do full case-insensitive libraries
|
// we may want to do full case-insensitive libraries
|
||||||
@@ -49,7 +50,7 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef
|
|||||||
* valid values. Example: "foo,bar,baz". Prepend "s:" to make
|
* valid values. Example: "foo,bar,baz". Prepend "s:" to make
|
||||||
* case sensitive
|
* case sensitive
|
||||||
*/
|
*/
|
||||||
public function make($string) {
|
function make($string) {
|
||||||
if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') {
|
if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') {
|
||||||
$string = substr($string, 2);
|
$string = substr($string, 2);
|
||||||
$sensitive = true;
|
$sensitive = true;
|
||||||
|
@@ -1,17 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a boolean attribute
|
* Validates a boolean attribute
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $name;
|
var $name;
|
||||||
public $minimized = true;
|
var $minimized = true;
|
||||||
|
|
||||||
public function __construct($name = false) {$this->name = $name;}
|
function HTMLPurifier_AttrDef_HTML_Bool($name = false) {$this->name = $name;}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
if (empty($string)) return false;
|
if (empty($string)) return false;
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
@@ -19,7 +21,7 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
|
|||||||
/**
|
/**
|
||||||
* @param $string Name of attribute
|
* @param $string Name of attribute
|
||||||
*/
|
*/
|
||||||
public function make($string) {
|
function make($string) {
|
||||||
return new HTMLPurifier_AttrDef_HTML_Bool($string);
|
return new HTMLPurifier_AttrDef_HTML_Bool($string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,12 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/CSS/Color.php'; // for %Core.ColorKeywords
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a color according to the HTML spec.
|
* Validates a color according to the HTML spec.
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
static $colors = null;
|
static $colors = null;
|
||||||
if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
|
if ($colors === null) $colors = $config->get('Core', 'ColorKeywords');
|
||||||
|
@@ -1,17 +1,30 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Attr', 'AllowedFrameTargets', array(), 'lookup',
|
||||||
|
'Lookup table of all allowed link frame targets. Some commonly used '.
|
||||||
|
'link targets include _blank, _self, _parent and _top. Values should '.
|
||||||
|
'be lowercase, as validation will be done in a case-sensitive manner '.
|
||||||
|
'despite W3C\'s recommendation. XHTML 1.0 Strict does not permit '.
|
||||||
|
'the target attribute so this directive will have no effect in that '.
|
||||||
|
'doctype. XHTML 1.1 does not enable the Target module by default, you '.
|
||||||
|
'will have to manually enable it (see the module documentation for more details.)'
|
||||||
|
);
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef/Enum.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special-case enum attribute definition that lazy loads allowed frame targets
|
* Special-case enum attribute definition that lazy loads allowed frame targets
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum
|
class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum
|
||||||
{
|
{
|
||||||
|
|
||||||
public $valid_values = false; // uninitialized value
|
var $valid_values = false; // uninitialized value
|
||||||
protected $case_sensitive = false;
|
var $case_sensitive = false;
|
||||||
|
|
||||||
public function __construct() {}
|
function HTMLPurifier_AttrDef_HTML_FrameTarget() {}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
if ($this->valid_values === false) $this->valid_values = $config->get('Attr', 'AllowedFrameTargets');
|
if ($this->valid_values === false) $this->valid_values = $config->get('Attr', 'AllowedFrameTargets');
|
||||||
return parent::validate($string, $config, $context);
|
return parent::validate($string, $config, $context);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,56 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/IDAccumulator.php';
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Attr', 'EnableID', false, 'bool',
|
||||||
|
'Allows the ID attribute in HTML. This is disabled by default '.
|
||||||
|
'due to the fact that without proper configuration user input can '.
|
||||||
|
'easily break the validation of a webpage by specifying an ID that is '.
|
||||||
|
'already on the surrounding HTML. If you don\'t mind throwing caution to '.
|
||||||
|
'the wind, enable this directive, but I strongly recommend you also '.
|
||||||
|
'consider blacklisting IDs you use (%Attr.IDBlacklist) or prefixing all '.
|
||||||
|
'user supplied IDs (%Attr.IDPrefix). This directive has been available '.
|
||||||
|
'since 1.2.0, and when set to true reverts to the behavior of pre-1.2.0 '.
|
||||||
|
'versions.'
|
||||||
|
);
|
||||||
|
HTMLPurifier_ConfigSchema::defineAlias(
|
||||||
|
'HTML', 'EnableAttrID', 'Attr', 'EnableID'
|
||||||
|
);
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Attr', 'IDPrefix', '', 'string',
|
||||||
|
'String to prefix to IDs. If you have no idea what IDs your pages '.
|
||||||
|
'may use, you may opt to simply add a prefix to all user-submitted ID '.
|
||||||
|
'attributes so that they are still usable, but will not conflict with '.
|
||||||
|
'core page IDs. Example: setting the directive to \'user_\' will result in '.
|
||||||
|
'a user submitted \'foo\' to become \'user_foo\' Be sure to set '.
|
||||||
|
'%HTML.EnableAttrID to true before using '.
|
||||||
|
'this. This directive was available since 1.2.0.'
|
||||||
|
);
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Attr', 'IDPrefixLocal', '', 'string',
|
||||||
|
'Temporary prefix for IDs used in conjunction with %Attr.IDPrefix. If '.
|
||||||
|
'you need to allow multiple sets of '.
|
||||||
|
'user content on web page, you may need to have a seperate prefix that '.
|
||||||
|
'changes with each iteration. This way, seperately submitted user content '.
|
||||||
|
'displayed on the same page doesn\'t clobber each other. Ideal values '.
|
||||||
|
'are unique identifiers for the content it represents (i.e. the id of '.
|
||||||
|
'the row in the database). Be sure to add a seperator (like an underscore) '.
|
||||||
|
'at the end. Warning: this directive will not work unless %Attr.IDPrefix '.
|
||||||
|
'is set to a non-empty value! This directive was available since 1.2.0.'
|
||||||
|
);
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Attr', 'IDBlacklistRegexp', null, 'string/null',
|
||||||
|
'PCRE regular expression to be matched against all IDs. If the expression '.
|
||||||
|
'is matches, the ID is rejected. Use this with care: may cause '.
|
||||||
|
'significant degradation. ID matching is done after all other '.
|
||||||
|
'validation. This directive was available since 1.6.0.'
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the HTML attribute ID.
|
* Validates the HTML attribute ID.
|
||||||
* @warning Even though this is the id processor, it
|
* @warning Even though this is the id processor, it
|
||||||
@@ -15,7 +66,7 @@ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
|
|||||||
// ref functionality disabled, since we also have to verify
|
// ref functionality disabled, since we also have to verify
|
||||||
// whether or not the ID it refers to exists
|
// whether or not the ID it refers to exists
|
||||||
|
|
||||||
public function validate($id, $config, $context) {
|
function validate($id, $config, &$context) {
|
||||||
|
|
||||||
if (!$config->get('Attr', 'EnableID')) return false;
|
if (!$config->get('Attr', 'EnableID')) return false;
|
||||||
|
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the HTML type length (not to be confused with CSS's length).
|
* Validates the HTML type length (not to be confused with CSS's length).
|
||||||
*
|
*
|
||||||
@@ -10,7 +13,7 @@
|
|||||||
class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels
|
class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
if ($string === '') return false;
|
if ($string === '') return false;
|
||||||
|
@@ -1,5 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Attr', 'AllowedRel', array(), 'lookup',
|
||||||
|
'List of allowed forward document relationships in the rel attribute. '.
|
||||||
|
'Common values may be nofollow or print. By default, this is empty, '.
|
||||||
|
'meaning that no document relationships are allowed. This directive '.
|
||||||
|
'was available since 1.6.0.'
|
||||||
|
);
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Attr', 'AllowedRev', array(), 'lookup',
|
||||||
|
'List of allowed reverse document relationships in the rev attribute. '.
|
||||||
|
'This attribute is a bit of an edge-case; if you don\'t know what it '.
|
||||||
|
'is for, stay away. This directive was available since 1.6.0.'
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a rel/rev link attribute against a directive of allowed values
|
* Validates a rel/rev link attribute against a directive of allowed values
|
||||||
* @note We cannot use Enum because link types allow multiple
|
* @note We cannot use Enum because link types allow multiple
|
||||||
@@ -10,9 +27,9 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
|
|||||||
{
|
{
|
||||||
|
|
||||||
/** Name config attribute to pull. */
|
/** Name config attribute to pull. */
|
||||||
protected $name;
|
var $name;
|
||||||
|
|
||||||
public function __construct($name) {
|
function HTMLPurifier_AttrDef_HTML_LinkTypes($name) {
|
||||||
$configLookup = array(
|
$configLookup = array(
|
||||||
'rel' => 'AllowedRel',
|
'rel' => 'AllowedRel',
|
||||||
'rev' => 'AllowedRev'
|
'rev' => 'AllowedRev'
|
||||||
@@ -25,7 +42,7 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
|
|||||||
$this->name = $configLookup[$name];
|
$this->name = $configLookup[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
$allowed = $config->get('Attr', $this->name);
|
$allowed = $config->get('Attr', $this->name);
|
||||||
if (empty($allowed)) return false;
|
if (empty($allowed)) return false;
|
||||||
@@ -42,7 +59,10 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($ret_lookup)) return false;
|
if (empty($ret_lookup)) return false;
|
||||||
$string = implode(' ', array_keys($ret_lookup));
|
|
||||||
|
$ret_array = array();
|
||||||
|
foreach ($ret_lookup as $part => $bool) $ret_array[] = $part;
|
||||||
|
$string = implode(' ', $ret_array);
|
||||||
|
|
||||||
return $string;
|
return $string;
|
||||||
|
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/HTML/Length.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a MultiLength as defined by the HTML spec.
|
* Validates a MultiLength as defined by the HTML spec.
|
||||||
*
|
*
|
||||||
@@ -9,7 +12,7 @@
|
|||||||
class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length
|
class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
if ($string === '') return false;
|
if ($string === '') return false;
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/Config.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates contents based on NMTOKENS attribute type.
|
* Validates contents based on NMTOKENS attribute type.
|
||||||
* @note The only current use for this is the class attribute in HTML
|
* @note The only current use for this is the class attribute in HTML
|
||||||
@@ -10,7 +13,7 @@
|
|||||||
class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
|
|
||||||
|
@@ -1,18 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates an integer representation of pixels according to the HTML spec.
|
* Validates an integer representation of pixels according to the HTML spec.
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $max;
|
var $max;
|
||||||
|
|
||||||
public function __construct($max = null) {
|
function HTMLPurifier_AttrDef_HTML_Pixels($max = null) {
|
||||||
$this->max = $max;
|
$this->max = $max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
if ($string === '0') return $string;
|
if ($string === '0') return $string;
|
||||||
@@ -36,7 +38,7 @@ class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function make($string) {
|
function make($string) {
|
||||||
if ($string === '') $max = null;
|
if ($string === '') $max = null;
|
||||||
else $max = (int) $string;
|
else $max = (int) $string;
|
||||||
$class = get_class($this);
|
$class = get_class($this);
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates an integer.
|
* Validates an integer.
|
||||||
* @note While this class was modeled off the CSS definition, no currently
|
* @note While this class was modeled off the CSS definition, no currently
|
||||||
@@ -13,24 +15,24 @@ class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef
|
|||||||
/**
|
/**
|
||||||
* Bool indicating whether or not negative values are allowed
|
* Bool indicating whether or not negative values are allowed
|
||||||
*/
|
*/
|
||||||
protected $negative = true;
|
var $negative = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bool indicating whether or not zero is allowed
|
* Bool indicating whether or not zero is allowed
|
||||||
*/
|
*/
|
||||||
protected $zero = true;
|
var $zero = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bool indicating whether or not positive values are allowed
|
* Bool indicating whether or not positive values are allowed
|
||||||
*/
|
*/
|
||||||
protected $positive = true;
|
var $positive = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $negative Bool indicating whether or not negative values are allowed
|
* @param $negative Bool indicating whether or not negative values are allowed
|
||||||
* @param $zero Bool indicating whether or not zero is allowed
|
* @param $zero Bool indicating whether or not zero is allowed
|
||||||
* @param $positive Bool indicating whether or not positive values are allowed
|
* @param $positive Bool indicating whether or not positive values are allowed
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
function HTMLPurifier_AttrDef_Integer(
|
||||||
$negative = true, $zero = true, $positive = true
|
$negative = true, $zero = true, $positive = true
|
||||||
) {
|
) {
|
||||||
$this->negative = $negative;
|
$this->negative = $negative;
|
||||||
@@ -38,7 +40,7 @@ class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef
|
|||||||
$this->positive = $positive;
|
$this->positive = $positive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($integer, $config, $context) {
|
function validate($integer, $config, &$context) {
|
||||||
|
|
||||||
$integer = $this->parseCDATA($integer);
|
$integer = $this->parseCDATA($integer);
|
||||||
if ($integer === '') return false;
|
if ($integer === '') return false;
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the HTML attribute lang, effectively a language code.
|
* Validates the HTML attribute lang, effectively a language code.
|
||||||
* @note Built according to RFC 3066, which obsoleted RFC 1766
|
* @note Built according to RFC 3066, which obsoleted RFC 1766
|
||||||
@@ -7,7 +9,7 @@
|
|||||||
class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
|
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
if (!$string) return false;
|
if (!$string) return false;
|
||||||
|
@@ -6,21 +6,21 @@
|
|||||||
class HTMLPurifier_AttrDef_Switch
|
class HTMLPurifier_AttrDef_Switch
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $tag;
|
var $tag;
|
||||||
protected $withTag, $withoutTag;
|
var $withTag, $withoutTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $tag Tag name to switch upon
|
* @param string $tag Tag name to switch upon
|
||||||
* @param HTMLPurifier_AttrDef $with_tag Call if token matches tag
|
* @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
|
* @param HTMLPurifier_AttrDef $without_tag Call if token doesn't match, or there is no token
|
||||||
*/
|
*/
|
||||||
public function __construct($tag, $with_tag, $without_tag) {
|
function HTMLPurifier_AttrDef_Switch($tag, $with_tag, $without_tag) {
|
||||||
$this->tag = $tag;
|
$this->tag = $tag;
|
||||||
$this->withTag = $with_tag;
|
$this->withTag = $with_tag;
|
||||||
$this->withoutTag = $without_tag;
|
$this->withoutTag = $without_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, $context) {
|
||||||
$token = $context->get('CurrentToken', true);
|
$token = $context->get('CurrentToken', true);
|
||||||
if (!$token || $token->name !== $this->tag) {
|
if (!$token || $token->name !== $this->tag) {
|
||||||
return $this->withoutTag->validate($string, $config, $context);
|
return $this->withoutTag->validate($string, $config, $context);
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates arbitrary text according to the HTML spec.
|
* Validates arbitrary text according to the HTML spec.
|
||||||
*/
|
*/
|
||||||
class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
return $this->parseCDATA($string);
|
return $this->parseCDATA($string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,66 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/URIParser.php';
|
||||||
|
require_once 'HTMLPurifier/URIScheme.php';
|
||||||
|
require_once 'HTMLPurifier/URISchemeRegistry.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/URI/Host.php';
|
||||||
|
require_once 'HTMLPurifier/PercentEncoder.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/URI/Email.php';
|
||||||
|
|
||||||
|
// special case filtering directives
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'URI', 'Munge', null, 'string/null', '
|
||||||
|
<p>
|
||||||
|
Munges all browsable (usually http, https and ftp)
|
||||||
|
absolute URI\'s into another URI, usually a URI redirection service.
|
||||||
|
This directive accepts a URI, formatted with a <code>%s</code> where
|
||||||
|
the url-encoded original URI should be inserted (sample:
|
||||||
|
<code>http://www.google.com/url?q=%s</code>).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Uses for this directive:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Prevent PageRank leaks, while being fairly transparent
|
||||||
|
to users (you may also want to add some client side JavaScript to
|
||||||
|
override the text in the statusbar). <strong>Notice</strong>:
|
||||||
|
Many security experts believe that this form of protection does not deter spam-bots.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Redirect users to a splash page telling them they are leaving your
|
||||||
|
website. While this is poor usability practice, it is often mandated
|
||||||
|
in corporate environments.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
This directive has been available since 1.3.0.
|
||||||
|
</p>
|
||||||
|
');
|
||||||
|
|
||||||
|
// disabling directives
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'URI', 'Disable', false, 'bool', '
|
||||||
|
<p>
|
||||||
|
Disables all URIs in all forms. Not sure why you\'d want to do that
|
||||||
|
(after all, the Internet\'s founded on the notion of a hyperlink).
|
||||||
|
This directive has been available since 1.3.0.
|
||||||
|
</p>
|
||||||
|
');
|
||||||
|
HTMLPurifier_ConfigSchema::defineAlias('Attr', 'DisableURI', 'URI', 'Disable');
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'URI', 'DisableResources', false, 'bool', '
|
||||||
|
<p>
|
||||||
|
Disables embedding resources, essentially meaning no pictures. You can
|
||||||
|
still link to them though. See %URI.DisableExternalResources for why
|
||||||
|
this might be a good idea. This directive has been available since 1.3.0.
|
||||||
|
</p>
|
||||||
|
');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a URI as defined by RFC 3986.
|
* Validates a URI as defined by RFC 3986.
|
||||||
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
|
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
|
||||||
@@ -7,23 +68,18 @@
|
|||||||
class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $parser;
|
var $parser;
|
||||||
protected $embedsResource;
|
var $embedsResource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $embeds_resource_resource Does the URI here result in an extra HTTP request?
|
* @param $embeds_resource_resource Does the URI here result in an extra HTTP request?
|
||||||
*/
|
*/
|
||||||
public function __construct($embeds_resource = false) {
|
function HTMLPurifier_AttrDef_URI($embeds_resource = false) {
|
||||||
$this->parser = new HTMLPurifier_URIParser();
|
$this->parser = new HTMLPurifier_URIParser();
|
||||||
$this->embedsResource = (bool) $embeds_resource;
|
$this->embedsResource = (bool) $embeds_resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function make($string) {
|
function validate($uri, $config, &$context) {
|
||||||
$embeds = (bool) $string;
|
|
||||||
return new HTMLPurifier_AttrDef_URI($embeds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function validate($uri, $config, $context) {
|
|
||||||
|
|
||||||
if ($config->get('URI', 'Disable')) return false;
|
if ($config->get('URI', 'Disable')) return false;
|
||||||
|
|
||||||
@@ -44,7 +100,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
if (!$result) break;
|
if (!$result) break;
|
||||||
|
|
||||||
// chained filtering
|
// chained filtering
|
||||||
$uri_def = $config->getDefinition('URI');
|
$uri_def =& $config->getDefinition('URI');
|
||||||
$result = $uri_def->filter($uri, $config, $context);
|
$result = $uri_def->filter($uri, $config, $context);
|
||||||
if (!$result) break;
|
if (!$result) break;
|
||||||
|
|
||||||
@@ -55,10 +111,6 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
$result = $scheme_obj->validate($uri, $config, $context);
|
$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;
|
|
||||||
|
|
||||||
// survived gauntlet
|
// survived gauntlet
|
||||||
$ok = true;
|
$ok = true;
|
||||||
|
|
||||||
@@ -68,7 +120,18 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
if (!$ok) return false;
|
if (!$ok) return false;
|
||||||
|
|
||||||
// back to string
|
// back to string
|
||||||
return $uri->toString();
|
$result = $uri->toString();
|
||||||
|
|
||||||
|
// munge entire URI if necessary
|
||||||
|
if (
|
||||||
|
!is_null($uri->host) && // indicator for authority
|
||||||
|
!empty($scheme_obj->browsable) &&
|
||||||
|
!is_null($munge = $config->get('URI', 'Munge'))
|
||||||
|
) {
|
||||||
|
$result = str_replace('%s', rawurlencode($result), $munge);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
|
class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,3 +15,4 @@ abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sub-implementations
|
// sub-implementations
|
||||||
|
require_once 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef/URI/Email.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Primitive email validation class based on the regexp found at
|
* Primitive email validation class based on the regexp found at
|
||||||
* http://www.regular-expressions.info/email.html
|
* http://www.regular-expressions.info/email.html
|
||||||
@@ -7,7 +9,7 @@
|
|||||||
class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email
|
class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email
|
||||||
{
|
{
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
// no support for named mailboxes i.e. "Bob <bob@example.com>"
|
// no support for named mailboxes i.e. "Bob <bob@example.com>"
|
||||||
// that needs more percent encoding to be done
|
// that needs more percent encoding to be done
|
||||||
if ($string == '') return false;
|
if ($string == '') return false;
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||||
|
require_once 'HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
|
* Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
|
||||||
*/
|
*/
|
||||||
@@ -9,19 +13,19 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
|
|||||||
/**
|
/**
|
||||||
* Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator
|
* Instance of HTMLPurifier_AttrDef_URI_IPv4 sub-validator
|
||||||
*/
|
*/
|
||||||
protected $ipv4;
|
var $ipv4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator
|
* Instance of HTMLPurifier_AttrDef_URI_IPv6 sub-validator
|
||||||
*/
|
*/
|
||||||
protected $ipv6;
|
var $ipv6;
|
||||||
|
|
||||||
public function __construct() {
|
function HTMLPurifier_AttrDef_URI_Host() {
|
||||||
$this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
|
$this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
|
||||||
$this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
|
$this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($string, $config, $context) {
|
function validate($string, $config, &$context) {
|
||||||
$length = strlen($string);
|
$length = strlen($string);
|
||||||
if ($string === '') return '';
|
if ($string === '') return '';
|
||||||
if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
|
if ($length > 1 && $string[0] === '[' && $string[$length-1] === ']') {
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'HTMLPurifier/AttrDef.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates an IPv4 address
|
* Validates an IPv4 address
|
||||||
* @author Feyd @ forums.devnetwork.net (public domain)
|
* @author Feyd @ forums.devnetwork.net (public domain)
|
||||||
@@ -9,10 +11,11 @@ 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
|
||||||
|
* @protected
|
||||||
*/
|
*/
|
||||||
protected $ip4;
|
var $ip4;
|
||||||
|
|
||||||
public function validate($aIP, $config, $context) {
|
function validate($aIP, $config, &$context) {
|
||||||
|
|
||||||
if (!$this->ip4) $this->_loadRegex();
|
if (!$this->ip4) $this->_loadRegex();
|
||||||
|
|
||||||
@@ -29,7 +32,7 @@ class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef
|
|||||||
* Lazy load function to prevent regex from being stuffed in
|
* Lazy load function to prevent regex from being stuffed in
|
||||||
* cache.
|
* cache.
|
||||||
*/
|
*/
|
||||||
protected function _loadRegex() {
|
function _loadRegex() {
|
||||||
$oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255
|
$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})";
|
$this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})";
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user