From e551dc3895b0525bd023ca368e4ae04e48ec2c3a Mon Sep 17 00:00:00 2001
From: Nathan Gray <nathangray.bsc@gmail.com>
Date: Thu, 25 Aug 2011 22:42:07 +0000
Subject: [PATCH] URL widget - Still needs to get telephony link from server,
 felamimail not tested because egw.link_registry not populated

---
 etemplate/js/et2_widget_url.js       | 193 +++++++++++++++++++++++++++
 etemplate/js/etemplate2.js           |   1 +
 etemplate/js/test/et2_test_text.json |   7 +
 etemplate/js/test/et2_test_text.xet  |  14 ++
 etemplate/js/test/gfx/email.png      | Bin 0 -> 1015 bytes
 etemplate/js/test/gfx/phone.png      | Bin 0 -> 299 bytes
 etemplate/js/test/gfx/url.png        | Bin 0 -> 1038 bytes
 etemplate/js/test/test.css           |  20 +++
 etemplate/js/test/test.php           |   1 +
 etemplate/js/test/test_xml.html      |   3 +
 10 files changed, 239 insertions(+)
 create mode 100644 etemplate/js/et2_widget_url.js
 create mode 100644 etemplate/js/test/et2_test_text.json
 create mode 100644 etemplate/js/test/et2_test_text.xet
 create mode 100755 etemplate/js/test/gfx/email.png
 create mode 100755 etemplate/js/test/gfx/phone.png
 create mode 100755 etemplate/js/test/gfx/url.png

diff --git a/etemplate/js/et2_widget_url.js b/etemplate/js/et2_widget_url.js
new file mode 100644
index 0000000000..6f4c384d17
--- /dev/null
+++ b/etemplate/js/et2_widget_url.js
@@ -0,0 +1,193 @@
+/**
+ * eGroupWare eTemplate2 - JS URL object
+ *
+ * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
+ * @package etemplate
+ * @subpackage api
+ * @link http://www.egroupware.org
+ * @author Nathan Gray
+ * @copyright Nathan Gray 2011
+ * @version $Id$
+ */
+
+"use strict";
+
+/*egw:uses
+	et2_textbox;
+	et2_valueWidget;
+*/
+
+/**
+ * Class which implements the "url" XET-Tag, which covers URLs, email & phone
+ */ 
+var et2_url = et2_textbox.extend({
+
+	attributes: {
+		"multiline": {
+			"ignore": true
+		}
+	},
+
+	createInputWidget: function() {
+		this.input = $j(document.createElement("input"))
+			.blur(this,this.validate)
+			.blur(this,function(e){e.data.set_value(e.data.getValue());});
+
+		this._button = null;
+
+		console.log(this);
+
+		if(this.size) {
+			this.set_size(this.size);
+		}
+
+		this.setDOMNode(this.input[0]);
+	},
+
+	destroy: function() {
+		if(this.input) {
+			this.input.unbind();
+		}
+		this._button = null;
+	},
+
+	/**
+	 * Override parent to update href of 'button'
+	 */
+	set_value: function(_value) {
+		this.update_button(_value);
+		this._super.apply(this, arguments);
+	},
+
+	update_button: function(_value) {
+		if(this.value == _value) return;
+		if(_value)
+		{
+			// Create button if it doesn't exist yet
+			if(this._button == null)
+			{
+				this._button = $j(document.createElement("a")).addClass("et2_url");
+                                this.getSurroundings().insertDOMNode(this._button[0]);
+				this.getSurroundings().update();
+			}
+			this._button.removeClass("url phone email").removeAttr("href");
+			switch(this._type)
+			{
+				case "url":
+					// Silently use http if no protocol
+					if(_value.indexOf("://") == -1) _value = "http://"+_value;
+					this._button.attr("href", _value).attr("target", "_blank").addClass("url");
+					break;
+				case "url-phone":
+					if(navigator.userAgent.indexOf('AppleWebKit') !== -1 && (
+							navigator.userAgent.indexOf("iPhone") !== -1 ||
+							navigator.userAgent.indexOf("Android") !== -1 
+						) &&
+						 _value.indexOf("tel:") == -1)
+					{
+						 _value = "tel:"+_value;
+						this._button.attr("href", _value).addClass("phone").show();
+					} else if (false) {
+						// TODO: Check for telephony config, use link from server
+						//this._button.attr("href", _value).addClass("phone").show();
+					} else {
+						// Can't make a good handler, hide button
+						this._button.hide();
+					}
+					break;
+				case "url-email":
+					if(egw.link_registry && egw.link_registry.felamimail)
+					{
+						this._button.click(this, function() {
+							egw.open("","felamimail","add","send_to="+_value);
+						}).addClass("email");
+					}
+					else if(_value.indexOf("mailto:") == -1)
+					{
+						_value = "mailto:"+_value;
+						this._button.attr("href", _value).addClass("email");
+					}
+					break;
+			}
+		}
+		else
+		{
+			if(this._button)
+			{
+				this.getSurroundings().deleteDOMNode(this._button[0]);
+			}
+			this._button = null;
+		}
+	},
+
+	validate: function(e) {
+		e.data.hideMessage();
+
+		if(e.data._super) {
+			e.data._super.apply(this, arguments);
+		}
+
+		// Check value, and correct if possible
+		var value = jQuery.trim(e.data.getValue());
+		if(value == "") return;
+		switch(e.data._type) {
+			case "url":
+				if(value.indexOf("://") == -1) {
+					e.data.set_value("http://"+value);
+					e.data.showMessage(egw.lang("Protocol is required"), "hint", true);
+				}
+				break;
+		}
+	}
+});
+
+et2_register_widget(et2_url, ["url", "url-email", "url-phone"]);
+
+/**
+ * et2_url_ro is the readonly implementation of the url, email & phone.
+ * It renders things as links, when possible
+ */
+var et2_url_ro = et2_valueWidget.extend({
+
+	init: function() {
+		this._super.apply(this, arguments);
+
+		this.value = "";
+		this.span = $j(document.createElement("a"))
+			.addClass("et2_textbox readonly");
+
+		this.setDOMNode(this.span[0]);
+	},
+
+	set_value: function(_value) {
+		this.value = _value;
+
+		this.span.text(_value);
+		switch(this._type) {
+			case "url":
+				// Silently use http if no protocol
+				if(_value.indexOf("://") == -1) _value = "http://"+_value;
+				this.span.attr("href", _value).attr("target", "_blank");
+				break;
+			case "url-phone":
+				if(navigator.userAgent.indexOf('AppleWebKit') !== -1 && (
+						navigator.userAgent.indexOf("iPhone") !== -1 ||
+						navigator.userAgent.indexOf("Android") !== -1 
+				) {
+					if(_value.indexOf("tel:") == -1) _value = "tel:"+_value;
+					this.span.attr("href", _value);
+				} else {
+					//TODO: Check for telephony integration, use link from server
+				}
+				break;
+			case "url-email":
+				if(_value.indexOf("mailto:") == -1) _value = "mailto:"+_value;
+				this.span.attr("href", _value);
+				break;
+		}
+	}
+
+});
+
+et2_register_widget(et2_url_ro, ["url_ro", "url-email_ro", "url-phone_ro"]);
+
diff --git a/etemplate/js/etemplate2.js b/etemplate/js/etemplate2.js
index e7406ed84e..4b04ed0c8c 100644
--- a/etemplate/js/etemplate2.js
+++ b/etemplate/js/etemplate2.js
@@ -20,6 +20,7 @@
 	et2_widget_description;
 	et2_widget_textbox;
 	et2_widget_number;
+	et2_widget_url;
 	et2_widget_selectbox;
 	et2_widget_checkbox;
 	et2_widget_radiobox;
diff --git a/etemplate/js/test/et2_test_text.json b/etemplate/js/test/et2_test_text.json
new file mode 100644
index 0000000000..7b5f394966
--- /dev/null
+++ b/etemplate/js/test/et2_test_text.json
@@ -0,0 +1,7 @@
+var text_data = {
+	content: {
+		"url":	"www.egroupware.org",
+		"email": "",
+		"phone": "(866) 789-RACE"
+	},
+}
diff --git a/etemplate/js/test/et2_test_text.xet b/etemplate/js/test/et2_test_text.xet
new file mode 100644
index 0000000000..5fc46fb8a8
--- /dev/null
+++ b/etemplate/js/test/et2_test_text.xet
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!-- $Id$ -->
+<overlay>
+	<vbox cols="1" rows="3">
+		<textbox label="Plain text" id="text"/>
+		<url label="URL" id="url"/>
+		<url-email label="Email" id="email"/>
+		<url-phone label="Phone" id="phone"/>
+		<url label="URL" id="url" readonly="true"/>
+		<url-email label="Email" id="email" readonly="true"/>
+		<url-phone label="Phone" id="phone" readonly="true"/>
+		<button label="test" onclick="" statustext="button"/>
+	</vbox>
+</overlay>
diff --git a/etemplate/js/test/gfx/email.png b/etemplate/js/test/gfx/email.png
new file mode 100755
index 0000000000000000000000000000000000000000..45f313f07535a3df902d92e392061243ac002f89
GIT binary patch
literal 1015
zcmV<T0|@+yP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ
zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#iAh93RCwBA
z{Qv(y10?_;fLKnSJ_BVk0WmYf*RS6h{{3TQ`1$h>!;c@o8UFnF4;1?$!o<YlBO)Rk
z`{>a_fy&C{$PXXh-va3Z2p|@0rh;7c_wQfEfB*iO^YC!RC@4q=NlA%Fva_=>@bmL9
zC@E=0pF4N75vcSZKmef_0Mr1~_)nOTktIM}TqH(JOxRXPh>w|-m5t%ouip%B-h5(^
zmKJBQv2ph}fBx89phb@W0*Hl=j}K%c%h#{pOgT9?qGcq-0tJNxr8qb_8U6u-=lAbF
zAlERwfB%_*iHV7UlaqzP($c|T^=etG=g%KK0tg`HmoHv096NfL-@(!4u&BJ6<2Md|
z-hcmD7}%NqGO#cKy#fr6FJHa^!{ZkNH#a8(GczLt4-X&n#fvw--??*nCqMwP2uO-E
z{AJ;ky8cIyiR~TG#y|fUo__ep!1(hYgRS^i21P+8hR>hBG4S#6FtD&NgTqHkN&x5$
zSBC=!)@c9)5cA%Xr({IT+;+3_@kpCVGBSt@0W|=fdi6Ck!;UL|806VMFvy8=GjMTp
z0lmNo#vB|hK$mdwpFDZuHb4L|ZNB)m=FTGqMQtu%ME+r9c>j}u;qPw-pcfbz-u&fZ
z*mj$nK|qL`fsKs`h*=o8xY!xk*_jzsRTUUaOx%3{0*K}O6GlI8BL)UWpoY_L7#N;>
zVPN?98K@aZ{|5%(&SPI0O1*g*1i6{PG4=ZOcZL%uuKwG#YtN%ASB~5U2mnC<zW)T-
z-1rUe{{sM7HwOR{2LJ%#?EnDU=>P!l_5c9*=<)#V>-hld^8*0w=IH>wzsT{ox3$*H
z%)rLy=iSHs{r=Meh~@pW?|*LJ`^KQcC(7V!$j%_k`=4Ra)vpYq?7tZPzxm7{BF@dQ
zaL$6q`?oAVarOGSBcDFKKMQooJs<{J#qbLtfLIuQzB((-D&}k~&&t3I^o9&C1A`I&
zcLrH$HikoQxfs5EdG>9|+=jW29z0nE)bIp|zk<>nEb##Z5QDOPf`8@4zyGg%|Ns93
zFpmBJ@k<~+^7{Y(NvHq+w+YVP15{@X%`6xIAb^-ZJidIBm51>^zqFzC-G}VVAiuu`
z;z#elGc4$CJa%+t?<}CYV?g{Jn*jg;#0X>X$mj)dN;!nFF|!FXvHbn}_37cO@9v%1
l4U_`;`5h>aVKV?AzyJ($Un+X`6rcbA002ovPDHLkV1m!k;Z^_u

literal 0
HcmV?d00001

diff --git a/etemplate/js/test/gfx/phone.png b/etemplate/js/test/gfx/phone.png
new file mode 100755
index 0000000000000000000000000000000000000000..58ded805daa099d8951651fc0c0ba741247e6c65
GIT binary patch
literal 299
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;>1s;*b
z3=G^tAk28_ZrvZC;8{->$B>FSQzvf}JgmUuD!-FwanRy`DjByA98>gcyS%60YY}0Y
z>r~M9;+)-qJ^D-fnLh{as@!m$XHF2)0~>#aZMn=G#!RZu&+J+kFW>k0f#KwTyY!^H
zIh2w<Yc|^b6XjT2$N#UkNn&yD_uBbK8(ujqyp_?vN^C)e_@46z4?1jJAIWi*QNiZ+
zu{oPdf6tw0eZxH?^4G4Uo+VQvrX6+p^`_vmi{MX&cL~BDq;I)O%I<7ujN(6&{C?}I
uSr<6Ial3}PUo|P<_}=~Z{V(C1k4z^Pr%X+jyDkd!7=x#)pUXO@geCy>qIgIE

literal 0
HcmV?d00001

diff --git a/etemplate/js/test/gfx/url.png b/etemplate/js/test/gfx/url.png
new file mode 100755
index 0000000000000000000000000000000000000000..b4f686787d3b534280493a4aca7fc3e2b7e4bc41
GIT binary patch
literal 1038
zcmV+p1o8WcP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ
zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#ph-kQRCwBA
z{Qv(y!{d)18GbV`FuY-4Wcd7tUHsAWKXD(vFxY?m#-#lJ@4s(P9zVWxWO>ip+xr%5
z`Ty@P12O;zAV!!0e;ED)4PbG8^@Vd9%irH>yqs(d%>Nk~KK)@}xciZj;mK<ThU44T
zFFraWv-Ic3moH%k00a;d*c1?EWVU(oj&uFD|IBLQQXC9gqD%}jVvGzdyo?MS><kQ?
zTnr3q&VjL-QIi%jGBF9m3;+lqumLR03|uE4vQNGDftgp9n}I?4KTyLzh`}HQ%s~7X
z=#rnm7#PG%!rY~7QY(Q%tRTGr0R%SS(Kpt>V^0|Mj3gNt<behNeZ%kysNv~%28Lfh
zfLx%re**cxLEZ-%ETEeh&%(}b2+|7>KwtxoJ^1It{{J6?q7Vba51^uVK$}hj{e0&Q
z1H;4j3=EGyFfe@h1~d$4$e-^&7(RcK5aClWbpbgJAb`LIJbw0D_x6il498voZTb)K
z+pnJt4A0*IT>&)U^(O{~_g}ycWBB#%GsDN%{}{N$)OCPdK7arM8}R1MFSf@IzcZ{j
z`IBMaGoUR%F)a}W24e}J#?K54FMtO806Lxd#~+5*4?Z*S3vn{Aa&qwjm2m+C5ZC~w
z|BOH0KK{z^^zsLW)91f3y#D&1;TO;=+-yKE|M|!8`qeLn5BJ|O2><y4RQsPnRf~t=
z-><Krq{9RdKwtyDy}Nh)^%J1SKmK6Q7hz%mrImj`_i_LYVE*`-;p~nF46<xL83ef)
z8LnUY$ngBp8-_1WFFXeM2q1vK2HZcnXoIx00E4X_4}*awCxZYtBZCkJ1A`FI03SmR
zhT2qd1|Jt;hL6Bh<>4#Gz|C~`{f7sat^l=u1_&Uq0k@BB*rX`?=sX8E7Xv#mcDaF=
zj|GT<3Bf>#ogvtbpFvcJmBHLpfWgjPgyF@R87Ke#{&Nwi^*cZSferZZ^7+@x8%vA0
zMSp%|1=`FGOgX$j+j)S7Z~^f@U;uJ)GBW(*U}o4df6}eTC)TV3*$YZB009Kf3yh46
z;HVSRwhc;XnA*q0s436<?I(jU_kRXf4i*L#T@HrFZ+|e%?eD#Oa&f~#hW~%og3=!-
zSpftPiUHsl;Sx3x*6~ec5w*5pWfu_q`}gmEjz2fwzPq{Y{QEm6cLS9i1>$F*)D2P(
z5I`6PKmjKs6N3s9E2|{K|9`B1fBpRk)db3g-yn${0ssOG0A?{(v~=ZW`2YX_07*qo
IM6N<$f-G*(K>z>%

literal 0
HcmV?d00001

diff --git a/etemplate/js/test/test.css b/etemplate/js/test/test.css
index 32e0da3e27..7148a39d22 100644
--- a/etemplate/js/test/test.css
+++ b/etemplate/js/test/test.css
@@ -104,6 +104,26 @@ div.et2_hbox_right {
 	font-size: 10pt;
 }
 
+a.et2_url {
+	background-position: center;
+	background-repeat: no-repeat;
+
+	cursor: pointer;
+	margin: -4px;
+	padding: 2px;
+	padding-left: 16px;
+}
+
+a.et2_url.email {
+	background-image: url(gfx/email.png);
+}
+a.et2_url.phone {
+	background-image: url(gfx/phone.png);
+}
+a.et2_url.url {
+	background-image: url(gfx/url.png);
+}
+
 button.et2_button {
 	background-color: #E0E0E0;
 	background-image: url(gfx/gradient01.png);
diff --git a/etemplate/js/test/test.php b/etemplate/js/test/test.php
index 8622b86349..ce7734cc2c 100644
--- a/etemplate/js/test/test.php
+++ b/etemplate/js/test/test.php
@@ -29,6 +29,7 @@ Testing from inside framework, so JS includes work
                         <a href="#" onclick="open_xet('et2_test_template.xet');">Template proxy test</a>
                         <a href="#" onclick="open_xet('et2_test_grid.xet');">Grid test</a>
                         <a href="#" onclick="open_xet('et2_test_tabbox.xet');">Tabs test</a>
+                        <a href="#" onclick="open_xet('et2_test_text.xet');">Text/URL test</a>
                         <a href="#" onclick="open_xet('et2_test_basic_widgets.xet');">Basic widgits</a>
                         <a href="#" onclick="open_xet('et2_test_input_validator.xet', validation_data);">Validation</a>
                 </div>
diff --git a/etemplate/js/test/test_xml.html b/etemplate/js/test/test_xml.html
index 4aeeac5f34..6430291914 100644
--- a/etemplate/js/test/test_xml.html
+++ b/etemplate/js/test/test_xml.html
@@ -21,6 +21,7 @@
 		<script src="../et2_widget_box.js"></script>
 		<script src="../et2_widget_hbox.js"></script>
 		<script src="../et2_widget_textbox.js"></script>
+		<script src="../et2_widget_url.js"></script>
 		<script src="../et2_widget_number.js"></script>
 		<script src="../et2_widget_selectbox.js"></script>
 		<script src="../et2_widget_checkbox.js"></script>
@@ -47,6 +48,7 @@
 		<script src="et2_test_tabbox.json"></script>
 		<script src="et2_test_expressions.json"></script>
 		<script src="et2_test_dates.json"></script>
+		<script src="et2_test_text.json"></script>
 		<link rel="StyleSheet" type="text/css" href="./test.css" />
 		<link rel="StyleSheet" type="text/css" href="./grid.css" />
 
@@ -70,6 +72,7 @@
 			<a href="#" onclick="open_xet('et2_test_grid.xet');">Grid test</a>
 			<a href="#" onclick="open_xet('et2_test_tabbox.xet',tabbox_data);">Tabs test</a>
 			<a href="#" onclick="open_xet('et2_test_textbox.xet');">Textbox test</a>
+			<a href="#" onclick="open_xet('et2_test_text.xet', text_data);">Text/URL test</a>
 			<a href="#" onclick="open_xet('et2_test_description.xet');">Description test</a>
 			<a href="#" onclick="open_xet('et2_test_basic_widgets.xet');">Basic widgits</a>
 			<a href="#" onclick="open_xet('et2_test_date.xet',date_test_data);">Date/Time widgits</a>