diff --git a/dist/vue-linkify.min.js b/dist/vue-linkify.min.js index f46c0f9..4bd2a58 100644 --- a/dist/vue-linkify.min.js +++ b/dist/vue-linkify.min.js @@ -1 +1 @@ -'use strict';var _typeof='function'==typeof Symbol&&'symbol'==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&'function'==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?'symbol':typeof obj};/*global define*/var _html=require('linkifyjs/html'),_html2=_interopRequireDefault(_html);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}(function(){function a(b,c){b.innerHTML=(0,_html2.default)(b.innerHTML,c.value)}'object'==('undefined'==typeof exports?'undefined':_typeof(exports))?module.exports=a:'function'==typeof define&&define.amd?define([],function(){return a}):window.Vue&&window.Vue.directive('linkified',a)})(); +'use strict';var _typeof='function'==typeof Symbol&&'symbol'==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&'function'==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?'symbol':typeof obj};/*global define*/var _html=require('linkifyjs/html'),_html2=_interopRequireDefault(_html);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}(function(){function a(d,e){return'<'+d+'>'+e+''}function b(d,e,f){var g=d.text,h=d.tag,i=d.children;if(g)return(0,_html2.default)(g,e);if(i){var j=i.map(function(k){return b(k,e,!1)}).join('');return f?j:a(h,j)}}function c(d,e,f){d.innerHTML=f.data.domProps&&f.data.domProps.innerHTML?(0,_html2.default)(d.innerHTML,e.value):b(f,e.value,!0)}'object'==('undefined'==typeof exports?'undefined':_typeof(exports))?module.exports=c:'function'==typeof define&&define.amd?define([],function(){return c}):window.Vue&&window.Vue.directive('linkified',c)})(); diff --git a/index.js b/index.js index bc98bd9..d3db1da 100644 --- a/index.js +++ b/index.js @@ -2,8 +2,29 @@ import linkify from 'linkifyjs/html' (function () { - function install (el, binding) { - el.innerHTML = linkify(el.innerHTML, binding.value) + function surround (tagName, content) { + return `<${tagName}>${content}` + } + + function traverse (vnode, opts, isParent) { + const { text, tag, children } = vnode + if (text) return linkify(text, opts) + if (children) { + const content = children.map(childVNode => traverse(childVNode, opts, false)).join('') + if (isParent) return content + return surround(tag, content) + } + } + + function install (el, binding, vnode) { + if (vnode.data.domProps && vnode.data.domProps.innerHTML) { + // when v-html is used + el.innerHTML = linkify(el.innerHTML, binding.value) + } else { + // when `{{}}` syntax is used + const isParent = true + el.innerHTML = traverse(vnode, binding.value, isParent) + } } if (typeof exports === 'object') { diff --git a/package.json b/package.json index c47d33e..12484d6 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "lint": "./node_modules/.bin/eslint index.js", "build": "./node_modules/.bin/eslint index.js && BABEL_ENV=production && babel index.js -o ./dist/vue-linkify.min.js", - "test": "npm build && karma start test/unit/karma.conf.js --single-run" + "test": "npm run build && karma start test/unit/karma.conf.js --single-run" }, "keywords": [ "vue", diff --git a/test/unit/index.js b/test/unit/index.js index 17db9d1..700c133 100644 --- a/test/unit/index.js +++ b/test/unit/index.js @@ -25,4 +25,46 @@ describe('vue-linkify', () => { expect(vm.$el.innerHTML).to.be .equal('Hello from vuejs.org') }) + + it('should correctly linkify content with {{}} syntax', () => { + const vm = new Vue({ + el: document.createElement('div'), + data: { + msg: 'https://vuejs.org' + }, + template: 'Site url: {{ msg }}' + }).$mount() + + expect(vm.$el.innerHTML).to.be + .equal('Site url: https://vuejs.org') + }) + + it('should correctly linkify content with {{}} syntax and options', () => { + const vm = new Vue({ + el: document.createElement('div'), + data: { + msg: 'https://vuejs.org' + }, + template: 'Site url: {{ msg }}' + }).$mount() + + expect(vm.$el.innerHTML).to.be + .equal('Site url: https://vuejs.org') + }) + + it('should correctly linkify content with {{}} even after update', () => { + const vm = new Vue({ + el: document.createElement('div'), + data: { + msg: 'https://vuejs.org' + }, + template: 'Site url: {{ msg }}' + }).$mount() + + vm.msg = 'https://reactjs.org' + Vue.nextTick(() => { + expect(vm.$el.innerHTML).to.be + .equal('Site url: https://reactjs.org') + }) + }) })