diff --git a/apps/calendar/index.html b/apps/calendar/index.html
index cc8ae816b5c4..cdd089918411 100644
--- a/apps/calendar/index.html
+++ b/apps/calendar/index.html
@@ -45,6 +45,11 @@
+
+
+
+
+
diff --git a/apps/calendar/js/common/link_action_handler.js b/apps/calendar/js/common/link_action_handler.js
new file mode 100644
index 000000000000..ce555487f11e
--- /dev/null
+++ b/apps/calendar/js/common/link_action_handler.js
@@ -0,0 +1,29 @@
+/* global ActivityPicker */
+
+define(function(require, exports, module) {
+ 'use strict';
+ /*
+ Centralized event handling for various
+ data-actions url, email, phone in a message
+ */
+
+ module.exports.onClick = function lah_onClick(event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ var dataset = event.target.dataset;
+ var action = dataset.action;
+
+ if (!action) {
+ return;
+ }
+
+ var type = action.replace('-link', '');
+
+ ActivityPicker[type](
+ dataset[type], this.reset, this.reset
+ );
+
+ };
+
+});
diff --git a/apps/calendar/js/views/view_event.js b/apps/calendar/js/views/view_event.js
index e13e10602483..93c2ee86f247 100644
--- a/apps/calendar/js/views/view_event.js
+++ b/apps/calendar/js/views/view_event.js
@@ -1,3 +1,5 @@
+/* global LinkHelper */
+
define(function(require, exports, module) {
'use strict';
@@ -6,6 +8,7 @@ var EventBase = require('./event_base');
var alarmTemplate = require('templates/alarm');
var localCalendarId = require('common/constants').localCalendarId;
var router = require('router');
+var linkActionHandler = require('common/link_action_handler');
require('dom!event-view');
@@ -27,6 +30,13 @@ ViewEvent.prototype = {
_initEvents: function() {
EventBase.prototype._initEvents.apply(this, arguments);
+ this.getEl('description').addEventListener('click', this);
+ },
+
+ handleEvent: function(e) {
+ if (e.type === 'click') {
+ linkActionHandler.onClick(e);
+ }
},
/**
@@ -126,7 +136,9 @@ ViewEvent.prototype = {
}
this.setContent('alarms', alarmContent, 'innerHTML');
- this.setContent('description', model.description);
+ var description = LinkHelper.searchAndLinkClickableData(model.description);
+
+ this.setContent('description', description, 'innerHTML');
},
oninactive: function() {
diff --git a/apps/calendar/style/event_view.css b/apps/calendar/style/event_view.css
index d6c5d7fee5ef..8ae711bb35a0 100644
--- a/apps/calendar/style/event_view.css
+++ b/apps/calendar/style/event_view.css
@@ -84,3 +84,8 @@
#event-view .current-calendar .content {
margin-inline-start: 1.2rem;
}
+
+#event-view .description a {
+ color: #00F;
+ text-decoration: underline;
+}
diff --git a/apps/sms/index.html b/apps/sms/index.html
index b97875e10acb..6872ba11e6c7 100644
--- a/apps/sms/index.html
+++ b/apps/sms/index.html
@@ -115,10 +115,10 @@
-
+
-
+
diff --git a/apps/sms/views/conversation/index.html b/apps/sms/views/conversation/index.html
index 70037c3bc3b5..14041455e2cc 100644
--- a/apps/sms/views/conversation/index.html
+++ b/apps/sms/views/conversation/index.html
@@ -87,7 +87,7 @@
-
+
@@ -111,7 +111,7 @@
-
+
diff --git a/apps/sms/views/conversation/js/startup.js b/apps/sms/views/conversation/js/startup.js
index 723badc69f51..8d01bd36f713 100644
--- a/apps/sms/views/conversation/js/startup.js
+++ b/apps/sms/views/conversation/js/startup.js
@@ -31,7 +31,7 @@
'/views/shared/js/error_dialog.js',
'/views/conversation/js/link_action_handler.js',
'/views/shared/js/contact_renderer.js',
- '/views/shared/js/activity_picker.js',
+ '/shared/js/links/activity_picker.js',
'/views/conversation/js/information.js',
'/views/shared/js/localization_helper.js'
];
diff --git a/apps/sms/views/conversation/test/unit/link_helper_test.js b/apps/sms/views/conversation/test/unit/link_helper_test.js
index e0e1c7a1b4e4..6052a08b5de1 100644
--- a/apps/sms/views/conversation/test/unit/link_helper_test.js
+++ b/apps/sms/views/conversation/test/unit/link_helper_test.js
@@ -5,9 +5,8 @@
*/
'use strict';
-require('/views/conversation/js/link_helper.js');
+require('/shared/js/links/link_helper.js');
-require('/views/shared/js/utils.js');
require('/views/shared/test/unit/mock_utils.js');
suite('link_helper_test.js', function() {
@@ -366,8 +365,9 @@ suite('link_helper_test.js', function() {
'http://stackoverflow.com/q/12882966/' +
' and call me at ' +
- '' +
- '+18155551212 or (e-mail +18155551212 or (e-mail ' +
+ 'user@hostname.tld)';
assert.equal(LinkHelper.searchAndLinkClickableData(test), expected);
});
diff --git a/apps/sms/views/inbox/index.html b/apps/sms/views/inbox/index.html
index e5fcdded4e61..e5a318a03a00 100644
--- a/apps/sms/views/inbox/index.html
+++ b/apps/sms/views/inbox/index.html
@@ -85,7 +85,7 @@
-
+
-->
diff --git a/apps/sms/views/inbox/js/startup.js b/apps/sms/views/inbox/js/startup.js
index 1cbc559cefd1..a16e4f4956f0 100644
--- a/apps/sms/views/inbox/js/startup.js
+++ b/apps/sms/views/inbox/js/startup.js
@@ -19,7 +19,7 @@
'/views/shared/js/waiting_screen.js',
'/views/shared/js/dialog.js',
'/views/shared/js/error_dialog.js',
- '/views/shared/js/activity_picker.js'
+ '/shared/js/links/activity_picker.js'
];
function initLazyDependencies() {
diff --git a/apps/sms/views/shared/js/startup.js b/apps/sms/views/shared/js/startup.js
index 7f71cb2e40b0..0fad3afff3f2 100644
--- a/apps/sms/views/shared/js/startup.js
+++ b/apps/sms/views/shared/js/startup.js
@@ -52,10 +52,10 @@ var Startup = exports.Startup = {
'/views/shared/js/errors.js',
'/views/shared/js/dialog.js',
'/views/shared/js/error_dialog.js',
- '/views/conversation/js/link_helper.js',
+ '/shared/js/links/link_helper.js',
'/views/conversation/js/link_action_handler.js',
'/views/shared/js/contact_renderer.js',
- '/views/shared/js/activity_picker.js',
+ '/shared/js/links/activity_picker.js',
'/views/conversation/js/information.js',
'/views/shared/js/shared_components.js',
'/views/shared/js/task_runner.js',
diff --git a/apps/sms/views/shared/test/unit/activity_picker_test.js b/apps/sms/views/shared/test/unit/activity_picker_test.js
index 9c25ae9a1397..2ced5e5c94ba 100644
--- a/apps/sms/views/shared/test/unit/activity_picker_test.js
+++ b/apps/sms/views/shared/test/unit/activity_picker_test.js
@@ -4,8 +4,7 @@
require('/shared/test/unit/mocks/mock_l20n.js');
-require('/views/shared/js/activity_picker.js');
-require('/views/shared/js/utils.js');
+require('/shared/js/links/activity_picker.js');
require('/views/shared/test/unit/mock_moz_activity.js');
require('/views/shared/test/unit/mock_utils.js');
@@ -13,7 +12,6 @@ require('/views/shared/test/unit/mock_utils.js');
var mocksHelperAP = new MocksHelper([
'MozActivity',
- 'Utils'
]).init();
suite('ActivityPicker', function() {
diff --git a/apps/sms/views/shared/test/unit/sms_test.js b/apps/sms/views/shared/test/unit/sms_test.js
index 67aea774bf32..03b281cc2ac7 100644
--- a/apps/sms/views/shared/test/unit/sms_test.js
+++ b/apps/sms/views/shared/test/unit/sms_test.js
@@ -36,7 +36,7 @@ require('/views/shared/test/unit/thread_list_mockup.js');
require('/views/shared/js/utils.js');
require('/views/shared/js/selection_handler.js');
require('/views/shared/js/navigation.js');
-require('/views/conversation/js/link_helper.js');
+require('/shared/js/links/link_helper.js');
require('/services/js/drafts.js');
require('/views/shared/js/contacts.js');
require('/views/conversation/js/subject_composer.js');
diff --git a/apps/sms/views/shared/js/activity_picker.js b/shared/js/links/activity_picker.js
similarity index 100%
rename from apps/sms/views/shared/js/activity_picker.js
rename to shared/js/links/activity_picker.js
diff --git a/apps/sms/views/conversation/js/link_helper.js b/shared/js/links/link_helper.js
similarity index 98%
rename from apps/sms/views/conversation/js/link_helper.js
rename to shared/js/links/link_helper.js
index f14efd2c4427..c91b1066d50b 100644
--- a/apps/sms/views/conversation/js/link_helper.js
+++ b/shared/js/links/link_helper.js
@@ -1,5 +1,3 @@
-/*global Utils */
-
(function() {
'use strict';
/*
@@ -59,6 +57,12 @@ function checkDomain(domain) {
// defines things that can match right before to be a "safe" link
var safeStart = /[\s,:;\(>\u0080-\uFFFF]/;
+var Utils = {
+ rnondialablechars: /[^,#+\*\d]/g,
+ removeNonDialables: function removeNonDialables(input){
+ return input.replace(this.rnondialablechars, '');
+ }
+};
const MINIMUM_DIGITS_IN_PHONE_NUMBER = 5;
const LEADING_DIGIT_BREAKPOINT = 7;
@@ -84,6 +88,7 @@ var LINK_TYPES = {
'(?:\\d[\\d \\t.()-]{0,12}\\d)' + // *
'\\b' // must end on a word boundary
].join(''), 'g'),
+
matchFilter: function phoneMatchFilter(phone, link) {
var onlyDigits = Utils.removeNonDialables(phone);
@@ -161,8 +166,8 @@ var LINK_TYPES = {
if (!linkSpec.match[1]) {
href = 'http://' + href;
}
- return '' + url +
- '';
+ return '' +
+ url + '';
}
},