Commit 50d190a2 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(Utils): `encodeUrisToQmlFormat` supports images

parent 3ce0f2f2
......@@ -165,9 +165,9 @@ ColumnLayout {
ListElement { $dateSection: 1465389121000; $outgoing: true; $timestamp: 1465389121000; $type: 'message'; $content: "<img src='http://html.com/wp-content/uploads/html-com-1.png' width='50%' height='50%' />www.google.fr" }
ListElement { $dateSection: 1465389121000; $outgoing: true; $timestamp: 1465389121000; $type: 'message'; $content: "<a href='mailto:qq1@qqpart.com'>Contact mail</a>" }
ListElement { $dateSection: 1465389121000; $timestamp: 1465389133000; $type: 'event'; $content: 'incoming_call' }
ListElement { $dateSection: 1465389121000; $timestamp: 1465389439000; $type: 'message'; $content: '<blink>Perfect!</blink> bg g vg gv v g v hgv gv gv jhb jh b jb jh hg vg cfcy f v u uyg f tf tf ft f tf t t fy ft f tu ty f rd rd d d uu gu y gg y f r dr ' }
ListElement { $dateSection: 1465389121000; $timestamp: 1465389439000; $type: 'message'; $content: 'www.test.fr<blink>Perfect!</blink> bg g vg gv v g v hgv gv gv jhb jh b jb jh hg vg cfcy f v u uyg f tf tf ft f tf t t fy ft f tu ty f rd rd d d uu gu y gg y f r dr ' }
ListElement { $dateSection: 1465389121000; $timestamp: 1465389500000; $type: 'event'; $content: 'end_call' }
ListElement { $dateSection: 1465994221000; $outgoing: true; $timestamp: 1465924321000; $type: 'message'; $content: 'You\'ve heard the expression, "Just believe it and it will come." Well, technically, that is true, however, \'believing\' is not just thinking that you can have it...' }
ListElement { $dateSection: 1465994221000; $outgoing: true; $timestamp: 1465924321000; $type: 'message'; $content: 'https://cdn.pixabay.com/photo/2014/03/29/09/17/cat-300572_960_720.jpg You\'ve heard the expression, "Just believe it and http://writm.com/wp-content/uploads/2016/08/Cat-hd-wallpapers.jpg it will https://cdn.pixabay.com/photo/2014/03/29/09/17/cat-300572_960_720.jpg come." http://html.com/wp-content/uploads/html-com-1.png Well, technically, that is true, https://cdn.pixabay.com/photo/2014/03/29/09/17/cat-300572_960_720.jpg however, \'believing\' is not just thinking that you can have it...' }
ListElement { $dateSection: 1465994221000; $timestamp: 1465924391000; $type: 'event'; $content: 'lost_incoming_call' }
}
}
......
......@@ -45,7 +45,7 @@ Item {
// See http://doc.qt.io/qt-5/qml-qtquick-text.html#textFormat-prop
// and http://doc.qt.io/qt-5/richtext-html-subset.html
textFormat: Text.StyledText
textFormat: Text.RichText
onLinkActivated: Qt.openUrlExternally(link)
......
......@@ -4,6 +4,12 @@
.pragma library
// Options.
// If true, strings starting with `www.` can be detected.
// Not standard but helpful.
var SUPPORTS_URL = true
// Level 0. ----------------------------------------------------------
var URI_PCT_ENCODED = '%[A-Fa-f\\d]{2}'
......@@ -78,9 +84,11 @@ var URI_HIER_PART = '(?:' +
// Regex to match URI. It respects the RFC 3986.
// But many features are not supported like IP format.
var URI = URI_SCHEME + ':' + URI_HIER_PART + '(?:' +
'\\?' + URI_QUERY +
')?' + '(?:' + '#' + URI_FRAGMENT + ')?'
var URI = (SUPPORTS_URL
? '(?:' + URI_SCHEME + ':' + '|' + 'www\\.' + ')'
: URI_SCHEME + ':'
) + URI_HIER_PART + '(?:' + '\\?' + URI_QUERY + ')?' +
'(?:' + '#' + URI_FRAGMENT + ')?'
var URI_REGEX = new RegExp(URI, 'g')
......
......@@ -4,6 +4,10 @@
.import 'uri-tools.js' as UriTools
// ===================================================================
// QML helpers.
// ===================================================================
// Load by default a window in the ui/views folder.
// If options.isString is equals to true, a marshalling component can
// be used.
......@@ -67,24 +71,6 @@ function openConfirmDialog (parent, options) {
// -------------------------------------------------------------------
function _computeOptimizedCb (func, context) {
return (context != null)
? (function () {
return func.apply(context, arguments)
}) : func
}
// -------------------------------------------------------------------
// Convert a snake_case string to a lowerCamelCase string.
function snakeToCamel (s) {
return s.replace(/(\_\w)/g, function (matches) {
return matches[1].toUpperCase()
})
}
// -------------------------------------------------------------------
// A copy of `Window.setTimeout` from js.
// delay is in milliseconds.
function setTimeout (parent, delay, cb) {
......@@ -121,15 +107,6 @@ function connectOnce (signal, cb) {
// -------------------------------------------------------------------
// Basic assert function.
function assert (condition, message) {
if (!condition) {
throw new Error('Assert: ' + message)
}
}
// -------------------------------------------------------------------
// Returns the top (root) parent of one object.
function getTopParent (object, useFakeParent) {
function _getTopParent (object, useFakeParent) {
......@@ -165,6 +142,36 @@ function qmlTypeof (object, className) {
// -------------------------------------------------------------------
function encodeUrisToQmlFormat (text) {
var images = ''
text = text
.replace(/</g, '\u2063&lt;')
.replace(/>/g, '\u2063&gt;')
.replace(UriTools.URI_REGEX, function (match) {
// If it's a simple URL, transforms it in URI.
if (startsWith(match, 'www.')) {
match = 'http://' + match
}
var ext = getExtension(match)
if (includes([ 'jpg', 'jpeg', 'gif', 'png', 'svg' ], ext)) {
images += '<a href="' + match +
'"><img width="auto" height="48" src="' + match + '" /></a>'
}
return '<a href="' + match + '">' + match + '</a>'
})
if (images.length > 0) {
images = '<div>' + images + '</div>'
}
return images.concat(text)
}
// -------------------------------------------------------------------
// Test if a point is in a item.
//
// `source` is the item that generated the point.
......@@ -181,6 +188,55 @@ function pointIsInItem (source, target, point) {
)
}
// ===================================================================
// GENERIC.
// ===================================================================
function _computeOptimizedCb (func, context) {
return (context != null)
? (function () {
return func.apply(context, arguments)
}) : func
}
// -------------------------------------------------------------------
// Convert a snake_case string to a lowerCamelCase string.
function snakeToCamel (s) {
return s.replace(/(\_\w)/g, function (matches) {
return matches[1].toUpperCase()
})
}
// -------------------------------------------------------------------
// Basic assert function.
function assert (condition, message) {
if (!condition) {
throw new Error('Assert: ' + message)
}
}
// -------------------------------------------------------------------
// Returns the extension of a filename.
function getExtension (str) {
var index = str.lastIndexOf('.')
if (index === -1) {
return ''
}
return str.slice(index + 1)
}
// -------------------------------------------------------------------
// Test if a string starts by a given string.
function startsWith (str, searchStr) {
return str.slice(0, searchStr.length) === searchStr
}
// -------------------------------------------------------------------
// Invoke a `cb` function with each value of the interval: `[0, n[`.
......@@ -198,7 +254,12 @@ function times (n, cb, context) {
// -------------------------------------------------------------------
// Test if a var is a string.
function isArray (array) {
return (array instanceof Array)
}
// -------------------------------------------------------------------
function isString (string) {
return typeof string === 'string' || string instanceof String
}
......@@ -245,11 +306,40 @@ function genRandomNumberBetweenIntervals (intervals) {
// -------------------------------------------------------------------
function encodeUrisToQmlFormat (text) {
return text
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(UriTools.URI_REGEX, function (match) {
return '<a href="' + match + '">' + match + '</a>'
})
// Returns an array from a `object` or `array` argument.
function ensureArray (obj) {
if (isArray(obj)) {
return obj
}
var keys = Object.keys(obj)
var length = keys.length
var values = Array(length)
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]]
}
return values
}
// -------------------------------------------------------------------
// Test if a value is included in an array or object.
function includes (obj, value, startIndex) {
obj = ensureArray(obj)
if (startIndex == null) {
startIndex = 0
}
var length = obj.length
for (var i = startIndex; i < length; i++) {
if (value === obj[i]) {
return true
}
}
return false
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment