diff --git a/modules/filter/filter.module b/modules/filter/filter.module
index 7c8b2b88cf..6c7707937a 100644
--- a/modules/filter/filter.module
+++ b/modules/filter/filter.module
@@ -1511,6 +1511,9 @@ function _filter_url($text, $filter) {
$pattern = "`($url_pattern)($punctuation)`";
$tasks['_filter_url_parse_partial_links'] = $pattern;
+ // Allow modules to alter the tasks and patterns.
+ drupal_alter('filter_url_tasks', $tasks);
+
// Each type of URL needs to be processed separately. The text is joined and
// re-split after each task, since all injected HTML tags must be correctly
// protected before the next task.
diff --git a/modules/filter/filter.test b/modules/filter/filter.test
index 2af3103c12..96efe8442a 100644
--- a/modules/filter/filter.test
+++ b/modules/filter/filter.test
@@ -2043,3 +2043,50 @@ class FilterDOMSerializeTestCase extends DrupalWebTestCase {
$this->assertEqual('', $result);
}
}
+
+/**
+ * Tests drupal_alter invocations in the filter module.
+ */
+class FilterDrupalAlterTestCase extends DrupalWebTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Filter drupal_alter',
+ 'description' => 'Test drupal_alter invocations in the filter module.',
+ 'group' => 'Filter',
+ );
+ }
+
+ function setUp() {
+ parent::setUp('filter_test');
+ }
+
+ /**
+ * Tests hook_filter_url_tasks_alter().
+ */
+ function testDrupalAlterFilterUrlTasks() {
+
+ // Setup dummy filter object.
+ $filter = new stdClass();
+ $filter->settings = array(
+ 'filter_url_length' => 496,
+ );
+
+ $test_data = array(
+ '中文abc@example.com中文' => '中文abc@example.com中文',
+ '來信至xyz@來信至example.com' => '來信至xyz@來信至example.com',
+ );
+
+ variable_set('drupal_alter_filter_url_tasks', FALSE);
+ foreach ($test_data as $filter_input => $expected_output) {
+ $filter_output = _filter_url($filter_input, $filter);
+ $this->assertNotEqual($filter_output, $expected_output, 'Filter did not produce expected results without drupal_alter.');
+ }
+
+ variable_set('drupal_alter_filter_url_tasks', TRUE);
+ foreach ($test_data as $filter_input => $expected_output) {
+ $filter_output = _filter_url($filter_input, $filter);
+ $this->assertEqual($filter_output, $expected_output, 'Filter produced expected results with drupal_alter.');
+ }
+ }
+}
diff --git a/modules/simpletest/tests/filter_test.module b/modules/simpletest/tests/filter_test.module
index 63b7f66d67..b0f1a153e6 100644
--- a/modules/simpletest/tests/filter_test.module
+++ b/modules/simpletest/tests/filter_test.module
@@ -62,3 +62,13 @@ function filter_test_replace($text, $filter, $format, $langcode, $cache, $cache_
return implode("
\n", $text);
}
+/**
+ * Implements hook_filter_url_tasks_alter().
+ */
+function filter_test_filter_url_tasks_alter(&$tasks) {
+ if (!variable_get('drupal_alter_filter_url_tasks', FALSE)) {
+ return;
+ }
+ // Alter the pattern for parsing email links to add the unicode modifier.
+ $tasks['_filter_url_parse_email_links'] = $tasks['_filter_url_parse_email_links'] . 'u';
+}