diff --git a/package-lock.json b/package-lock.json index 7b77f7e2e1de..e5cc670bfe63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2857,6 +2857,24 @@ "sha.js": "^2.4.8" } }, + "create-html-element": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/create-html-element/-/create-html-element-2.1.0.tgz", + "integrity": "sha512-ofbOpJh3GSDsyINuqppupKRUcQHnXSyvwvk0F5DlEtwKwb+thdFoJAtYczy7bIZWdsQjZfADUc38pF4gVd0o+Q==", + "requires": { + "escape-goat": "^1.3.0", + "html-tags": "^2.0.0", + "stringify-attributes": "^1.0.0", + "type-fest": "^0.3.0" + }, + "dependencies": { + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=" + } + } + }, "credit-card-type": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/credit-card-type/-/credit-card-type-8.3.0.tgz", @@ -3730,6 +3748,11 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, + "escape-goat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-1.3.0.tgz", + "integrity": "sha512-E2nU1Y39N5UgfLU8qwMlK0vZrZprIwWLeVmDYN8wd/e37hMtGzu2w1DBiREts0XHfgyZEQlj/hYr0H0izF0HDQ==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -5721,6 +5744,14 @@ "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", "dev": true }, + "linkify-urls": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/linkify-urls/-/linkify-urls-3.1.1.tgz", + "integrity": "sha512-sRxMSunCnLFtZ4iVkMqHhZKSJ3MC/nRAvej8Ou3pEEEPBL0iVN91mZvdFREKcGv3VNcakbT4qsfOnnWMEbA59w==", + "requires": { + "create-html-element": "^2.1.0" + } + }, "listr": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", @@ -8882,6 +8913,14 @@ "safe-buffer": "~5.1.0" } }, + "stringify-attributes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stringify-attributes/-/stringify-attributes-1.0.0.tgz", + "integrity": "sha1-nosvmpRn57SAk8shJOvBwX5jgsU=", + "requires": { + "escape-goat": "^1.1.0" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -9283,6 +9322,11 @@ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", diff --git a/package.json b/package.json index ebe239820e64..f3c1e6a0189d 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "cross-env": "^7.0.3", "jsignature": "^2.1.3", "laravel-mix": "^5.0.9", + "linkify-urls": "^3.1.1", "lodash": "^4.17.20", "resolve-url-loader": "^3.1.2", "sass": "^1.32.7", diff --git a/public/js/clients/linkify-urls.js b/public/js/clients/linkify-urls.js new file mode 100644 index 000000000000..19fb4fffc657 --- /dev/null +++ b/public/js/clients/linkify-urls.js @@ -0,0 +1,2 @@ +/*! For license information please see linkify-urls.js.LICENSE.txt */ +!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/",r(r.s=16)}({16:function(e,t,r){e.exports=r("cN42")},Ievl:function(e,t,r){"use strict";t.escape=e=>e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">"),t.unescape=e=>e.replace(/>/g,">").replace(/</g,"<").replace(/'/g,"'").replace(/"/g,'"').replace(/&/g,"&"),t.escapeTag=function(e){let r=e[0];for(let n=1;n{if((e=Object.assign({name:"div",attributes:{},html:""},e)).html&&e.text)throw new Error("The `html` and `text` options are mutually exclusive");const t=e.text?a.escape(e.text):e.html;let r=`<${e.name}${n(e.attributes)}>`;return u.has(e.name)||(r+=`${t}`),r}},cN42:function(e,t,r){var n=r("jG5F");document.querySelectorAll("[data-ref=entity-terms]").forEach((function(e){e.innerHTML=n(e.innerText,{attributes:{target:"_blank",class:"text-primary"}})}))},dBjz:function(e,t,r){"use strict";const n=r("Ievl");e.exports=e=>{const t=[];for(const r of Object.keys(e)){let o=e[r];if(!1===o)continue;Array.isArray(o)&&(o=o.join(" "));let a=n.escape(r);!0!==o&&(a+=`="${n.escape(String(o))}"`),t.push(a)}return t.length>0?" "+t.join(" "):""}},jG5F:function(e,t,r){"use strict";const n=r("YIIW"),o=(e,t)=>n({name:"a",attributes:{href:"",...t.attributes,href:e},text:void 0===t.value?e:void 0,html:void 0===t.value?void 0:"function"==typeof t.value?t.value(e):t.value});e.exports=(e,t)=>{if("string"===(t={attributes:{},type:"string",...t}).type)return((e,t)=>e.replace(/((?o(e,t)))(e,t);if("dom"===t.type)return((e,t)=>{const r=document.createDocumentFragment();for(const[a,u]of Object.entries(e.split(/((?0&&r.append(u);var n;return r})(e,t);throw new Error("The type option must be either `dom` or `string`")}},sW1H:function(e){e.exports=JSON.parse('["area","base","br","col","embed","hr","img","input","link","menuitem","meta","param","source","track","wbr"]')}}); \ No newline at end of file diff --git a/public/js/clients/linkify-urls.js.LICENSE.txt b/public/js/clients/linkify-urls.js.LICENSE.txt new file mode 100644 index 000000000000..585c6ab0e4fc --- /dev/null +++ b/public/js/clients/linkify-urls.js.LICENSE.txt @@ -0,0 +1,9 @@ +/** + * Invoice Ninja (https://invoiceninja.com) + * + * @link https://github.com/invoiceninja/invoiceninja source repository + * + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) + * + * @license https://opensource.org/licenses/AAL + */ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index fa6f474e15b1..75d737b930db 100755 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -3,6 +3,7 @@ "/css/app.css": "/css/app.css?id=58736e43b16ddde82ba9", "/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=a09bb529b8e1826f13b4", "/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=8ce8955ba775ea5f47d1", + "/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=0dc8c34010d09195d2f7", "/js/clients/payment_methods/authorize-authorize-card.js": "/js/clients/payment_methods/authorize-authorize-card.js?id=206d7de4ac97612980ff", "/js/clients/payments/authorize-credit-card-payment.js": "/js/clients/payments/authorize-credit-card-payment.js?id=a376eff2227da398b0ba", "/js/clients/payments/card-js.min.js": "/js/clients/payments/card-js.min.js?id=5469146cd629ea1b5c20", diff --git a/resources/js/clients/linkify-urls.js b/resources/js/clients/linkify-urls.js new file mode 100644 index 000000000000..b6362e1f715b --- /dev/null +++ b/resources/js/clients/linkify-urls.js @@ -0,0 +1,19 @@ +/** + * Invoice Ninja (https://invoiceninja.com) + * + * @link https://github.com/invoiceninja/invoiceninja source repository + * + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) + * + * @license https://opensource.org/licenses/AAL + */ + +const linkifyUrls = require('linkify-urls'); + +document + .querySelectorAll('[data-ref=entity-terms]') + .forEach((text) => { + text.innerHTML = linkifyUrls(text.innerText, { + attributes: {target: '_blank', class: 'text-primary'} + }); + }); diff --git a/resources/views/portal/ninja2020/invoices/includes/terms.blade.php b/resources/views/portal/ninja2020/invoices/includes/terms.blade.php index 3c28674347a2..b8f83bd9d4d2 100644 --- a/resources/views/portal/ninja2020/invoices/includes/terms.blade.php +++ b/resources/views/portal/ninja2020/invoices/includes/terms.blade.php @@ -12,9 +12,9 @@
@foreach($entities as $entity)
-

{{ $entity_type }} {{ $entity->number }}:

+

{{ $entity_type }} {{ $entity->number }}:

@if($entity->terms) -

{!! $entity->terms !!}

+
{!! $entity->terms !!}
@else {{ ctrans('texts.not_specified') }} @endif @@ -39,3 +39,7 @@
+ +@push('footer') + +@endpush diff --git a/webpack.mix.js b/webpack.mix.js index c5953f800f3e..ef423fb2c701 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -61,6 +61,10 @@ mix.js("resources/js/app.js", "public/js") .js( "resources/js/clients/shared/multiple-downloads.js", "public/js/clients/shared/multiple-downloads.js" + ) + .js( + "resources/js/clients/linkify-urls.js", + "public/js/clients/linkify-urls.js" ); mix.copyDirectory('node_modules/card-js/card-js.min.css', 'public/css/card-js.min.css');