autolink and html support
This commit is contained in:
parent
9e36b93ec6
commit
015b424f0d
8 changed files with 249 additions and 19 deletions
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"php-imap/php-imap": "~2.0",
|
"php-imap/php-imap": "~2.0",
|
||||||
"gnugat/PronounceableWord": "*"
|
"gnugat/PronounceableWord": "*",
|
||||||
|
"ezyang/htmlpurifier": "^4.9"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"vendor-dir": "src/backend-libs"
|
"vendor-dir": "src/backend-libs"
|
||||||
|
|
51
composer.lock
generated
51
composer.lock
generated
|
@ -4,9 +4,56 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "781cc38d2f745ec4bfba29e440111b80",
|
"hash": "c071b40be7f9bdf56a06a9e52d220684",
|
||||||
"content-hash": "70878ea12bce14861844baa8032688de",
|
"content-hash": "31df20b392f8545dda12635a78572bf7",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "ezyang/htmlpurifier",
|
||||||
|
"version": "v4.9.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ezyang/htmlpurifier.git",
|
||||||
|
"reference": "95e1bae3182efc0f3422896a3236e991049dac69"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/95e1bae3182efc0f3422896a3236e991049dac69",
|
||||||
|
"reference": "95e1bae3182efc0f3422896a3236e991049dac69",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"simpletest/simpletest": "^1.1"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"HTMLPurifier": "library/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"library/HTMLPurifier.composer.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Edward Z. Yang",
|
||||||
|
"email": "admin@htmlpurifier.org",
|
||||||
|
"homepage": "http://ezyang.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Standards compliant HTML filter written in PHP",
|
||||||
|
"homepage": "http://htmlpurifier.org/",
|
||||||
|
"keywords": [
|
||||||
|
"html"
|
||||||
|
],
|
||||||
|
"time": "2017-06-03 02:28:16"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "gnugat/PronounceableWord",
|
"name": "gnugat/PronounceableWord",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
|
|
@ -8,4 +8,5 @@ $baseDir = dirname(dirname($vendorDir));
|
||||||
return array(
|
return array(
|
||||||
'PronounceableWord_' => array($vendorDir . '/gnugat/PronounceableWord/src'),
|
'PronounceableWord_' => array($vendorDir . '/gnugat/PronounceableWord/src'),
|
||||||
'PhpImap' => array($vendorDir . '/php-imap/php-imap/src'),
|
'PhpImap' => array($vendorDir . '/php-imap/php-imap/src'),
|
||||||
|
'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
|
||||||
);
|
);
|
||||||
|
|
|
@ -47,6 +47,24 @@ class ComposerAutoloaderInit125dddd280a32cf75b181166154246ec
|
||||||
|
|
||||||
$loader->register(true);
|
$loader->register(true);
|
||||||
|
|
||||||
|
if ($useStaticLoader) {
|
||||||
|
$includeFiles = Composer\Autoload\ComposerStaticInit125dddd280a32cf75b181166154246ec::$files;
|
||||||
|
} else {
|
||||||
|
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||||
|
}
|
||||||
|
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||||
|
composerRequire125dddd280a32cf75b181166154246ec($fileIdentifier, $file);
|
||||||
|
}
|
||||||
|
|
||||||
return $loader;
|
return $loader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function composerRequire125dddd280a32cf75b181166154246ec($fileIdentifier, $file)
|
||||||
|
{
|
||||||
|
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||||
|
require $file;
|
||||||
|
|
||||||
|
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ namespace Composer\Autoload;
|
||||||
|
|
||||||
class ComposerStaticInit125dddd280a32cf75b181166154246ec
|
class ComposerStaticInit125dddd280a32cf75b181166154246ec
|
||||||
{
|
{
|
||||||
|
public static $files = array (
|
||||||
|
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
|
||||||
|
);
|
||||||
|
|
||||||
public static $prefixesPsr0 = array (
|
public static $prefixesPsr0 = array (
|
||||||
'P' =>
|
'P' =>
|
||||||
array (
|
array (
|
||||||
|
@ -18,6 +22,13 @@ class ComposerStaticInit125dddd280a32cf75b181166154246ec
|
||||||
0 => __DIR__ . '/..' . '/php-imap/php-imap/src',
|
0 => __DIR__ . '/..' . '/php-imap/php-imap/src',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
'H' =>
|
||||||
|
array (
|
||||||
|
'HTMLPurifier' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/ezyang/htmlpurifier/library',
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
|
|
|
@ -87,5 +87,54 @@
|
||||||
"word"
|
"word"
|
||||||
],
|
],
|
||||||
"abandoned": true
|
"abandoned": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ezyang/htmlpurifier",
|
||||||
|
"version": "v4.9.3",
|
||||||
|
"version_normalized": "4.9.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ezyang/htmlpurifier.git",
|
||||||
|
"reference": "95e1bae3182efc0f3422896a3236e991049dac69"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/95e1bae3182efc0f3422896a3236e991049dac69",
|
||||||
|
"reference": "95e1bae3182efc0f3422896a3236e991049dac69",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"simpletest/simpletest": "^1.1"
|
||||||
|
},
|
||||||
|
"time": "2017-06-03 02:28:16",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"HTMLPurifier": "library/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"library/HTMLPurifier.composer.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Edward Z. Yang",
|
||||||
|
"email": "admin@htmlpurifier.org",
|
||||||
|
"homepage": "http://ezyang.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Standards compliant HTML filter written in PHP",
|
||||||
|
"homepage": "http://htmlpurifier.org/",
|
||||||
|
"keywords": [
|
||||||
|
"html"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -155,5 +155,74 @@ function delete_old_messages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AutoLinkExtension {
|
||||||
|
static public function auto_link_text($string) {
|
||||||
|
|
||||||
|
$string = preg_replace_callback("/
|
||||||
|
((?<![\"']) # don't look inside quotes
|
||||||
|
(\b
|
||||||
|
( # protocol or www.
|
||||||
|
[a-z]{3,}:\/\/
|
||||||
|
|
|
||||||
|
www\.
|
||||||
|
)
|
||||||
|
(?: # domain
|
||||||
|
[a-zA-Z0-9_\-]+
|
||||||
|
(?:\.[a-zA-Z0-9_\-]+)*
|
||||||
|
|
|
||||||
|
localhost
|
||||||
|
)
|
||||||
|
(?: # port
|
||||||
|
\:[0-9]+
|
||||||
|
)?
|
||||||
|
(?: # path
|
||||||
|
\/[a-z0-9:%_|~.-]*
|
||||||
|
(?:\/[a-z0-9:%_|~.-]*)*
|
||||||
|
)?
|
||||||
|
(?: # attributes
|
||||||
|
\?[a-z0-9:%_|~.=&#;-]*
|
||||||
|
)?
|
||||||
|
(?: # anchor
|
||||||
|
\#[a-z0-9:%_|~.=&#;-]*
|
||||||
|
)?
|
||||||
|
)
|
||||||
|
(?![\"']))
|
||||||
|
/ix", function ($match) {
|
||||||
|
$url = $match[0];
|
||||||
|
$href = $url;
|
||||||
|
|
||||||
|
if (false === strpos($href, 'http')) {
|
||||||
|
$href = 'http://' . $href;
|
||||||
|
}
|
||||||
|
return '<a href="' . $href . '" rel="noreferrer">' . $url . '</a>';
|
||||||
|
}
|
||||||
|
, $string);
|
||||||
|
|
||||||
|
|
||||||
|
$string = AutoLinkExtension::unescape($string);
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
} # filter()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unescape()
|
||||||
|
*
|
||||||
|
* @param string $text
|
||||||
|
* @return string $text
|
||||||
|
**/
|
||||||
|
static function unescape($text) {
|
||||||
|
global $escape_autolink_uri;
|
||||||
|
|
||||||
|
if (!$escape_autolink_uri)
|
||||||
|
return $text;
|
||||||
|
|
||||||
|
$unescape = array_reverse($escape_autolink_uri);
|
||||||
|
|
||||||
|
return str_replace(array_keys($unescape), array_values($unescape), $text);
|
||||||
|
} # unescape()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// run on every request
|
// run on every request
|
||||||
delete_old_messages();
|
delete_old_messages();
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
require_once('backend.php');
|
require_once('backend.php');
|
||||||
|
|
||||||
|
$purifier_config = HTMLPurifier_Config::createDefault();
|
||||||
|
$purifier_config->set('HTML.Nofollow', true);
|
||||||
|
$purifier_config->set('HTML.ForbiddenElements', array("img"));
|
||||||
|
$purifier = new HTMLPurifier($purifier_config);
|
||||||
|
|
||||||
// simple router:
|
// simple router:
|
||||||
if (isset($_GET['username']) && isset($_GET['domain'])) {
|
if (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||||
$username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_EMAIL);
|
$username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_EMAIL);
|
||||||
|
@ -30,7 +35,6 @@ if (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
$emails = get_emails($address);
|
$emails = get_emails($address);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
@ -38,7 +42,7 @@ if (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title><?php echo $address ?></title>
|
<title><?php echo $address ?></title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.gif">
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
|
@ -77,7 +81,24 @@ if (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||||
|
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
reloadWithTurbolinks();
|
reloadWithTurbolinks();
|
||||||
}, 15000)
|
}, 15000);
|
||||||
|
|
||||||
|
|
||||||
|
function showHtml(id) {
|
||||||
|
document.getElementById('email-' + id + '-html').style.display = 'block';
|
||||||
|
document.getElementById('email-' + id + '-plain').style.display = 'none';
|
||||||
|
document.getElementById('show-html-button-' + id).style.display = 'none';
|
||||||
|
document.getElementById('show-plain-button-' + id).style.display = 'block';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showPlain(id) {
|
||||||
|
document.getElementById('email-' + id + '-html').style.display = 'none';
|
||||||
|
document.getElementById('email-' + id + '-plain').style.display = 'block';
|
||||||
|
document.getElementById('show-html-button-' + id).style.display = 'block';
|
||||||
|
document.getElementById('show-plain-button-' + id).style.display = 'none';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -95,11 +116,11 @@ if (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
|
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input id="username" class="form-control form-control-lg" name="username"
|
<input id="username" class="form-control form-control-lg" name="username" title="username"
|
||||||
value="<?php echo $username ?>">
|
value="<?php echo $username ?>">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<select id="domain" class="form-control form-control-lg" name="domain">
|
<select id="domain" class="form-control form-control-lg" name="domain" title="domain">
|
||||||
<?php
|
<?php
|
||||||
foreach ($config['domains'] as $domain) {
|
foreach ($config['domains'] as $domain) {
|
||||||
$selected = $domain === $userDomain ? ' selected ' : '';
|
$selected = $domain === $userDomain ? ' selected ' : '';
|
||||||
|
@ -166,9 +187,18 @@ if (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||||
<div class="col-sm-4 text-right">
|
<div class="col-sm-4 text-right">
|
||||||
<form class="form-inline float-xs-right">
|
<form class="form-inline float-xs-right">
|
||||||
|
|
||||||
<!-- TODO: switch between html and plaintext -->
|
<button type="button" class="btn btn-outline-info btn-sm"
|
||||||
<!-- <button class="btn btn-outline-info btn-sm">show html-->
|
style="display: block"
|
||||||
<!-- </button>-->
|
id="show-html-button-<?php echo filter_var($email->id, FILTER_VALIDATE_INT); ?>"
|
||||||
|
onclick="showHtml(<?php echo filter_var($email->id, FILTER_VALIDATE_INT); ?>)">
|
||||||
|
show html
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-info btn-sm"
|
||||||
|
style="display: none"
|
||||||
|
id="show-plain-button-<?php echo filter_var($email->id, FILTER_VALIDATE_INT); ?>"
|
||||||
|
onclick="showPlain(<?php echo filter_var($email->id, FILTER_VALIDATE_INT); ?>)">
|
||||||
|
show text
|
||||||
|
</button>
|
||||||
|
|
||||||
<a class="btn btn-sm btn-outline-primary " download="true"
|
<a class="btn btn-sm btn-outline-primary " download="true"
|
||||||
role="button"
|
role="button"
|
||||||
|
@ -216,17 +246,21 @@ if (isset($_GET['username']) && isset($_GET['domain'])) {
|
||||||
|
|
||||||
|
|
||||||
<div class="mt-2 card-text">
|
<div class="mt-2 card-text">
|
||||||
<!-- TODO: switch between html and plaintext -->
|
<!-- show plaintext or html -->
|
||||||
<div>
|
<div id="email-<?php echo filter_var($email->id, FILTER_VALIDATE_INT); ?>-plain"
|
||||||
<!-- TODO: applyAutolink
|
style="display: block;">
|
||||||
TODO: applyNewlines -->
|
|
||||||
<?php $text = filter_var($email->textPlain, FILTER_SANITIZE_SPECIAL_CHARS);
|
<?php $text = filter_var($email->textPlain, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||||
echo str_replace(' ', '<br />', $text);
|
// Keep newlines
|
||||||
|
$text = str_replace(' ', '<br />', $text);
|
||||||
|
echo \AutoLinkExtension::auto_link_text($text)
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="htmlTabActive">
|
<div id="email-<?php echo filter_var($email->id, FILTER_VALIDATE_INT); ?>-html"
|
||||||
<!-- TODO: stripHtml(mail.textHtml) -->
|
style="display: none;">
|
||||||
|
<?php
|
||||||
|
$clean_html = $purifier->purify($email->textHtml);
|
||||||
|
echo $clean_html;
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue