Implement et2-url-* incl. r/o

ToDo: implement allow_path and trailing slash attributes for et2-url
This commit is contained in:
ralf 2022-03-10 10:15:59 +02:00
parent 6a8b14fd8e
commit ebaebf65ca
10 changed files with 310 additions and 24 deletions

View File

@ -13,7 +13,8 @@
use EGroupware\Api;
// add et2- prefix to following widgets/tags
const ADD_ET2_PREFIX_REGEXP = '#<((/?)([vh]?box|textbox|textarea|button|colorpicker|description))(/?|\s[^>]*)>#m';
const ADD_ET2_PREFIX_REGEXP = '#<((/?)([vh]?box|textbox|textarea|button|colorpicker|description|url(-email|-phone|-fax)?))(/?|\s[^>]*)>#m';
const ADD_ET2_PREFIX_LAST_GROUP = 5;
// switch evtl. set output-compression off, as we cant calculate a Content-Length header with transparent compression
ini_set('zlib.output_compression', 0);
@ -152,7 +153,8 @@ function send_template()
{
return '<' . $matches[2] . 'et2-' . $matches[3] .
// web-components must not be self-closing (no "<et2-button .../>", but "<et2-button ...></et2-button>")
(substr($matches[4], -1) === '/' ? substr($matches[4], 0, -1) . '></et2-' . $matches[3] : $matches[4]) . '>';
(substr($matches[ADD_ET2_PREFIX_LAST_GROUP], -1) === '/' ? substr($matches[ADD_ET2_PREFIX_LAST_GROUP], 0, -1) .
'></et2-' . $matches[3] : $matches[ADD_ET2_PREFIX_LAST_GROUP]) . '>';
}, $str);
// handling of date and partially implemented select widget (no search or tags attribute), incl. removing of type attribute
@ -175,14 +177,6 @@ function send_template()
return $matches[0];
}, $str);
// add et2- prefix to url widget, as far as it is currently implemented
$str = preg_replace_callback('#<url-(email|phone) (.*?)/>#', static function($matches)
{
if (strpos($matches[2], 'readonly="true"')) return $matches[0]; // leave readonly alone for now
return str_replace('<url-'.$matches[1], '<et2-url-'.$matches[1], substr($matches[0], 0, -2)).
'></et2-url-'.$matches[1].'>';
}, $str);
$processing = microtime(true);
if(isset($cache) && (file_exists($cache_dir = dirname($cache)) || mkdir($cache_dir, 0755, true)))

View File

@ -0,0 +1,64 @@
/**
* EGroupware eTemplate2 - Url input widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @link https://www.egroupware.org
* @author Ralf Becker
*/
/* eslint-disable import/no-extraneous-dependencies */
import {Et2InvokerMixin} from "./Et2InvokerMixin";
import {IsEmail} from "../Validators/IsEmail";
import {Et2Textbox} from "../Et2Textbox/Et2Textbox";
/**
* @customElement et2-url
*
* @ToDo: implement allow_path and trailing_slash attributes
*/
export class Et2Url extends Et2InvokerMixin(Et2Textbox)
{
/** @type {any} */
static get properties()
{
return {
...super.properties,
/**
* Allow a path instead of a URL, path must start with /, default false = not allowed
*/
allow_path: {
type: Boolean,
},
/**
* Require (or forbid) that the path ends with a /, default not checked
*/
trailing_slash: {
type: Boolean,
},
};
}
constructor()
{
super();
this.defaultValidators.push(new IsEmail());
this._invokerLabel = '⎆';
this._invokerTitle = 'Open';
this._invokerAction = () => {
Et2Url.action(this.value);
}
this.allow_path = false;
this.trailing_slash = undefined;
}
static action(value)
{
if (!value) return;
// implicit add http:// if no protocol given
if(value.indexOf("://") == -1) value = "http://"+value;
egw.open_link(value, '_blank');
}
}
// @ts-ignore TypeScript is not recognizing that this is a LitElement
customElements.define("et2-url", Et2Url);

View File

@ -23,15 +23,20 @@ export class Et2UrlEmail extends Et2InvokerMixin(Et2Textbox)
this.defaultValidators.push(new IsEmail());
this._invokerLabel = '@';
this._invokerTitle = 'Compose mail to';
this._invokerAction = () => this.__invokerAction();
this._invokerAction = () =>
{
if (!this._isEmpty() && !this.hasFeedbackFor.length)
{
Et2UrlEmail.action(this.value);
}
}
}
__invokerAction()
static action(value)
{
if (!this._isEmpty() && !this.hasFeedbackFor.length &&
this.egw().user('apps').mail && this.egw().preference('force_mailto','addressbook') != '1' )
if (egw.user('apps').mail && egw.preference('force_mailto','addressbook') != '1' )
{
egw.open_link('mailto:'+this.value);
egw.open_link('mailto:'+value);
}
}
}

View File

@ -0,0 +1,41 @@
/**
* EGroupware eTemplate2 - Email url/compose widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @link https://www.egroupware.org
* @author Ralf Becker
*/
/* eslint-disable import/no-extraneous-dependencies */
import {IsEmail} from "../Validators/IsEmail";
import {Et2UrlEmail} from "./Et2UrlEmail";
import {Et2UrlReadonly} from "./Et2UrlReadonly";
/**
* @customElement et2-url-email_ro
*/
export class Et2UrlEmailReadonly extends Et2UrlReadonly
{
constructor()
{
super();
}
transformAttributes(attrs)
{
if (typeof attrs.onclick === 'undefined')
{
attrs.onclick = () =>
{
if (IsEmail.EMAIL_PREG.exec(this.value))
{
Et2UrlEmail.action(this.value);
}
}
}
super.transformAttributes(attrs);
}
}
// @ts-ignore TypeScript is not recognizing that this is a LitElement
customElements.define("et2-url-email_ro", Et2UrlEmailReadonly);

View File

@ -0,0 +1,46 @@
/**
* EGroupware eTemplate2 - Fax input widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @link https://www.egroupware.org
* @author Ralf Becker
*/
/* eslint-disable import/no-extraneous-dependencies */
import {Et2UrlPhone} from "./Et2UrlPhone";
import {Et2UrlEmail} from "./Et2UrlEmail";
/**
* @customElement et2-url-phone
*/
export class Et2UrlFax extends Et2UrlPhone
{
constructor()
{
super();
//this.defaultValidators.push(...);
this._invokerLabel = '📠';
this._invokerTitle = 'Send';
this._invokerAction = () => {
Et2UrlFax.action(this.value);
}
}
static action(value)
{
// convert fax numbers to email, if configured
if (egw.config('fax_email') && (value = value.replace('&#9829;','').replace('(0)','').replace(/[^0-9+]/g, '')))
{
value = value.replace(new RegExp(egw.config('fax_email_regexp')||'(.*)'),
egw.config('fax_email'));
Et2UrlEmail.action(value);
}
else
{
Et2UrlPhone.action(value);
}
}
}
// @ts-ignore TypeScript is not recognizing that this is a LitElement
customElements.define("et2-url-fax", Et2UrlFax);

View File

@ -0,0 +1,37 @@
/**
* EGroupware eTemplate2 - Fax url/send widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @link https://www.egroupware.org
* @author Ralf Becker
*/
/* eslint-disable import/no-extraneous-dependencies */
import {Et2UrlFax} from "./Et2UrlFax";
import {Et2UrlReadonly} from "./Et2UrlReadonly";
/**
* @customElement et2-url-fax_ro
*/
export class Et2UrlFaxReadonly extends Et2UrlReadonly
{
constructor()
{
super();
}
transformAttributes(attrs)
{
if (typeof attrs.onclick === 'undefined')
{
attrs.onclick = () =>
{
Et2UrlFax.action(this.value);
}
}
super.transformAttributes(attrs);
}
}
// @ts-ignore TypeScript is not recognizing that this is a LitElement
customElements.define("et2-url-fax_ro", Et2UrlFaxReadonly);

View File

@ -22,12 +22,13 @@ export class Et2UrlPhone extends Et2InvokerMixin(Et2Textbox)
//this.defaultValidators.push(...);
this._invokerLabel = '✆';
this._invokerTitle = 'Call';
this._invokerAction = () => this.__invokerAction();
this._invokerAction = () => {
Et2UrlPhone.action(this.value);
}
}
__invokerAction()
static action(value)
{
let value = this.value;
// Clean number
value = value.replace('&#9829;','').replace('(0)','');
value = value.replace(/[abc]/gi,2).replace(/[def]/gi,3).replace(/[ghi]/gi,4).replace(/[jkl]/gi,5).replace(/[mno]/gi,6);
@ -41,15 +42,15 @@ export class Et2UrlPhone extends Et2InvokerMixin(Et2Textbox)
{
window.open("tel:"+value);
}
else if (this.egw().config("call_link"))
else if (egw.config("call_link"))
{
var link = this.egw().config("call_link")
var link = egw.config("call_link")
// tel: links use no URL encoding according to rfc3966 section-5.1.4
.replace("%1", this.egw().config("call_link").substr(0, 4) == 'tel:' ?
.replace("%1", egw.config("call_link").substr(0, 4) == 'tel:' ?
value : encodeURIComponent(value))
.replace("%u",this.egw().user('account_lid'))
.replace("%t",this.egw().user('account_phone'));
var popup = this.egw().config("call_popup");
.replace("%u",egw.user('account_lid'))
.replace("%t",egw.user('account_phone'));
var popup = egw.config("call_popup");
if (popup && popup !== '_self' || !link.match(/^https?:/)) // execute non-http(s) links eg. tel: like before
{
egw.open_link(link, '_phonecall', popup);

View File

@ -0,0 +1,37 @@
/**
* EGroupware eTemplate2 - Phone url/call widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @link https://www.egroupware.org
* @author Ralf Becker
*/
/* eslint-disable import/no-extraneous-dependencies */
import {Et2UrlPhone} from "./Et2UrlPhone";
import {Et2UrlReadonly} from "./Et2UrlReadonly";
/**
* @customElement et2-url-phone_ro
*/
export class Et2UrlPhoneReadonly extends Et2UrlReadonly
{
constructor()
{
super();
}
transformAttributes(attrs)
{
if (typeof attrs.onclick === 'undefined')
{
attrs.onclick = () =>
{
Et2UrlPhone.action(this.value);
}
}
super.transformAttributes(attrs);
}
}
// @ts-ignore TypeScript is not recognizing that this is a LitElement
customElements.define("et2-url-phone_ro", Et2UrlPhoneReadonly);

View File

@ -0,0 +1,55 @@
/**
* EGroupware eTemplate2 - Url r/o widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @link https://www.egroupware.org
* @author Ralf Becker
*/
/* eslint-disable import/no-extraneous-dependencies */
import {IsEmail} from "../Validators/IsEmail";
import {Et2Description} from "../Et2Description/Et2Description";
import {Et2UrlEmail} from "./Et2UrlEmail";
import {css} from "@lion/core";
import {Et2Url} from "./Et2Url";
/**
* @customElement et2-url_ro
*/
export class Et2UrlReadonly extends Et2Description
{
constructor()
{
super();
}
static get styles()
{
return [
...super.styles,
css`
:host {
cursor: pointer;
color: #26537c;
}`
];
}
transformAttributes(attrs)
{
if (typeof attrs.onclick === 'undefined')
{
attrs.onclick = () =>
{
if (this.value)
{
Et2Url.action(this.value);
}
}
}
super.transformAttributes(attrs);
}
}
// @ts-ignore TypeScript is not recognizing that this is a LitElement
customElements.define("et2-url_ro", Et2UrlReadonly);

View File

@ -46,8 +46,14 @@ import './Et2Textbox/Et2Number';
import './Et2Textbox/Et2NumberReadonly';
import './Et2Colorpicker/Et2Colorpicker';
import './Et2Taglist/Et2Taglist';
import './Et2Url/Et2Url';
import './Et2Url/Et2UrlReadonly';
import './Et2Url/Et2UrlEmail';
import './Et2Url/Et2UrlEmailReadonly';
import './Et2Url/Et2UrlPhone';
import './Et2Url/Et2UrlPhoneReadonly';
import './Et2Url/Et2UrlFax';
import './Et2Url/Et2UrlFaxReadonly';
/* Include all widget classes here, we only care about them registering, not importing anything*/
import './et2_widget_vfs'; // Vfs must be first (before et2_widget_file) due to import cycle