From 6385f42ebce5ac1395f32f68db349c80696688b4 Mon Sep 17 00:00:00 2001 From: "Bradley M. Froehle" Date: Sun, 13 Feb 2011 20:34:32 -0800 Subject: [PATCH] Add AutoFormat.LinkifyEmail Option. If enabled, automatically provide links to e-mail addresses. For example, Send an e-mail to user@example.com. is transformed to Send an e-mail to user@example.com. Signed-off-by: Bradley M. Froehle --- NEWS | 2 + configdoc/usage.xml | 3 ++ library/HTMLPurifier.includes.php | 1 + library/HTMLPurifier.safe-includes.php | 1 + library/HTMLPurifier/ConfigSchema/schema.ser | Bin 13966 -> 14071 bytes .../schema/AutoFormat.LinkifyEmail.txt | 12 +++++ .../HTMLPurifier/Injector/LinkifyEmail.php | 43 +++++++++++++++ .../Injector/LinkifyEmailTest.php | 50 ++++++++++++++++++ 8 files changed, 112 insertions(+) create mode 100644 library/HTMLPurifier/ConfigSchema/schema/AutoFormat.LinkifyEmail.txt create mode 100644 library/HTMLPurifier/Injector/LinkifyEmail.php create mode 100644 tests/HTMLPurifier/Injector/LinkifyEmailTest.php diff --git a/NEWS b/NEWS index f43cde3a..975b9dfc 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier directory/file permissions ! Fix longstanding bug in Flash support for non-IE browsers, and allow more wmode attributes. +! Add %AutoFormat.LinkifyEmail option for automatically linking + to e-mail addresses. - Switch to an iterative traversal of the DOM, which prevents us from running out of stack space for deeply nested documents. Thanks Maxim Krizhanovsky for contributing a patch. diff --git a/configdoc/usage.xml b/configdoc/usage.xml index a401a9ee..871c2440 100644 --- a/configdoc/usage.xml +++ b/configdoc/usage.xml @@ -254,6 +254,9 @@ 64 + + 75 + diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index abee9a2e..b7f68f51 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -176,6 +176,7 @@ require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php'; require 'HTMLPurifier/Injector/AutoParagraph.php'; require 'HTMLPurifier/Injector/DisplayLinkURI.php'; require 'HTMLPurifier/Injector/Linkify.php'; +require 'HTMLPurifier/Injector/LinkifyEmail.php'; require 'HTMLPurifier/Injector/PurifierLinkify.php'; require 'HTMLPurifier/Injector/RemoveEmpty.php'; require 'HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php'; diff --git a/library/HTMLPurifier.safe-includes.php b/library/HTMLPurifier.safe-includes.php index a5c0d5bb..89948529 100644 --- a/library/HTMLPurifier.safe-includes.php +++ b/library/HTMLPurifier.safe-includes.php @@ -170,6 +170,7 @@ 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/LinkifyEmail.php'; require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php'; require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php'; require_once $__dir . '/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php'; diff --git a/library/HTMLPurifier/ConfigSchema/schema.ser b/library/HTMLPurifier/ConfigSchema/schema.ser index 1a70feba4e11e9efc163a8e4b76c137950e2d064..ddb044dc9b7aa83b64b5a84ba3ba77d75afd1279 100644 GIT binary patch delta 93 zcmeCn{hm9)oY7+PMMc@ox`OdcOh(3&3xq{jU2_vNb2hJGO6J2ODa|)|zM>(c;pU5q N?98Y-FR1Jj1ORf+9Wnp_ delta 51 zcmeyK+m}1RoY8!vMGe#D>rBynaHcTd;j0O`eWH*~Ay<(btNmzYzhHAec0Po!r ATmS$7 diff --git a/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.LinkifyEmail.txt b/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.LinkifyEmail.txt new file mode 100644 index 00000000..97a9bdb2 --- /dev/null +++ b/library/HTMLPurifier/ConfigSchema/schema/AutoFormat.LinkifyEmail.txt @@ -0,0 +1,12 @@ +AutoFormat.LinkifyEmail +TYPE: bool +VERSION: 4.3.0 +DEFAULT: false +--DESCRIPTION-- + +

+ This directive turns on e-mail linkification, auto-linking e-mail addresses. + a tags with the href attribute + must be allowed. +

+--# vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Injector/LinkifyEmail.php b/library/HTMLPurifier/Injector/LinkifyEmail.php new file mode 100644 index 00000000..e756bf42 --- /dev/null +++ b/library/HTMLPurifier/Injector/LinkifyEmail.php @@ -0,0 +1,43 @@ + array('href')); + + public function handleText(&$token) { + if (!$this->allowsElement('a')) return; + + if (strpos($token->data, '@') === false) { + // our really quick heuristic failed, abort + return; + } + + // e-mail regex comes from Drupal 7, see http://api.drupal.org/_filter_url + $bits = preg_split('#([A-Za-z0-9._-]+@(?:(?:[A-Za-z0-9._+-]+\.)?[A-Za-z]{2,64}\b))#S', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE); + + $token = array(); + + // $i = index + // $c = count + // $l = is link + for ($i = 0, $c = count($bits), $l = false; $i < $c; $i++, $l = !$l) { + if (!$l) { + if ($bits[$i] === '') continue; + $token[] = new HTMLPurifier_Token_Text($bits[$i]); + } else { + $token[] = new HTMLPurifier_Token_Start('a', array('href' => 'mailto:' . $bits[$i])); + $token[] = new HTMLPurifier_Token_Text($bits[$i]); + $token[] = new HTMLPurifier_Token_End('a'); + } + } + + } + +} + +// vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/Injector/LinkifyEmailTest.php b/tests/HTMLPurifier/Injector/LinkifyEmailTest.php new file mode 100644 index 00000000..a99fef09 --- /dev/null +++ b/tests/HTMLPurifier/Injector/LinkifyEmailTest.php @@ -0,0 +1,50 @@ +config->set('AutoFormat.LinkifyEmail', true); + } + + function testLinkifyEmailInRootNode() { + $this->assertResult( + 'user@example.com', + 'user@example.com' + ); + } + + function testLinkifyEmailLInInlineNode() { + $this->assertResult( + 'user@example.com', + 'user@example.com' + ); + } + + function testBasicUsageCase() { + $this->assertResult( + 'This e-mail user@example.com is what you need', + 'This e-mail user@example.com is what you need' + ); + } + + function testIgnoreEmailInATag() { + $this->assertResult( + 'user@example.com' + ); + } + + function testNeeded() { + $this->config->set('HTML.Allowed', 'b'); + $this->expectError('Cannot enable LinkifyEmail injector because a is not allowed'); + $this->assertResult('user@example.com'); + } + + function testExcludes() { + $this->assertResult('user@example.com'); + } + +} + +// vim: et sw=4 sts=4