This commit is contained in:
parent
5ad77e8a3a
commit
bc3006f3c4
9 changed files with 92 additions and 17 deletions
19
src/common/text/elements/link.js
Normal file
19
src/common/text/elements/link.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Link
|
||||
*/
|
||||
|
||||
module.exports = text => {
|
||||
const match = text.match(/^\??\[(.+?)\]\((https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+)\)/);
|
||||
if (!match) return null;
|
||||
const silent = text[0] == '?';
|
||||
const link = match[0];
|
||||
const title = match[1];
|
||||
const url = match[2];
|
||||
return {
|
||||
type: 'link',
|
||||
content: link,
|
||||
title: title,
|
||||
url: url,
|
||||
silent: silent
|
||||
};
|
||||
};
|
|
@ -3,11 +3,12 @@
|
|||
*/
|
||||
|
||||
module.exports = text => {
|
||||
const match = text.match(/^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+/);
|
||||
const match = text.match(/^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+/);
|
||||
if (!match) return null;
|
||||
const link = match[0];
|
||||
const url = match[0];
|
||||
return {
|
||||
type: 'link',
|
||||
content: link
|
||||
type: 'url',
|
||||
content: url,
|
||||
url: url
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
const elements = [
|
||||
require('./elements/bold'),
|
||||
require('./elements/url'),
|
||||
require('./elements/link'),
|
||||
require('./elements/mention'),
|
||||
require('./elements/hashtag'),
|
||||
require('./elements/code'),
|
||||
|
|
|
@ -21,8 +21,10 @@ module.exports = (tokens, shouldBreak) => {
|
|||
.replace(/(\r\n|\n|\r)/g, shouldBreak ? '<br>' : ' ');
|
||||
case 'bold':
|
||||
return '<strong>' + escape(token.bold) + '</strong>';
|
||||
case 'link':
|
||||
case 'url':
|
||||
return '<mk-url href="' + escape(token.content) + '" target="_blank"></mk-url>';
|
||||
case 'link':
|
||||
return '<a class="link" href="' + escape(token.url) + '" target="_blank">' + escape(token.title) + '</a>';
|
||||
case 'mention':
|
||||
return '<a href="' + CONFIG.url + '/' + escape(token.username) + '" target="_blank" data-user-preview="' + token.content + '" ' + (me && me.username == token.username ? 'data-is-me' : '') + '>' + token.content + '</a>';
|
||||
case 'hashtag': // TODO
|
||||
|
|
|
@ -233,6 +233,16 @@
|
|||
font-size 1.5em
|
||||
color #717171
|
||||
|
||||
.link
|
||||
&:after
|
||||
content "\f14c"
|
||||
display inline-block
|
||||
padding-left 2px
|
||||
font-family FontAwesome
|
||||
font-size .9em
|
||||
font-weight 400
|
||||
font-style normal
|
||||
|
||||
> mk-url-preview
|
||||
margin-top 8px
|
||||
|
||||
|
@ -367,10 +377,10 @@
|
|||
|
||||
// URLをプレビュー
|
||||
tokens
|
||||
.filter(t => t.type == 'link')
|
||||
.filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
|
||||
.map(t => {
|
||||
riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
|
||||
url: t.content
|
||||
url: t.url
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -229,6 +229,16 @@
|
|||
mk-url-preview
|
||||
margin-top 8px
|
||||
|
||||
.link
|
||||
&:after
|
||||
content "\f14c"
|
||||
display inline-block
|
||||
padding-left 2px
|
||||
font-family FontAwesome
|
||||
font-size .9em
|
||||
font-weight 400
|
||||
font-style normal
|
||||
|
||||
> .reply
|
||||
margin-right 8px
|
||||
color #717171
|
||||
|
@ -344,10 +354,10 @@
|
|||
|
||||
// URLをプレビュー
|
||||
tokens
|
||||
.filter(t => t.type == 'link')
|
||||
.filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
|
||||
.map(t => {
|
||||
riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
|
||||
url: t.content
|
||||
url: t.url
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -230,6 +230,16 @@
|
|||
@media (min-width 500px)
|
||||
font-size 24px
|
||||
|
||||
.link
|
||||
&:after
|
||||
content "\f14c"
|
||||
display inline-block
|
||||
padding-left 2px
|
||||
font-family FontAwesome
|
||||
font-size .9em
|
||||
font-weight 400
|
||||
font-style normal
|
||||
|
||||
> mk-url-preview
|
||||
margin-top 8px
|
||||
|
||||
|
@ -368,10 +378,10 @@
|
|||
|
||||
// URLをプレビュー
|
||||
tokens
|
||||
.filter(t => t.type == 'link')
|
||||
.filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
|
||||
.map(t => {
|
||||
riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
|
||||
url: t.content
|
||||
url: t.url
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -209,6 +209,16 @@
|
|||
> .dummy
|
||||
display none
|
||||
|
||||
.link
|
||||
&:after
|
||||
content "\f14c"
|
||||
display inline-block
|
||||
padding-left 2px
|
||||
font-family FontAwesome
|
||||
font-size .9em
|
||||
font-weight 400
|
||||
font-style normal
|
||||
|
||||
mk-url-preview
|
||||
margin-top 8px
|
||||
|
||||
|
@ -318,10 +328,10 @@
|
|||
|
||||
// URLをプレビュー
|
||||
tokens
|
||||
.filter(t => t.type == 'link')
|
||||
.filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
|
||||
.map(t => {
|
||||
riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
|
||||
url: t.content
|
||||
url: t.url
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
20
test/text.js
20
test/text.js
|
@ -49,11 +49,23 @@ describe('Text', () => {
|
|||
], tokens);
|
||||
});
|
||||
|
||||
it('link', () => {
|
||||
it('url', () => {
|
||||
const tokens = analyze('https://himasaku.net');
|
||||
assert.deepEqual([
|
||||
{ type: 'link', content: 'https://himasaku.net' }
|
||||
], tokens);
|
||||
assert.deepEqual([{
|
||||
type: 'url',
|
||||
content: 'https://himasaku.net',
|
||||
url: 'https://himasaku.net'
|
||||
}], tokens);
|
||||
});
|
||||
|
||||
it('link', () => {
|
||||
const tokens = analyze('[ひまさく](https://himasaku.net)');
|
||||
assert.deepEqual([{
|
||||
type: 'link',
|
||||
content: '[ひまさく](https://himasaku.net)',
|
||||
title: 'ひまさく',
|
||||
url: 'https://himasaku.net'
|
||||
}], tokens);
|
||||
});
|
||||
|
||||
it('emoji', () => {
|
||||
|
|
Loading…
Reference in a new issue