Skip to content

Commit

Permalink
MDL-37138 weblib: Add blanktarget option to format_text
Browse files Browse the repository at this point in the history
  • Loading branch information
cameorn1730 committed May 30, 2016
1 parent 6a74e76 commit bf99748
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
52 changes: 52 additions & 0 deletions lib/tests/weblib_format_text_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,56 @@ public function test_format_text_overflowdiv() {
$this->assertEquals('<div class="no-overflow"><p>:-)</p></div>',
format_text('<p>:-)</p>', FORMAT_HTML, array('overflowdiv' => true)));
}

/**
* Test adding blank target attribute to links
*
* @dataProvider format_text_blanktarget_testcases
* @param string $link The link to add target="_blank" to
* @param string $expected The expected filter value
*/
public function test_format_text_blanktarget($link, $expected) {
$actual = format_text($link, FORMAT_MOODLE, array('blanktarget' => true, 'filter' => false, 'noclean' => true));
$this->assertEquals($expected, $actual);
}

/**
* Data provider for the test_format_text_blanktarget testcase
*
* @return array of testcases
*/
public function format_text_blanktarget_testcases() {
return [
'Simple link' =>
[
'<a href="https://www.youtube.com/watch?v=JeimE8Wz6e4">Hey, that\'s pretty good!</a>',
'<div class="text_to_html"><a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" target="_blank"' .
' rel="noreferrer">Hey, that\'s pretty good!</a></div>'
],
'Link with rel' =>
[
'<a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" rel="nofollow">Hey, that\'s pretty good!</a>',
'<div class="text_to_html"><a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" rel="nofollow noreferrer"' .
' target="_blank">Hey, that\'s pretty good!</a></div>'
],
'Link with rel noreferrer' =>
[
'<a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" rel="noreferrer">Hey, that\'s pretty good!</a>',
'<div class="text_to_html"><a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" rel="noreferrer"' .
' target="_blank">Hey, that\'s pretty good!</a></div>'
],
'Link with target' =>
[
'<a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" target="_self">Hey, that\'s pretty good!</a>',
'<div class="text_to_html"><a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" target="_self">' .
'Hey, that\'s pretty good!</a></div>'
],
'Link with target blank' =>
[
'<a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" target="_blank">Hey, that\'s pretty good!</a>',
'<div class="text_to_html"><a href="https://www.youtube.com/watch?v=JeimE8Wz6e4" target="_blank"' .
' rel="noreferrer">Hey, that\'s pretty good!</a></div>'
]
];
}
}
22 changes: 22 additions & 0 deletions lib/weblib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,7 @@ function format_text_menu() {
* with the class no-overflow before being returned. Default false.
* allowid : If true then id attributes will not be removed, even when
* using htmlpurifier. Default false.
* blanktarget : If true all <a> tags will have target="_blank" added unless target is explicitly specified.
* </pre>
*
* @staticvar array $croncache
Expand Down Expand Up @@ -1222,6 +1223,7 @@ function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseidd
if (!isset($options['overflowdiv'])) {
$options['overflowdiv'] = false;
}
$options['blanktarget'] = !empty($options['blanktarget']);

// Calculate best context.
if (empty($CFG->version) or $CFG->version < 2013051400 or during_initial_install()) {
Expand Down Expand Up @@ -1318,6 +1320,26 @@ function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseidd
$text = html_writer::tag('div', $text, array('class' => 'no-overflow'));
}

if ($options['blanktarget']) {
$domdoc = new DOMDocument();
$domdoc->loadHTML($text);
foreach ($domdoc->getElementsByTagName('a') as $link) {
if ($link->hasAttribute('target') && strpos($link->getAttribute('target'), '_blank') === false) {
continue;
}
$link->setAttribute('target', '_blank');
if (strpos($link->getAttribute('rel'), 'noreferrer') === false) {
$link->setAttribute('rel', trim($link->getAttribute('rel') . ' noreferrer'));
}
}

// This regex is nasty and I don't like it. The correct way to solve this is by loading the HTML like so:
// $domdoc->loadHTML($text, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); however it seems like the libxml
// version that travis uses doesn't work properly and ends up leaving <html><body>, so I'm forced to use
// this regex to remove those tags.
$text = trim(preg_replace('~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i', '', $domdoc->saveHTML()));
}

return $text;
}

Expand Down

0 comments on commit bf99748

Please sign in to comment.