From f4f7c9d15473d234eb3be4509a5b48027ca16d7f Mon Sep 17 00:00:00 2001 From: Mark Elphinstone-Hoadley Date: Mon, 8 Feb 2016 23:05:35 +0000 Subject: [PATCH 1/3] Add majority of 2.0 refactor --- angular-linkify.js | 73 ----------------------------------------- angular-linkify.min.js | 6 ---- bower.json | 2 +- dist/.gitignore | 2 ++ lib/directive.js | 26 +++++++++++++++ lib/filter.js | 14 ++++++++ lib/index.js | 13 ++++++++ lib/plugins/mentions.js | 38 +++++++++++++++++++++ lib/service.js | 39 ++++++++++++++++++++++ package.json | 29 ++++++++++------ webpack.base.config.js | 23 +++++++++++++ webpack.dev.config.js | 8 +++++ webpack.prod.config.js | 21 ++++++++++++ 13 files changed, 204 insertions(+), 90 deletions(-) delete mode 100644 angular-linkify.js delete mode 100644 angular-linkify.min.js create mode 100644 dist/.gitignore create mode 100644 lib/directive.js create mode 100644 lib/filter.js create mode 100644 lib/index.js create mode 100644 lib/plugins/mentions.js create mode 100644 lib/service.js create mode 100644 webpack.base.config.js create mode 100644 webpack.dev.config.js create mode 100644 webpack.prod.config.js diff --git a/angular-linkify.js b/angular-linkify.js deleted file mode 100644 index a00f413..0000000 --- a/angular-linkify.js +++ /dev/null @@ -1,73 +0,0 @@ -angular.module('linkify', []); - -angular.module('linkify') - .filter('linkify', function () { - 'use strict'; - - function linkify (_str, type) { - if (!_str) { - return; - } - - var _text = _str.replace( /(?:https?\:\/\/|www\.)+(?![^\s]*?")([\w.,@?!^=%&:\/~+#-]*[\w@?!^=%&\/~+#-])?/ig, function(url) { - var wrap = document.createElement('div'); - var anch = document.createElement('a'); - anch.href = url; - anch.target = "_blank"; - anch.innerHTML = url; - wrap.appendChild(anch); - return wrap.innerHTML; - }); - - // bugfix - if (!_text) { - return ''; - } - - // Twitter - if (type === 'twitter') { - _text = _text.replace(/(|\s)*@([\u00C0-\u1FFF\w]+)/g, '$1@$2'); - _text = _text.replace(/(^|\s)*#([\u00C0-\u1FFF\w]+)/g, '$1#$2'); - } - - - // Github - if (type === 'github') { - _text = _text.replace(/(|\s)*@(\w+)/g, '$1@$2'); - } - - return _text; - } - - // - return function (text, type) { - return linkify(text, type); - }; - }) - .factory('linkify', ['$filter', function ($filter) { - 'use strict'; - - function _linkifyAsType (type) { - return function (str) {(type, str); - return $filter('linkify')(str, type); - }; - } - - return { - twitter: _linkifyAsType('twitter'), - github: _linkifyAsType('github'), - normal: _linkifyAsType() - }; - }]) - .directive('linkify', ['$filter', '$timeout', 'linkify', function ($filter, $timeout, linkify) { - 'use strict'; - - return { - restrict: 'A', - link: function (scope, element, attrs) { - var type = attrs.linkify || 'normal'; - $timeout(function () { element.html(linkify[type](element.html())); }); - } - }; - }]); - diff --git a/angular-linkify.min.js b/angular-linkify.min.js deleted file mode 100644 index a0f01ae..0000000 --- a/angular-linkify.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/* -angular-linkify - v1.2.0 - 3/5/2015 -Angular filter to linkify urls, "@" usernames, and hashtags. -Copyright (c) 2015 ; Licensed -*/ -angular.module("linkify",[]),angular.module("linkify").filter("linkify",function(){"use strict";function linkify(_str,type){if(_str){var _text=_str.replace(/(?:https?\:\/\/|www\.)+(?![^\s]*?")([\w.,@?!^=%&:\/~+#-]*[\w@?!^=%&\/~+#-])?/gi,function(url){var wrap=document.createElement("div"),anch=document.createElement("a");return anch.href=url,anch.target="_blank",anch.innerHTML=url,wrap.appendChild(anch),wrap.innerHTML});return _text?("twitter"===type&&(_text=_text.replace(/(|\s)*@([\u00C0-\u1FFF\w]+)/g,'$1@$2'),_text=_text.replace(/(^|\s)*#([\u00C0-\u1FFF\w]+)/g,'$1#$2')),"github"===type&&(_text=_text.replace(/(|\s)*@(\w+)/g,'$1@$2')),_text):""}}return function(text,type){return linkify(text,type)}}).factory("linkify",["$filter",function($filter){"use strict";function _linkifyAsType(type){return function(str){return $filter("linkify")(str,type)}}return{twitter:_linkifyAsType("twitter"),github:_linkifyAsType("github"),normal:_linkifyAsType()}}]).directive("linkify",["$filter","$timeout","linkify",function($filter,$timeout,linkify){"use strict";return{restrict:"A",link:function(scope,element,attrs){var type=attrs.linkify||"normal";$timeout(function(){element.html(linkify[type](element.html()))})}}}]); \ No newline at end of file diff --git a/bower.json b/bower.json index b2cbbc5..539a865 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "angular-linkify", "version": "1.2.0", - "main": "angular-linkify.js", + "main": "dist/angular-linkify.js", "description": "Angular filter to linkify urls, \"@\" usernames, and hashtags.", "ignore": [ "**/.*", diff --git a/dist/.gitignore b/dist/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/dist/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/lib/directive.js b/lib/directive.js new file mode 100644 index 0000000..6d5840f --- /dev/null +++ b/lib/directive.js @@ -0,0 +1,26 @@ +var angular = require('angular'); +var linkifyElement = require('linkifyjs/element'); + +angular.module('linkify').directive('linkify',[ + 'linkify', + function (linkify) { + var defaultOptions = linkify.getOptions() || {}; + + var link = function (scope, element) { + var options = angular.extend(defaultOptions, scope.options); + + scope.$evalAsync(function () { + try { + linkifyElement(element[0], options); + } catch (e) {} + }); + }; + + return { + link: link, + scope: { + options: '=?linkify' + } + } + } +]) \ No newline at end of file diff --git a/lib/filter.js b/lib/filter.js new file mode 100644 index 0000000..ce8cea3 --- /dev/null +++ b/lib/filter.js @@ -0,0 +1,14 @@ +'use strict'; + +var angular = require('angular'); + +angular.module('linkify') + .filter('linkify', [ + 'linkify', + function (linkify) { + return function (str, options) { + if (!str) { return str; } + return linkify.parse(str, options); + }; + } + ]); \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..42f822e --- /dev/null +++ b/lib/index.js @@ -0,0 +1,13 @@ +'use strict'; + +var angular = require('angular'); +// add configuration for plugins +var linkifyjs = require('linkifyjs'); +require('linkifyjs/plugins/hashtag')(linkifyjs); +require('./plugins/mentions')(linkifyjs); + +module.exports = angular.module('linkify', []).name; + +require('./filter'); +require('./service'); +require('./directive'); \ No newline at end of file diff --git a/lib/plugins/mentions.js b/lib/plugins/mentions.js new file mode 100644 index 0000000..5958bb7 --- /dev/null +++ b/lib/plugins/mentions.js @@ -0,0 +1,38 @@ +'use strict'; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +function mention(linkify) { + var TT = linkify.scanner.TOKENS, + // Text tokens + MT = linkify.parser.TOKENS, + // Multi tokens + MultiToken = MT.Base, + S_START = linkify.parser.start, + S_AT = undefined, + S_MENTION = undefined; + + var MENTION = (function (_MultiToken) { + _inherits(MENTION, _MultiToken); + + function MENTION(value) { + _classCallCheck(this, MENTION); + + _MultiToken.call(this, value); + this.type = 'mention'; + this.isLink = true; + } + + return MENTION; + })(MultiToken); + + S_AT = new linkify.parser.State(); + S_MENTION = new linkify.parser.State(MENTION); + + S_START.on(TT.AT, S_AT); + S_AT.on(TT.DOMAIN, S_MENTION); + S_AT.on(TT.TLD, S_MENTION); +} + +module.exports = mention; \ No newline at end of file diff --git a/lib/service.js b/lib/service.js new file mode 100644 index 0000000..3ac0dd0 --- /dev/null +++ b/lib/service.js @@ -0,0 +1,39 @@ +'use strict'; + +var linkifyjs = require('linkifyjs'); +var linkifyHtml = require('linkifyjs/html'); +var angular = require('angular'); + +angular.module('linkify') + .provider('linkify', function () { + var defaultOptions = { + formatHref: function (value, type) { + if (type === 'hashtag') { + return 'https://twitter.com/hashtag/' + value.substring(1); + } + if (type === 'mention') { + return 'https://www.github.com/' + value.substring(1); + } + return value; + } + }; + + this.setOptions = function (options) { + defaultOptions = angular.extend(defaultOptions, options); + }; + + this.$get = [ + function () { + return { + parse: function (str, options) { + if (!str) { return str; } + if (!options) { return linkifyHtml(str, defaultOptions); } + return linkifyHtml(str, angular.extend(defaultOptions, options)); + }, + getOptions: function () { + return defaultOptions; + } + }; + } + ]; + }); \ No newline at end of file diff --git a/package.json b/package.json index 67da783..1a2fa80 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,10 @@ { "name": "angular-linkify", - "version": "1.2.0", - "description": "Angular filter to linkify urls, \"@\" usernames, and hashtags.", - "main": "angular-linkify.js", - "directories": { - "test": "test" - }, + "version": "2.0.0", + "description": "Angular filter to linkify urls, @mentions and #hashtags.", + "main": "lib/index.js", "scripts": { + "prepublish": "webpack -p --config webpack.prod.config.js", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -21,13 +19,24 @@ "twitter" ], "author": "Scott Corgan", - "license": "BSD", + "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/scottcorgan/angular-linkify/issues" }, "devDependencies": { - "grunt": "~0.4.1", - "grunt-contrib-jshint": "~0.6.0", - "grunt-contrib-uglify": "~0.2.2" + "angular-mocks": "^1.5.0", + "chai": "^3.5.0", + "karma": "^0.13.19", + "karma-chai": "^0.1.0", + "karma-mocha": "^0.2.1", + "karma-webpack": "^1.7.0", + "mocha": "^2.4.5", + "phantomjs": "^2.1.3", + "phantomjs-polyfill": "0.0.1", + "webpack": "^1.12.13" + }, + "dependencies": { + "angular": "^1.5.0", + "linkify": "^0.2.1" } } diff --git a/webpack.base.config.js b/webpack.base.config.js new file mode 100644 index 0000000..e4a1732 --- /dev/null +++ b/webpack.base.config.js @@ -0,0 +1,23 @@ +'use strict'; + +var webpack = require('webpack'); + +module.exports = { + entry: './lib/index.js', + + resolve: { + modulesDirectories: ['node_modules', 'bower_components'], + extensions: ['', '.js'] + }, + + output: { + library: 'AngularLinkify', + libraryTarget: 'umd', + path: './dist', + filename: 'angular-linkify.js' + }, + + module: { + loaders: [] + } +}; \ No newline at end of file diff --git a/webpack.dev.config.js b/webpack.dev.config.js new file mode 100644 index 0000000..078130b --- /dev/null +++ b/webpack.dev.config.js @@ -0,0 +1,8 @@ +'use strict' +var baseConfig = require('./webpack.base.config.js'); + +var config = baseConfig; + +config.devtool = "inline-source-map"; + +module.exports = config; \ No newline at end of file diff --git a/webpack.prod.config.js b/webpack.prod.config.js new file mode 100644 index 0000000..c884b6f --- /dev/null +++ b/webpack.prod.config.js @@ -0,0 +1,21 @@ +'use strict' + +var webpack = require('webpack'); +var baseConfig = require('./webpack.base.config.js'); + +var config = baseConfig; + +config.plugins = [ + new webpack.optimize.OccurenceOrderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + warnings: false + }, + sourceMap: false + }) +]; + +module.exports = config; \ No newline at end of file From 143d67bf440d46a671f88e0b49097646792d41f3 Mon Sep 17 00:00:00 2001 From: Mark Elphinstone-Hoadley Date: Mon, 8 Feb 2016 23:31:53 +0000 Subject: [PATCH 2/3] Add webpack build for publishing --- lib/service.js | 1 - package.json | 2 +- webpack.base.config.js | 12 ++++++++++++ webpack.prod.config.js | 13 +++---------- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/service.js b/lib/service.js index 3ac0dd0..fb7f393 100644 --- a/lib/service.js +++ b/lib/service.js @@ -1,6 +1,5 @@ 'use strict'; -var linkifyjs = require('linkifyjs'); var linkifyHtml = require('linkifyjs/html'); var angular = require('angular'); diff --git a/package.json b/package.json index 1a2fa80..32c408e 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,6 @@ }, "dependencies": { "angular": "^1.5.0", - "linkify": "^0.2.1" + "linkifyjs": "^2.0.0-beta.9" } } diff --git a/webpack.base.config.js b/webpack.base.config.js index e4a1732..2fccd6a 100644 --- a/webpack.base.config.js +++ b/webpack.base.config.js @@ -10,6 +10,18 @@ module.exports = { extensions: ['', '.js'] }, + externals: [ + { + linkifyjs: "linkify", + angular: { + root: "angular", + commonjs2: "angular", + commonjs: "angular", + amd: "angular" + } + } + ], + output: { library: 'AngularLinkify', libraryTarget: 'umd', diff --git a/webpack.prod.config.js b/webpack.prod.config.js index c884b6f..98c68bb 100644 --- a/webpack.prod.config.js +++ b/webpack.prod.config.js @@ -6,16 +6,9 @@ var baseConfig = require('./webpack.base.config.js'); var config = baseConfig; config.plugins = [ - new webpack.optimize.OccurenceOrderPlugin(), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify('production') - }), - new webpack.optimize.UglifyJsPlugin({ - compressor: { - warnings: false - }, - sourceMap: false - }) + new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }), + new webpack.optimize.DedupePlugin(), + new webpack.optimize.UglifyJsPlugin() ]; module.exports = config; \ No newline at end of file From 4826c760199a094f39c48daf3d6ee7364ab4b383 Mon Sep 17 00:00:00 2001 From: Mark Elphinstone-Hoadley Date: Mon, 8 Feb 2016 23:45:15 +0000 Subject: [PATCH 3/3] remove linkifyjs externals --- webpack.base.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/webpack.base.config.js b/webpack.base.config.js index 2fccd6a..5852dfa 100644 --- a/webpack.base.config.js +++ b/webpack.base.config.js @@ -12,7 +12,6 @@ module.exports = { externals: [ { - linkifyjs: "linkify", angular: { root: "angular", commonjs2: "angular",