mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Meld a chaotic commit history into one commit
Some important commit messages:
```
Fix youtu.be not being embedded
And also try to maintain the old behaviour matching
`provider.provider_url`.
```
```
Remove confusing code comments and obsolete code
I discovered that the behaviour of no duplicate notifications being send
out is caused by the frontend: When the editor reads html from the
backend, it will parse hashtags and mentions as ordinary links, not as
their respective nodes during editing. Also, we don't have to worry
about duplicate ids being found: The cypher statement will implicitly
suppress duplicate notification nodes for the same user.
So let's remove the code to avoid confusing the next developer.
```
```
Test editor.getHTML()
I do this because I'm not able to test the content of `this.editor` from
a wrapper of `vue-test-utils`. If I call `this.editor.getHTML` directly
and use it as a computed property `renderedContent` to populate a `<div
v-html="renderedContent" />` this will not work for the embeds. So, my
current best bet is to test the editor object isolated from a real
component. ;(
```
```
Add core-js as explicit dependency
Because of build errors on Travis.
See: https://stackoverflow.com/a/55313456
Remove as soon as this issue is resolved:
https://github.com/storybookjs/storybook/issues/7591
```
```
Refactor: Keep Runtime-only builds
See: https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
```
This commit is contained in:
parent
34f86c95a0
commit
72edf78889
@ -86,6 +86,7 @@
|
||||
"metascraper-url": "^5.5.0",
|
||||
"metascraper-video": "^5.6.3",
|
||||
"metascraper-youtube": "^4.8.5",
|
||||
"minimatch": "^3.0.4",
|
||||
"neo4j-driver": "~1.7.4",
|
||||
"neo4j-graphql-js": "^2.6.3",
|
||||
"neode": "^0.2.16",
|
||||
|
||||
@ -64,7 +64,7 @@ describe('currentUser { notifications }', () => {
|
||||
let post
|
||||
const title = 'Mentioning Al Capone'
|
||||
const content =
|
||||
'Hey <a class="mention" href="/profile/you/al-capone">@al-capone</a> how do you do?'
|
||||
'Hey <a class="mention" data-mention-id="you" href="/profile/you/al-capone">@al-capone</a> how do you do?'
|
||||
|
||||
beforeEach(async () => {
|
||||
const createPostMutation = gql`
|
||||
@ -88,7 +88,7 @@ describe('currentUser { notifications }', () => {
|
||||
|
||||
it('sends you a notification', async () => {
|
||||
const expectedContent =
|
||||
'Hey <a href="/profile/you/al-capone" target="_blank">@al-capone</a> how do you do?'
|
||||
'Hey <a class="mention" data-mention-id="you" href="/profile/you/al-capone" target="_blank">@al-capone</a> how do you do?'
|
||||
const expected = {
|
||||
currentUser: {
|
||||
notifications: [
|
||||
@ -108,14 +108,22 @@ describe('currentUser { notifications }', () => {
|
||||
).resolves.toEqual(expected)
|
||||
})
|
||||
|
||||
describe('who mentions me again', () => {
|
||||
describe('who mentions me many times', () => {
|
||||
beforeEach(async () => {
|
||||
const updatedContent = `${post.content} One more mention to <a href="/profile/you" class="mention">@al-capone</a>`
|
||||
// The response `post.content` contains a link but the XSSmiddleware
|
||||
// should have the `mention` CSS class removed. I discovered this
|
||||
// during development and thought: A feature not a bug! This way we
|
||||
// can encode a re-mentioning of users when you edit your post or
|
||||
// comment.
|
||||
const updatedContent = `
|
||||
One more mention to
|
||||
<a data-mention-id="you" class="mention" href="/profile/you">
|
||||
@al-capone
|
||||
</a>
|
||||
and again:
|
||||
<a data-mention-id="you" class="mention" href="/profile/you">
|
||||
@al-capone
|
||||
</a>
|
||||
and again
|
||||
<a data-mention-id="you" class="mention" href="/profile/you">
|
||||
@al-capone
|
||||
</a>
|
||||
`
|
||||
const updatePostMutation = gql`
|
||||
mutation($id: ID!, $title: String!, $content: String!) {
|
||||
UpdatePost(id: $id, content: $content, title: $title) {
|
||||
@ -136,7 +144,7 @@ describe('currentUser { notifications }', () => {
|
||||
|
||||
it('creates exactly one more notification', async () => {
|
||||
const expectedContent =
|
||||
'Hey <a href="/profile/you/al-capone" target="_blank">@al-capone</a> how do you do? One more mention to <a href="/profile/you" target="_blank">@al-capone</a>'
|
||||
'<br>One more mention to<br><a data-mention-id="you" class="mention" href="/profile/you" target="_blank"><br>@al-capone<br></a><br>and again:<br><a data-mention-id="you" class="mention" href="/profile/you" target="_blank"><br>@al-capone<br></a><br>and again<br><a data-mention-id="you" class="mention" href="/profile/you" target="_blank"><br>@al-capone<br></a><br>'
|
||||
const expected = {
|
||||
currentUser: {
|
||||
notifications: [
|
||||
|
||||
@ -1,20 +1,13 @@
|
||||
import cheerio from 'cheerio'
|
||||
const ID_REGEX = /\/profile\/([\w\-.!~*'"(),]+)/g
|
||||
|
||||
export default function(content) {
|
||||
if (!content) return []
|
||||
const $ = cheerio.load(content)
|
||||
const urls = $('.mention')
|
||||
let userIds = $('a.mention[data-mention-id]')
|
||||
.map((_, el) => {
|
||||
return $(el).attr('href')
|
||||
return $(el).attr('data-mention-id')
|
||||
})
|
||||
.get()
|
||||
const ids = []
|
||||
urls.forEach(url => {
|
||||
let match
|
||||
while ((match = ID_REGEX.exec(url)) != null) {
|
||||
ids.push(match[1])
|
||||
}
|
||||
})
|
||||
return ids
|
||||
userIds = userIds.map(id => id.trim()).filter(id => !!id)
|
||||
return userIds
|
||||
}
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
import extractMentionedUsers from './extractMentionedUsers'
|
||||
|
||||
const contentWithMentions =
|
||||
'<p>Something inspirational about <a href="/profile/u2" class="not-a-mention" data-mention-id="bobs-id" target="_blank">@bob-der-baumeister</a> and <a href="/profile/u3/jenny-rostock" class="mention" data-mention-id="u3" target="_blank">@jenny-rostock</a>.</p>'
|
||||
const contentEmptyMentions =
|
||||
'<p>Something inspirational about <a href="/profile/u2" data-mention-id="" target="_blank">@bob-der-baumeister</a> and <a href="/profile/u3/jenny-rostock" class="mention" data-mention-id target="_blank">@jenny-rostock</a>.</p>'
|
||||
const contentWithLinks =
|
||||
'<p>Something inspirational about <a class="mention" href="/profile/u2" target="_blank">@bob-der-baumeister</a> and <a href="/profile/u3" target="_blank">@jenny-rostock</a>.</p>'
|
||||
|
||||
describe('extractMentionedUsers', () => {
|
||||
describe('content undefined', () => {
|
||||
it('returns empty array', () => {
|
||||
@ -7,53 +14,17 @@ describe('extractMentionedUsers', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('searches through links', () => {
|
||||
it('ignores links without .mention class', () => {
|
||||
const content =
|
||||
'<p>Something inspirational about <a href="/profile/u2" target="_blank">@bob-der-baumeister</a> and <a href="/profile/u3" target="_blank">@jenny-rostock</a>.</p>'
|
||||
expect(extractMentionedUsers(content)).toEqual([])
|
||||
it('ignores links without .mention class', () => {
|
||||
expect(extractMentionedUsers(contentWithLinks)).toEqual([])
|
||||
})
|
||||
|
||||
describe('given a link with .mention class and `data-mention-id` attribute ', () => {
|
||||
it('extracts ids', () => {
|
||||
expect(extractMentionedUsers(contentWithMentions)).toEqual(['u3'])
|
||||
})
|
||||
|
||||
describe('given a link with .mention class', () => {
|
||||
it('extracts ids', () => {
|
||||
const content =
|
||||
'<p>Something inspirational about <a href="/profile/u2" class="mention" target="_blank">@bob-der-baumeister</a> and <a href="/profile/u3/jenny-rostock" class="mention" target="_blank">@jenny-rostock</a>.</p>'
|
||||
expect(extractMentionedUsers(content)).toEqual(['u2', 'u3'])
|
||||
})
|
||||
|
||||
describe('handles links', () => {
|
||||
it('with slug and id', () => {
|
||||
const content =
|
||||
'<p>Something inspirational about <a href="/profile/u2/bob-der-baumeister" class="mention" target="_blank">@bob-der-baumeister</a> and <a href="/profile/u3/jenny-rostock/" class="mention" target="_blank">@jenny-rostock</a>.</p>'
|
||||
expect(extractMentionedUsers(content)).toEqual(['u2', 'u3'])
|
||||
})
|
||||
|
||||
it('with domains', () => {
|
||||
const content =
|
||||
'<p>Something inspirational about <a href="http://localhost:3000/profile/u2/bob-der-baumeister" class="mention" target="_blank">@bob-der-baumeister</a> and <a href="http://localhost:3000//profile/u3/jenny-rostock/" class="mention" target="_blank">@jenny-rostock</a>.</p>'
|
||||
expect(extractMentionedUsers(content)).toEqual(['u2', 'u3'])
|
||||
})
|
||||
|
||||
it('special characters', () => {
|
||||
const content =
|
||||
'<p>Something inspirational about <a href="http://localhost:3000/profile/u!*(),2/bob-der-baumeister" class="mention" target="_blank">@bob-der-baumeister</a> and <a href="http://localhost:3000//profile/u.~-3/jenny-rostock/" class="mention" target="_blank">@jenny-rostock</a>.</p>'
|
||||
expect(extractMentionedUsers(content)).toEqual(['u!*(),2', 'u.~-3'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('does not crash if', () => {
|
||||
it('`href` contains no user id', () => {
|
||||
const content =
|
||||
'<p>Something inspirational about <a href="/profile" class="mention" target="_blank">@bob-der-baumeister</a> and <a href="/profile/" class="mention" target="_blank">@jenny-rostock</a>.</p>'
|
||||
expect(extractMentionedUsers(content)).toEqual([])
|
||||
})
|
||||
|
||||
it('`href` is empty or invalid', () => {
|
||||
const content =
|
||||
'<p>Something inspirational about <a href="" class="mention" target="_blank">@bob-der-baumeister</a> and <a href="not-a-url" class="mention" target="_blank">@jenny-rostock</a>.</p>'
|
||||
expect(extractMentionedUsers(content)).toEqual([])
|
||||
})
|
||||
})
|
||||
it('ignores empty `data-mention-id` attributes', () => {
|
||||
expect(extractMentionedUsers(contentEmptyMentions)).toEqual([])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -2,30 +2,17 @@ import walkRecursive from '../helpers/walkRecursive'
|
||||
// import { getByDot, setByDot, getItems, replaceItems } from 'feathers-hooks-common'
|
||||
import sanitizeHtml from 'sanitize-html'
|
||||
// import { isEmpty, intersection } from 'lodash'
|
||||
import cheerio from 'cheerio'
|
||||
import linkifyHtml from 'linkifyjs/html'
|
||||
|
||||
const embedToAnchor = content => {
|
||||
const $ = cheerio.load(content)
|
||||
$('div[data-url-embed]').each((i, el) => {
|
||||
let url = el.attribs['data-url-embed']
|
||||
let aTag = $(`<a href="${url}" target="_blank" data-url-embed="">${url}</a>`)
|
||||
$(el).replaceWith(aTag)
|
||||
})
|
||||
return $('body').html()
|
||||
}
|
||||
|
||||
function clean(dirty) {
|
||||
if (!dirty) {
|
||||
return dirty
|
||||
}
|
||||
|
||||
// Convert embeds to a-tags
|
||||
dirty = embedToAnchor(dirty)
|
||||
dirty = linkifyHtml(dirty)
|
||||
dirty = sanitizeHtml(dirty, {
|
||||
allowedTags: [
|
||||
'iframe',
|
||||
'img',
|
||||
'p',
|
||||
'h3',
|
||||
@ -50,35 +37,24 @@ function clean(dirty) {
|
||||
a: ['href', 'class', 'target', 'data-*', 'contenteditable'],
|
||||
span: ['contenteditable', 'class', 'data-*'],
|
||||
img: ['src'],
|
||||
iframe: ['src', 'class', 'frameborder', 'allowfullscreen'],
|
||||
},
|
||||
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com'],
|
||||
parser: {
|
||||
lowerCaseTags: true,
|
||||
},
|
||||
transformTags: {
|
||||
iframe: function(tagName, attribs) {
|
||||
return {
|
||||
tagName: 'a',
|
||||
text: attribs.src,
|
||||
attribs: {
|
||||
href: attribs.src,
|
||||
target: '_blank',
|
||||
'data-url-embed': '',
|
||||
},
|
||||
}
|
||||
},
|
||||
h1: 'h3',
|
||||
h2: 'h3',
|
||||
h3: 'h3',
|
||||
h4: 'h4',
|
||||
h5: 'strong',
|
||||
i: 'em',
|
||||
a: function(tagName, attribs) {
|
||||
a: (tagName, attribs) => {
|
||||
return {
|
||||
tagName: 'a',
|
||||
attribs: {
|
||||
href: attribs.href,
|
||||
...attribs,
|
||||
href: attribs.href || '',
|
||||
target: '_blank',
|
||||
rel: 'noopener noreferrer nofollow',
|
||||
},
|
||||
@ -86,33 +62,6 @@ function clean(dirty) {
|
||||
},
|
||||
b: 'strong',
|
||||
s: 'strike',
|
||||
img: function(tagName, attribs) {
|
||||
let src = attribs.src
|
||||
|
||||
if (!src) {
|
||||
// remove broken images
|
||||
return {}
|
||||
}
|
||||
|
||||
// if (isEmpty(hook.result)) {
|
||||
// const config = hook.app.get('thumbor')
|
||||
// if (config && src.indexOf(config < 0)) {
|
||||
// // download image
|
||||
// // const ThumborUrlHelper = require('../helper/thumbor-helper')
|
||||
// // const Thumbor = new ThumborUrlHelper(config.key || null, config.url || null)
|
||||
// // src = Thumbor
|
||||
// // .setImagePath(src)
|
||||
// // .buildUrl('740x0')
|
||||
// }
|
||||
// }
|
||||
return {
|
||||
tagName: 'img',
|
||||
attribs: {
|
||||
// TODO: use environment variables
|
||||
src: `http://localhost:3050/images?url=${src}`,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@ -120,8 +69,6 @@ function clean(dirty) {
|
||||
dirty = dirty
|
||||
// remove all tags with "space only"
|
||||
.replace(/<[a-z-]+>[\s]+<\/[a-z-]+>/gim, '')
|
||||
// remove all iframes
|
||||
.replace(/(<iframe(?!.*?src=(['"]).*?\2)[^>]*)(>)[^>]*\/*>/gim, '')
|
||||
.replace(/[\n]{3,}/gim, '\n\n')
|
||||
.replace(/(\r\n|\n\r|\r|\n)/g, '<br>$1')
|
||||
|
||||
@ -144,8 +91,7 @@ const fields = ['content', 'contentExcerpt']
|
||||
export default {
|
||||
Mutation: async (resolve, root, args, context, info) => {
|
||||
args = walkRecursive(args, fields, clean)
|
||||
const result = await resolve(root, args, context, info)
|
||||
return result
|
||||
return resolve(root, args, context, info)
|
||||
},
|
||||
Query: async (resolve, root, args, context, info) => {
|
||||
const result = await resolve(root, args, context, info)
|
||||
|
||||
26
backend/src/schema/resolvers/embeds/findProvider.js
Normal file
26
backend/src/schema/resolvers/embeds/findProvider.js
Normal file
@ -0,0 +1,26 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import minimatch from 'minimatch'
|
||||
|
||||
let oEmbedProvidersFile = fs.readFileSync(path.join(__dirname, './providers.json'), 'utf8')
|
||||
// some providers allow a format parameter
|
||||
// we need JSON
|
||||
oEmbedProvidersFile = oEmbedProvidersFile.replace(/\{format\}/g, 'json')
|
||||
const oEmbedProviders = JSON.parse(oEmbedProvidersFile)
|
||||
|
||||
export default function(embedUrl) {
|
||||
for (let provider of oEmbedProviders) {
|
||||
for (let endpoint of provider.endpoints) {
|
||||
const { schemes = [], url } = endpoint
|
||||
if (schemes.some(scheme => minimatch(embedUrl, scheme))) return url
|
||||
}
|
||||
const { hostname } = new URL(embedUrl)
|
||||
if (provider.provider_url.includes(hostname)) {
|
||||
const {
|
||||
endpoints: [{ url }],
|
||||
} = provider
|
||||
return url
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
35
backend/src/schema/resolvers/embeds/findProvider.spec.js
Normal file
35
backend/src/schema/resolvers/embeds/findProvider.spec.js
Normal file
@ -0,0 +1,35 @@
|
||||
import findProvider from './findProvider'
|
||||
|
||||
describe('Vimeo', () => {
|
||||
it('matches `https://vimeo.com/showcase/2098620/video/4082288`', () => {
|
||||
expect(findProvider('https://vimeo.com/showcase/2098620/video/4082288')).toEqual(
|
||||
'https://vimeo.com/api/oembed.json',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('RiffReporter', () => {
|
||||
it('matches `https://www.riffreporter.de/flugbegleiter-koralle/`', () => {
|
||||
expect(findProvider('https://www.riffreporter.de/flugbegleiter-koralle/')).toEqual(
|
||||
'https://www.riffreporter.de/service/oembed',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Youtube', () => {
|
||||
it('matches `https://www.youtube.com/watch?v=qkdXAtO40Fo`', () => {
|
||||
expect(findProvider('https://www.youtube.com/watch?v=qkdXAtO40Fo')).toEqual(
|
||||
'https://www.youtube.com/oembed',
|
||||
)
|
||||
})
|
||||
|
||||
it('matches `https://youtu.be/qkdXAtO40Fo`', () => {
|
||||
expect(findProvider(`https://youtu.be/qkdXAtO40Fo`)).toEqual('https://www.youtube.com/oembed')
|
||||
})
|
||||
|
||||
it('matches `https://youtu.be/qkdXAtO40Fo?t=41`', () => {
|
||||
expect(findProvider(`https://youtu.be/qkdXAtO40Fo?t=41`)).toEqual(
|
||||
'https://www.youtube.com/oembed',
|
||||
)
|
||||
})
|
||||
})
|
||||
@ -1,12 +1,11 @@
|
||||
import Metascraper from 'metascraper'
|
||||
import fetch from 'node-fetch'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { ApolloError } from 'apollo-server'
|
||||
import isEmpty from 'lodash/isEmpty'
|
||||
import isArray from 'lodash/isArray'
|
||||
import mergeWith from 'lodash/mergeWith'
|
||||
import findProvider from './findProvider'
|
||||
|
||||
const error = require('debug')('embed:error')
|
||||
|
||||
@ -30,24 +29,11 @@ const metascraper = Metascraper([
|
||||
// require('./rules/metascraper-embed')()
|
||||
])
|
||||
|
||||
let oEmbedProvidersFile = fs.readFileSync(path.join(__dirname, './providers.json'), 'utf8')
|
||||
|
||||
// some providers allow a format parameter
|
||||
// we need JSON
|
||||
oEmbedProvidersFile = oEmbedProvidersFile.replace('{format}', 'json')
|
||||
|
||||
const oEmbedProviders = JSON.parse(oEmbedProvidersFile)
|
||||
|
||||
const fetchEmbed = async url => {
|
||||
const provider = oEmbedProviders.find(provider => {
|
||||
return provider.provider_url.includes(url.hostname)
|
||||
})
|
||||
if (!provider) return {}
|
||||
const {
|
||||
endpoints: [endpoint],
|
||||
} = provider
|
||||
const endpointUrl = new URL(endpoint.url)
|
||||
endpointUrl.searchParams.append('url', url.href)
|
||||
let endpointUrl = findProvider(url)
|
||||
if (!endpointUrl) return {}
|
||||
endpointUrl = new URL(endpointUrl)
|
||||
endpointUrl.searchParams.append('url', url)
|
||||
endpointUrl.searchParams.append('format', 'json')
|
||||
let json
|
||||
try {
|
||||
@ -70,7 +56,7 @@ const fetchEmbed = async url => {
|
||||
const fetchResource = async url => {
|
||||
const response = await fetch(url)
|
||||
const html = await response.text()
|
||||
const resource = await metascraper({ html, url: url.href })
|
||||
const resource = await metascraper({ html, url })
|
||||
return {
|
||||
sources: ['resource'],
|
||||
...resource,
|
||||
@ -78,12 +64,6 @@ const fetchResource = async url => {
|
||||
}
|
||||
|
||||
export default async function scrape(url) {
|
||||
url = new URL(url)
|
||||
if (url.hostname === 'youtu.be') {
|
||||
// replace youtu.be to get proper results
|
||||
url.hostname = 'youtube.com'
|
||||
}
|
||||
|
||||
const [meta, embed] = await Promise.all([fetchResource(url), fetchEmbed(url)])
|
||||
const output = mergeWith(meta, embed, (objValue, srcValue) => {
|
||||
if (isArray(objValue)) {
|
||||
|
||||
@ -7,4 +7,4 @@ type Tag {
|
||||
taggedCountUnique: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p)<-[:WROTE]-(u:User) RETURN COUNT(DISTINCT u)")
|
||||
deleted: Boolean
|
||||
disabled: Boolean
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ When("I choose {string} as the title of the post", title => {
|
||||
|
||||
When("I type in the following text:", text => {
|
||||
lastPost.content = text.replace("\n", " ");
|
||||
cy.get(".ProseMirror").type(lastPost.content);
|
||||
cy.get(".editor .ProseMirror").type(lastPost.content);
|
||||
});
|
||||
|
||||
Then("the post shows up on the landing page at position {int}", index => {
|
||||
|
||||
@ -45,7 +45,11 @@
|
||||
{{ $t('comment.show.more') }}
|
||||
</a>
|
||||
</div>
|
||||
<div v-if="!isCollapsed" v-html="comment.content" style="padding-left: 40px;" />
|
||||
<content-viewer
|
||||
v-if="!isCollapsed"
|
||||
:content="comment.content"
|
||||
style="padding-left: 40px;"
|
||||
/>
|
||||
<div style="text-align: right; margin-right: 20px; margin-top: -12px;">
|
||||
<a v-if="!isCollapsed" @click="isCollapsed = !isCollapsed" style="padding-left: 40px; ">
|
||||
{{ $t('comment.show.less') }}
|
||||
@ -62,6 +66,7 @@ import gql from 'graphql-tag'
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import HcUser from '~/components/User'
|
||||
import ContentMenu from '~/components/ContentMenu'
|
||||
import ContentViewer from '~/components/Editor/ContentViewer'
|
||||
import HcEditCommentForm from '~/components/comments/EditCommentForm/EditCommentForm'
|
||||
|
||||
export default {
|
||||
@ -74,6 +79,7 @@ export default {
|
||||
components: {
|
||||
HcUser,
|
||||
ContentMenu,
|
||||
ContentViewer,
|
||||
HcEditCommentForm,
|
||||
},
|
||||
props: {
|
||||
|
||||
32
webapp/components/Editor/ContentViewer.vue
Normal file
32
webapp/components/Editor/ContentViewer.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<editor-content :editor="editor" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import defaultExtensions from './defaultExtensions.js'
|
||||
import { Editor, EditorContent } from 'tiptap'
|
||||
|
||||
export default {
|
||||
name: 'ContentViewer',
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
props: {
|
||||
content: { type: String, default: '' },
|
||||
doc: { type: Object, default: () => {} },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: new Editor({
|
||||
doc: this.doc,
|
||||
content: this.content,
|
||||
editable: false,
|
||||
extensions: defaultExtensions(this),
|
||||
}),
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -1,9 +1,27 @@
|
||||
import { storiesOf } from '@storybook/vue'
|
||||
import { withA11y } from '@storybook/addon-a11y'
|
||||
import HcEditor from '~/components/Editor/Editor.vue'
|
||||
import helpers from './helpers'
|
||||
import helpers from '~/storybook/helpers'
|
||||
import Vue from 'vue'
|
||||
|
||||
helpers.init()
|
||||
const embed = {
|
||||
html:
|
||||
'<iframe width="480" height="270" src="https://www.youtube.com/embed/qkdXAtO40Fo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
|
||||
}
|
||||
|
||||
const plugins = [
|
||||
(app = {}) => {
|
||||
app.$apollo = {
|
||||
mutate: () => {},
|
||||
query: () => {
|
||||
return { data: { embed } }
|
||||
},
|
||||
}
|
||||
Vue.prototype.$apollo = app.$apollo
|
||||
return app
|
||||
},
|
||||
]
|
||||
helpers.init({ plugins })
|
||||
|
||||
const users = [{ id: 1, slug: 'peter' }, { id: 1, slug: 'sandra' }, { id: 1, slug: 'jane' }]
|
||||
|
||||
@ -47,7 +65,7 @@ storiesOf('Editor', module)
|
||||
<p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
|
||||
<h5>Heading 5</h5>
|
||||
<p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
|
||||
|
||||
|
||||
<h3>Unordered List</h3>
|
||||
<ul>
|
||||
<li><p>Also some list</p></li>
|
||||
@ -55,7 +73,7 @@ storiesOf('Editor', module)
|
||||
<li><p>several</p></li>
|
||||
<li><p>points</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Ordered List</h3>
|
||||
<ol>
|
||||
<li><p>justo</p></li>
|
||||
@ -74,7 +92,7 @@ storiesOf('Editor', module)
|
||||
users,
|
||||
content: `
|
||||
<p>
|
||||
Here you can mention people like
|
||||
Here you can mention people like
|
||||
<a class="mention" href="/profile/1" target="_blank" contenteditable="false">@sandra</a> and others.
|
||||
Try it out!
|
||||
</p>
|
||||
@ -102,9 +120,12 @@ storiesOf('Editor', module)
|
||||
data: () => ({
|
||||
users,
|
||||
content: `
|
||||
<p>The following link should be rendered with metainformation for its destination such as: Title, Description, Image, Pagename and Favicon.</p>
|
||||
<a class="embed" href="https://human-connection.org">Human Connection</a>
|
||||
<p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
|
||||
<p>
|
||||
The following link should render a youtube video in addition to the link.
|
||||
</p>
|
||||
<a class="embed" href="https://www.youtube.com/watch?v=qkdXAtO40Fo">
|
||||
<em>https://www.youtube.com/watch?v=qkdXAtO40Fo</em>
|
||||
</a>
|
||||
`,
|
||||
}),
|
||||
template: `<hc-editor :users="users" :value="content" />`,
|
||||
@ -183,32 +183,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import defaultExtensions from './defaultExtensions.js'
|
||||
import linkify from 'linkify-it'
|
||||
import stringHash from 'string-hash'
|
||||
import Fuse from 'fuse.js'
|
||||
import tippy from 'tippy.js'
|
||||
import { Editor, EditorContent, EditorFloatingMenu, EditorMenuBubble } from 'tiptap'
|
||||
import EventHandler from './plugins/eventHandler.js'
|
||||
import {
|
||||
Heading,
|
||||
HardBreak,
|
||||
Blockquote,
|
||||
ListItem,
|
||||
BulletList,
|
||||
OrderedList,
|
||||
HorizontalRule,
|
||||
Placeholder,
|
||||
Bold,
|
||||
Italic,
|
||||
Strike,
|
||||
Underline,
|
||||
// Link,
|
||||
History,
|
||||
} from 'tiptap-extensions'
|
||||
import Mention from './nodes/Mention.js'
|
||||
import Embed from './nodes/Embed.js'
|
||||
import Link from './nodes/Link.js'
|
||||
import { History } from 'tiptap-extensions'
|
||||
import Hashtag from './nodes/Hashtag.js'
|
||||
import Mention from './nodes/Mention.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
let throttleInputEvent
|
||||
@ -232,25 +216,8 @@ export default {
|
||||
content: this.value || '',
|
||||
doc: this.doc,
|
||||
extensions: [
|
||||
...defaultExtensions(this),
|
||||
new EventHandler(),
|
||||
new Heading(),
|
||||
new HardBreak(),
|
||||
new Blockquote(),
|
||||
new BulletList(),
|
||||
new OrderedList(),
|
||||
new HorizontalRule(),
|
||||
new Bold(),
|
||||
new Italic(),
|
||||
new Strike(),
|
||||
new Underline(),
|
||||
new Embed(),
|
||||
new Link(),
|
||||
new Heading({ levels: [3, 4] }),
|
||||
new ListItem(),
|
||||
new Placeholder({
|
||||
emptyNodeClass: 'is-empty',
|
||||
emptyNodeText: this.placeholder || this.$t('editor.placeholder'),
|
||||
}),
|
||||
new History(),
|
||||
new Mention({
|
||||
// a list of all suggested items
|
||||
@ -496,13 +463,11 @@ export default {
|
||||
selectItem(item) {
|
||||
const typeAttrs = {
|
||||
mention: {
|
||||
// TODO: use router here
|
||||
url: `/profile/${item.id}`,
|
||||
id: item.id,
|
||||
label: item.slug,
|
||||
},
|
||||
hashtag: {
|
||||
// TODO: Fill up with input hashtag in search field
|
||||
url: `/search/hashtag/${item.name}`,
|
||||
id: item.name,
|
||||
label: item.name,
|
||||
},
|
||||
}
|
||||
|
||||
49
webapp/components/Editor/commands/pasteRule.js
Normal file
49
webapp/components/Editor/commands/pasteRule.js
Normal file
@ -0,0 +1,49 @@
|
||||
import { Plugin } from 'prosemirror-state'
|
||||
import { Slice, Fragment } from 'prosemirror-model'
|
||||
|
||||
export default function(regexp, type, getAttrs) {
|
||||
const handler = fragment => {
|
||||
const nodes = []
|
||||
|
||||
fragment.forEach(child => {
|
||||
if (child.isText) {
|
||||
const { text } = child
|
||||
let pos = 0
|
||||
let match
|
||||
|
||||
do {
|
||||
match = regexp.exec(text)
|
||||
if (match) {
|
||||
const start = match.index
|
||||
const end = start + match[0].length
|
||||
const attrs = getAttrs instanceof Function ? getAttrs(match[0]) : getAttrs
|
||||
|
||||
if (start > 0) {
|
||||
nodes.push(child.cut(pos, start))
|
||||
}
|
||||
|
||||
// only difference to `pasteRule` of `tiptap-commands`:
|
||||
// we replace the node instead of adding markup
|
||||
nodes.push(type.create(attrs, child.cut(start, end)))
|
||||
|
||||
pos = end
|
||||
}
|
||||
} while (match)
|
||||
|
||||
if (pos < text.length) {
|
||||
nodes.push(child.cut(pos))
|
||||
}
|
||||
} else {
|
||||
nodes.push(child.copy(handler(child.content)))
|
||||
}
|
||||
})
|
||||
|
||||
return Fragment.fromArray(nodes)
|
||||
}
|
||||
|
||||
return new Plugin({
|
||||
props: {
|
||||
transformPasted: slice => new Slice(handler(slice.content), slice.openStart, slice.openEnd),
|
||||
},
|
||||
})
|
||||
}
|
||||
48
webapp/components/Editor/defaultExtensions.js
Normal file
48
webapp/components/Editor/defaultExtensions.js
Normal file
@ -0,0 +1,48 @@
|
||||
import Embed from '~/components/Editor/nodes/Embed.js'
|
||||
import Link from '~/components/Editor/nodes/Link.js'
|
||||
import EmbedQuery from '~/graphql/EmbedQuery.js'
|
||||
import {
|
||||
Heading,
|
||||
HardBreak,
|
||||
Blockquote,
|
||||
ListItem,
|
||||
BulletList,
|
||||
OrderedList,
|
||||
HorizontalRule,
|
||||
Placeholder,
|
||||
Bold,
|
||||
Italic,
|
||||
Strike,
|
||||
Underline,
|
||||
} from 'tiptap-extensions'
|
||||
|
||||
export default function defaultExtensions(component) {
|
||||
const { placeholder, $t, $apollo } = component
|
||||
return [
|
||||
new Heading(),
|
||||
new HardBreak(),
|
||||
new Blockquote(),
|
||||
new BulletList(),
|
||||
new OrderedList(),
|
||||
new HorizontalRule(),
|
||||
new Bold(),
|
||||
new Italic(),
|
||||
new Strike(),
|
||||
new Underline(),
|
||||
new Link(),
|
||||
new Heading({ levels: [3, 4] }),
|
||||
new ListItem(),
|
||||
new Placeholder({
|
||||
emptyNodeClass: 'is-empty',
|
||||
emptyNodeText: placeholder || $t('editor.placeholder'),
|
||||
}),
|
||||
new Embed({
|
||||
onEmbed: async ({ url }) => {
|
||||
const {
|
||||
data: { embed },
|
||||
} = await $apollo.query({ query: EmbedQuery(), variables: { url } })
|
||||
return embed
|
||||
},
|
||||
}),
|
||||
]
|
||||
}
|
||||
88
webapp/components/Editor/defaultExtensions.spec.js
Normal file
88
webapp/components/Editor/defaultExtensions.spec.js
Normal file
@ -0,0 +1,88 @@
|
||||
import defaultExtensions from './defaultExtensions.js'
|
||||
import { Editor } from 'tiptap'
|
||||
|
||||
let content
|
||||
let createEditor
|
||||
|
||||
describe('defaultExtensions', () => {
|
||||
describe('editor', () => {
|
||||
createEditor = () => {
|
||||
const componentStub = {
|
||||
placeholder: 'placeholder',
|
||||
$t: jest.fn(),
|
||||
$apollo: {
|
||||
mutate: jest.fn(),
|
||||
},
|
||||
}
|
||||
return new Editor({
|
||||
content,
|
||||
extensions: [...defaultExtensions(componentStub)],
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('renders', () => {
|
||||
content = ''
|
||||
expect(createEditor().getHTML()).toEqual('<p></p>')
|
||||
})
|
||||
|
||||
describe('`content` contains a mentioning', () => {
|
||||
beforeEach(() => {
|
||||
content =
|
||||
'<p>This is a post content mentioning <a class="mention" href="/profile/f0628376-e692-4167-bdb4-d521de5a014f" target="_blank">@alicia-luettgen</a>.</p>'
|
||||
})
|
||||
|
||||
it('renders mentioning as link', () => {
|
||||
const editor = createEditor()
|
||||
const expected =
|
||||
'<p>This is a post content mentioning <a href="/profile/f0628376-e692-4167-bdb4-d521de5a014f" rel="noopener noreferrer nofollow">@alicia-luettgen</a>.</p>'
|
||||
expect(editor.getHTML()).toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
describe('`content` contains a hashtag', () => {
|
||||
beforeEach(() => {
|
||||
content =
|
||||
'<p>This is a post content with a hashtag <a class="hashtag" href="/search/hashtag/metoo" target="_blank">#metoo</a>.</p>'
|
||||
})
|
||||
|
||||
it('renders hashtag as link', () => {
|
||||
const editor = createEditor()
|
||||
const expected =
|
||||
'<p>This is a post content with a hashtag <a href="/search/hashtag/metoo" rel="noopener noreferrer nofollow">#metoo</a>.</p>'
|
||||
expect(editor.getHTML()).toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
describe('`content` contains embed code', () => {
|
||||
beforeEach(() => {
|
||||
content =
|
||||
'<p>Baby loves cat: </p><a href="https://www.youtube.com/watch?v=qkdXAtO40Fo" class="embed" target="_blank"></a>'
|
||||
})
|
||||
|
||||
it('recognizes embed code', () => {
|
||||
const editor = createEditor()
|
||||
const expected = {
|
||||
content: [
|
||||
{
|
||||
content: [
|
||||
{
|
||||
text: 'Baby loves cat:',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'paragraph',
|
||||
},
|
||||
{
|
||||
attrs: {
|
||||
dataEmbedUrl: 'https://www.youtube.com/watch?v=qkdXAtO40Fo',
|
||||
},
|
||||
type: 'embed',
|
||||
},
|
||||
],
|
||||
type: 'doc',
|
||||
}
|
||||
expect(editor.getJSON()).toEqual(expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,14 +1,40 @@
|
||||
import { Node } from 'tiptap'
|
||||
import pasteRule from '../commands/pasteRule'
|
||||
import { compileToFunctions } from 'vue-template-compiler'
|
||||
|
||||
const template = `
|
||||
<a class="embed" :href="dataEmbedUrl" rel="noopener noreferrer nofollow">
|
||||
<div v-if="embedHtml" v-html="embedHtml" />
|
||||
<em> {{ dataEmbedUrl }} </em>
|
||||
</a>
|
||||
`
|
||||
const compiledTemplate = compileToFunctions(template)
|
||||
|
||||
export default class Embed extends Node {
|
||||
get name() {
|
||||
return 'embed'
|
||||
}
|
||||
|
||||
get defaultOptions() {
|
||||
return {
|
||||
onEmbed: () => ({}),
|
||||
}
|
||||
}
|
||||
|
||||
pasteRules({ type, schema }) {
|
||||
return [
|
||||
pasteRule(
|
||||
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g,
|
||||
type,
|
||||
url => ({ dataEmbedUrl: url }),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
get schema() {
|
||||
return {
|
||||
attrs: {
|
||||
href: {
|
||||
dataEmbedUrl: {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
@ -16,17 +42,17 @@ export default class Embed extends Node {
|
||||
selectable: false,
|
||||
parseDOM: [
|
||||
{
|
||||
tag: 'a[class=embed]',
|
||||
tag: 'a[href].embed',
|
||||
getAttrs: dom => ({
|
||||
href: dom.getAttribute('href'),
|
||||
dataEmbedUrl: dom.getAttribute('href'),
|
||||
}),
|
||||
},
|
||||
],
|
||||
toDOM: node => [
|
||||
'a',
|
||||
{
|
||||
href: node.attrs.dataEmbedUrl,
|
||||
class: 'embed',
|
||||
href: node.attrs.href,
|
||||
},
|
||||
],
|
||||
}
|
||||
@ -34,26 +60,36 @@ export default class Embed extends Node {
|
||||
|
||||
get view() {
|
||||
return {
|
||||
props: ['node', 'updateAttrs', 'view'],
|
||||
props: ['node', 'updateAttrs', 'options'],
|
||||
data: () => ({
|
||||
title: 'Link Title',
|
||||
description: 'Some Link Description text which talks a bit about the link.',
|
||||
embedData: {},
|
||||
}),
|
||||
async created() {
|
||||
if (!this.options) return {}
|
||||
this.embedData = await this.options.onEmbed({ url: this.dataEmbedUrl })
|
||||
},
|
||||
computed: {
|
||||
href: {
|
||||
embedClass() {
|
||||
return this.embedHtml ? 'embed' : ''
|
||||
},
|
||||
embedHtml() {
|
||||
const { html = '' } = this.embedData
|
||||
return html
|
||||
},
|
||||
dataEmbedUrl: {
|
||||
get() {
|
||||
return this.node.attrs.href
|
||||
return this.node.attrs.dataEmbedUrl
|
||||
},
|
||||
set(href) {
|
||||
set(dataEmbedUrl) {
|
||||
this.updateAttrs({
|
||||
href,
|
||||
dataEmbedUrl,
|
||||
})
|
||||
},
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<a class="embed" :href="href"><h4>{{ title }}</h4><p>{{ description }}</p><em>{{ href }}</em></a>
|
||||
`,
|
||||
render(createElement) {
|
||||
return compiledTemplate.render.call(this, createElement)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
webapp/components/Editor/nodes/Embed.spec.js
Normal file
66
webapp/components/Editor/nodes/Embed.spec.js
Normal file
@ -0,0 +1,66 @@
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import Embed from './Embed'
|
||||
|
||||
let Wrapper
|
||||
let propsData
|
||||
const someUrl = 'https://www.youtube.com/watch?v=qkdXAtO40Fo'
|
||||
|
||||
describe('Embed.vue', () => {
|
||||
beforeEach(() => {
|
||||
propsData = {}
|
||||
const component = new Embed()
|
||||
Wrapper = ({ mocks, propsData }) => {
|
||||
return shallowMount(component.view, { propsData })
|
||||
}
|
||||
})
|
||||
|
||||
it('renders anchor', () => {
|
||||
propsData = {
|
||||
node: { attrs: { href: someUrl } },
|
||||
}
|
||||
expect(Wrapper({ propsData }).is('a')).toBe(true)
|
||||
})
|
||||
|
||||
describe('given a href', () => {
|
||||
describe('onEmbed returned embed data', () => {
|
||||
beforeEach(() => {
|
||||
propsData.options = {
|
||||
onEmbed: () => ({
|
||||
type: 'video',
|
||||
title: 'Baby Loves Cat',
|
||||
author: 'Merkley Family',
|
||||
publisher: 'YouTube',
|
||||
date: '2015-08-16T00:00:00.000Z',
|
||||
description:
|
||||
'She’s incapable of controlling her limbs when her kitty is around. The obsession grows every day. Ps. That’s a sleep sack she’s in. Not a starfish outfit. Al...',
|
||||
url: someUrl,
|
||||
image: 'https://i.ytimg.com/vi/qkdXAtO40Fo/maxresdefault.jpg',
|
||||
audio: null,
|
||||
video: null,
|
||||
lang: 'de',
|
||||
sources: ['resource', 'oembed'],
|
||||
html:
|
||||
'<iframe width="480" height="270" src="https://www.youtube.com/embed/qkdXAtO40Fo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
it('renders the given html code', async () => {
|
||||
propsData.node = { attrs: { href: 'https://www.youtube.com/watch?v=qkdXAtO40Fo' } }
|
||||
const wrapper = Wrapper({ propsData })
|
||||
await wrapper.html()
|
||||
expect(wrapper.find('div iframe').attributes('src')).toEqual(
|
||||
'https://www.youtube.com/embed/qkdXAtO40Fo?feature=oembed',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('without embedded html but some meta data instead', () => {
|
||||
it.todo('renders description and link')
|
||||
})
|
||||
|
||||
describe('without any meta data', () => {
|
||||
it.todo('renders a link without `embed` class')
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -18,27 +18,24 @@ export default class Hashtag extends TipTapMention {
|
||||
}
|
||||
|
||||
get schema() {
|
||||
const patchedSchema = super.schema
|
||||
|
||||
patchedSchema.attrs = {
|
||||
url: {},
|
||||
label: {},
|
||||
return {
|
||||
...super.schema,
|
||||
toDOM: node => {
|
||||
return [
|
||||
'a',
|
||||
{
|
||||
class: this.options.mentionClass,
|
||||
href: `/search/hashtag/${node.attrs.id}`,
|
||||
'data-hashtag-id': node.attrs.id,
|
||||
target: '_blank',
|
||||
},
|
||||
`${this.options.matcher.char}${node.attrs.label}`,
|
||||
]
|
||||
},
|
||||
parseDOM: [
|
||||
// simply don't parse mentions from html
|
||||
// just treat them as normal links
|
||||
],
|
||||
}
|
||||
patchedSchema.toDOM = node => {
|
||||
return [
|
||||
'a',
|
||||
{
|
||||
class: this.options.mentionClass,
|
||||
href: node.attrs.url,
|
||||
target: '_blank',
|
||||
// contenteditable: 'true',
|
||||
},
|
||||
`${this.options.matcher.char}${node.attrs.label}`,
|
||||
]
|
||||
}
|
||||
patchedSchema.parseDOM = [
|
||||
// this is not implemented
|
||||
]
|
||||
return patchedSchema
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import { Link as TipTapLink } from 'tiptap-extensions'
|
||||
|
||||
export default class Link extends TipTapLink {
|
||||
pasteRules({ type }) {
|
||||
return []
|
||||
}
|
||||
|
||||
get schema() {
|
||||
return {
|
||||
attrs: {
|
||||
|
||||
@ -6,26 +6,24 @@ export default class Mention extends TipTapMention {
|
||||
}
|
||||
|
||||
get schema() {
|
||||
const patchedSchema = super.schema
|
||||
|
||||
patchedSchema.attrs = {
|
||||
url: {},
|
||||
label: {},
|
||||
return {
|
||||
...super.schema,
|
||||
toDOM: node => {
|
||||
return [
|
||||
'a',
|
||||
{
|
||||
class: this.options.mentionClass,
|
||||
href: `/profile/${node.attrs.id}`,
|
||||
'data-mention-id': node.attrs.id,
|
||||
target: '_blank',
|
||||
},
|
||||
`${this.options.matcher.char}${node.attrs.label}`,
|
||||
]
|
||||
},
|
||||
parseDOM: [
|
||||
// simply don't parse mentions from html
|
||||
// just treat them as normal links
|
||||
],
|
||||
}
|
||||
patchedSchema.toDOM = node => {
|
||||
return [
|
||||
'a',
|
||||
{
|
||||
class: this.options.mentionClass,
|
||||
href: node.attrs.url,
|
||||
target: '_blank',
|
||||
},
|
||||
`${this.options.matcher.char}${node.attrs.label}`,
|
||||
]
|
||||
}
|
||||
patchedSchema.parseDOM = [
|
||||
// this is not implemented
|
||||
]
|
||||
return patchedSchema
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { storiesOf } from '@storybook/vue'
|
||||
import { withA11y } from '@storybook/addon-a11y'
|
||||
import HcPostCard from '~/components/PostCard'
|
||||
import helpers from './helpers'
|
||||
import helpers from '~/storybook/helpers'
|
||||
|
||||
helpers.init()
|
||||
|
||||
23
webapp/graphql/EmbedQuery.js
Normal file
23
webapp/graphql/EmbedQuery.js
Normal file
@ -0,0 +1,23 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default function() {
|
||||
return gql`
|
||||
query($url: String!) {
|
||||
embed(url: $url) {
|
||||
type
|
||||
title
|
||||
author
|
||||
publisher
|
||||
date
|
||||
description
|
||||
url
|
||||
image
|
||||
audio
|
||||
video
|
||||
lang
|
||||
sources
|
||||
html
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
@ -116,7 +116,7 @@
|
||||
</ds-container>
|
||||
</div>
|
||||
<ds-container style="word-break: break-all">
|
||||
<div class="main-container" :width="{ base: '100%', md: '96%' }">
|
||||
<div class="main-container">
|
||||
<nuxt />
|
||||
</div>
|
||||
</ds-container>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
|
||||
"dev:styleguide": "cross-env STYLEGUIDE_DEV=true yarn dev",
|
||||
"storybook": "start-storybook -p 9001 -c .storybook",
|
||||
"storybook": "start-storybook -p 3002 -c storybook/",
|
||||
"build": "nuxt build",
|
||||
"start": "cross-env node server/index.js",
|
||||
"generate": "nuxt generate",
|
||||
@ -83,10 +83,10 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "~7.5.5",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/preset-env": "~7.5.5",
|
||||
"@storybook/addon-a11y": "^5.1.9",
|
||||
"@storybook/addon-actions": "^5.1.9",
|
||||
"@storybook/vue": "~5.1.9",
|
||||
"@babel/preset-env": "~7.5.5",
|
||||
"@vue/cli-shared-utils": "~3.9.0",
|
||||
"@vue/eslint-config-prettier": "~5.0.0",
|
||||
"@vue/server-test-utils": "~1.0.0-beta.29",
|
||||
@ -97,6 +97,7 @@
|
||||
"babel-loader": "~8.0.6",
|
||||
"babel-preset-vue": "~2.0.2",
|
||||
"css-loader": "~2.1.1",
|
||||
"core-js": "~2.6.9",
|
||||
"eslint": "~5.16.0",
|
||||
"eslint-config-prettier": "~6.0.0",
|
||||
"eslint-config-standard": "~12.0.0",
|
||||
@ -121,6 +122,6 @@
|
||||
"vue-jest": "~3.0.4",
|
||||
"vue-loader": "~15.7.0",
|
||||
"vue-svg-loader": "~0.12.0",
|
||||
"vue-template-compiler": "~2.6.10"
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,10 +20,7 @@
|
||||
<ds-space margin-bottom="small" />
|
||||
<ds-heading tag="h3" no-margin>{{ post.title }}</ds-heading>
|
||||
<ds-space margin-bottom="small" />
|
||||
<!-- Content -->
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<!-- TODO: replace editor content with tiptap render view -->
|
||||
<div class="content hc-editor-content" v-html="post.content" />
|
||||
<content-viewer class="content" :content="post.content" />
|
||||
<!-- eslint-enable vue/no-v-html -->
|
||||
<ds-space margin="xx-large" />
|
||||
<!-- Categories -->
|
||||
@ -62,6 +59,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentViewer from '~/components/Editor/ContentViewer'
|
||||
import HcCategory from '~/components/Category'
|
||||
import HcTag from '~/components/Tag'
|
||||
import ContentMenu from '~/components/ContentMenu'
|
||||
@ -86,6 +84,7 @@ export default {
|
||||
ContentMenu,
|
||||
HcCommentForm,
|
||||
HcCommentList,
|
||||
ContentViewer,
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
|
||||
@ -23,7 +23,7 @@ Vue.component('v-popover', {
|
||||
})
|
||||
|
||||
// Automatically import all files ending in *.stories.js
|
||||
const req = require.context('../stories', true, /.story.js$/)
|
||||
const req = require.context('../components', true, /.story.js$/)
|
||||
|
||||
function loadStories() {
|
||||
req.keys().forEach(req)
|
||||
@ -6,7 +6,7 @@ import Filters from '~/plugins/vue-filters'
|
||||
import layout from './layout.vue'
|
||||
|
||||
const helpers = {
|
||||
init() {
|
||||
init(options = {}) {
|
||||
Vue.use(Vuex)
|
||||
Vue.use(Styleguide)
|
||||
Vue.use(Filters)
|
||||
@ -16,6 +16,9 @@ const helpers = {
|
||||
Vue.i18n.add('de', require('~/locales/de.json'))
|
||||
Vue.i18n.set('en')
|
||||
Vue.i18n.fallback('en')
|
||||
|
||||
const { plugins = [] } = options
|
||||
plugins.forEach(plugin => Vue.use(plugin))
|
||||
},
|
||||
store: new Vuex.Store({
|
||||
modules: {
|
||||
382
webapp/yarn.lock
382
webapp/yarn.lock
@ -729,7 +729,7 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.12.0"
|
||||
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.3", "@babel/runtime@^7.5.0":
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.3":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
|
||||
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
|
||||
@ -1443,16 +1443,16 @@
|
||||
warning "^3.0.0"
|
||||
|
||||
"@storybook/addon-a11y@^5.1.9":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/addon-a11y/-/addon-a11y-5.1.10.tgz#0bf37a8e2827cdaa199b293b14e71e8434246591"
|
||||
integrity sha512-YiRj/8IQ5zq/I+x+aRyfS5PP9nTfuTU7O90+WtNomqCJPMBOrR3BYsEcl510jOy2iwhQwh76MFT5s1tKpMclAA==
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/addon-a11y/-/addon-a11y-5.1.9.tgz#3feea3f49680f6c311cefd1838b82721d59f397e"
|
||||
integrity sha512-5u90lEpJtO1W8unwNy5fKTKQG7Sbe3IZJpiC6rf1MdGk0avSwoxDyblt0NImPDBHTh4LeUcuCn57D7AVNLUplg==
|
||||
dependencies:
|
||||
"@storybook/addons" "5.1.10"
|
||||
"@storybook/api" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/components" "5.1.10"
|
||||
"@storybook/core-events" "5.1.10"
|
||||
"@storybook/theming" "5.1.10"
|
||||
"@storybook/addons" "5.1.9"
|
||||
"@storybook/api" "5.1.9"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
"@storybook/components" "5.1.9"
|
||||
"@storybook/core-events" "5.1.9"
|
||||
"@storybook/theming" "5.1.9"
|
||||
axe-core "^3.2.2"
|
||||
common-tags "^1.8.0"
|
||||
core-js "^3.0.1"
|
||||
@ -1466,15 +1466,15 @@
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
"@storybook/addon-actions@^5.1.9":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.1.10.tgz#8ed4272a6afc68f4a30372da2eeff414f0fe6ecd"
|
||||
integrity sha512-njl2AHBGi27NvisOB8LFnWH/3RcyJT/CW7tl1cvV2j5FH2oBjq5MsjxKyJIcKwC677k1Wr8G8fw/zSEHrPpmgA==
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.1.9.tgz#a515b62b109cb886ccd75ef2f5b12f8c27b43dd3"
|
||||
integrity sha512-h/csHPotBESyEUYlML3yyF2jUlDChB+u3TUNC3Ztzh/x7HzLqy88SL0INSIdY0dCBGx4TK5Gh+rMI7z28Hfdyw==
|
||||
dependencies:
|
||||
"@storybook/addons" "5.1.10"
|
||||
"@storybook/api" "5.1.10"
|
||||
"@storybook/components" "5.1.10"
|
||||
"@storybook/core-events" "5.1.10"
|
||||
"@storybook/theming" "5.1.10"
|
||||
"@storybook/addons" "5.1.9"
|
||||
"@storybook/api" "5.1.9"
|
||||
"@storybook/components" "5.1.9"
|
||||
"@storybook/core-events" "5.1.9"
|
||||
"@storybook/theming" "5.1.9"
|
||||
core-js "^3.0.1"
|
||||
fast-deep-equal "^2.0.1"
|
||||
global "^4.3.2"
|
||||
@ -1485,28 +1485,28 @@
|
||||
react-inspector "^3.0.2"
|
||||
uuid "^3.3.2"
|
||||
|
||||
"@storybook/addons@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.1.10.tgz#2d8d8ca20b6d9b4652744f5fc00ead483f705435"
|
||||
integrity sha512-M9b2PCp9RZxDC6wL7vVt2SCKCGXrrEAOsdpMvU569yB1zoUPEiiqElVDwb91O2eAGPnmd2yjImp90kOpKUW0EA==
|
||||
"@storybook/addons@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.1.9.tgz#ecf218d08508b97ca5e6e0f1ed361081385bd3ff"
|
||||
integrity sha512-1bavbcS/NiE65DwyKj8c0DmWmz9VekOinB+has2Pqt2bOffZoZwVnbmepcz9hH3GUyvp5fQBYbxTEmTDvF2lLA==
|
||||
dependencies:
|
||||
"@storybook/api" "5.1.10"
|
||||
"@storybook/channels" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/api" "5.1.9"
|
||||
"@storybook/channels" "5.1.9"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
core-js "^3.0.1"
|
||||
global "^4.3.2"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
"@storybook/api@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.1.10.tgz#5eeb5d9a7c268e5c89bd40c9a80293a7c72343b8"
|
||||
integrity sha512-YeZe/71zLMmgT95IMAEZOc9AwL6Y23mWvkZMwFbkokxS9+bU/qmVlQ0B9c3JBzO3OSs7sXaRqyP1o3QkQgVsiw==
|
||||
"@storybook/api@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.1.9.tgz#eec5b2f775392ce0803930104c6ce14fa4931e8b"
|
||||
integrity sha512-d1HhpOkW+706/WJ9lP5nCqOrp/icvbm0o+6jFFOGJ35AW5O9D8vDBxzvgMEO45jjN4I+rtbcNHQCxshSbPvP9w==
|
||||
dependencies:
|
||||
"@storybook/channels" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/core-events" "5.1.10"
|
||||
"@storybook/router" "5.1.10"
|
||||
"@storybook/theming" "5.1.10"
|
||||
"@storybook/channels" "5.1.9"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
"@storybook/core-events" "5.1.9"
|
||||
"@storybook/router" "5.1.9"
|
||||
"@storybook/theming" "5.1.9"
|
||||
core-js "^3.0.1"
|
||||
fast-deep-equal "^2.0.1"
|
||||
global "^4.3.2"
|
||||
@ -1520,33 +1520,33 @@
|
||||
telejson "^2.2.1"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
"@storybook/channel-postmessage@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.1.10.tgz#e0a58461d56ef20a87d8bc4df1067e7afc76950e"
|
||||
integrity sha512-kQZIwltN2cWDXluhCfdModFDK1LHV9ZhNQ1b/uD9vn1c65rQ9u7r4lRajCfS0X1dmAWqz48cBcEurAubNgmswg==
|
||||
"@storybook/channel-postmessage@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.1.9.tgz#bd710ca74d7998a234c6b1f38009020d7c34bbc0"
|
||||
integrity sha512-H71PsnDKW81eflOS48Lv9yK4O8AcoqXL6ohsWvLdrHWIBsH4zpjOIhdWHtmAaT3hyfMy+l49DQ+uCHLECEt55g==
|
||||
dependencies:
|
||||
"@storybook/channels" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/channels" "5.1.9"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
core-js "^3.0.1"
|
||||
global "^4.3.2"
|
||||
telejson "^2.2.1"
|
||||
|
||||
"@storybook/channels@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.1.10.tgz#04fd35c05032c675f7816ea1ca873c1a0415c6d9"
|
||||
integrity sha512-w7n/bV1BLu51KI1eLc75lN9H1ssBc3PZMXk88GkMiKyBVRzPlJA5ixnzH86qwYGReE0dhRpsgHXZ5XmoKaVmPA==
|
||||
"@storybook/channels@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.1.9.tgz#003cfca0b9f1ba6cf47ce68304aedd71bdb55e74"
|
||||
integrity sha512-R6i7859FsXgY9XFFErVe7gS37wGYpQEEWsO1LzUW7YptGuFTUa8yLgKkNkgfy7Zs61Xm+GiBq8PvS/CWxjotPw==
|
||||
dependencies:
|
||||
core-js "^3.0.1"
|
||||
|
||||
"@storybook/client-api@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.1.10.tgz#a10f028f2d33d044e5c3b3daea5d8375323e6a66"
|
||||
integrity sha512-v2PqiNUhwDlVDLYL94f6LFjdYMToTpuwWh9aeqzt/4PAJUnIcA+2P8+qXiYdJTqQy/u7P72HFMlc9Ru4tl3QFg==
|
||||
"@storybook/client-api@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.1.9.tgz#b598efe4ab07bffaeb4cb9e30ed9c21add739df1"
|
||||
integrity sha512-J5HDtOS7x5YRpF/CMiHdxywV5NIh1i/03Xh2RhG15lmPy87VStIGpLzhF71uCRPLEJinYelcjuXRNAJgRzUOlg==
|
||||
dependencies:
|
||||
"@storybook/addons" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/core-events" "5.1.10"
|
||||
"@storybook/router" "5.1.10"
|
||||
"@storybook/addons" "5.1.9"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
"@storybook/core-events" "5.1.9"
|
||||
"@storybook/router" "5.1.9"
|
||||
common-tags "^1.8.0"
|
||||
core-js "^3.0.1"
|
||||
eventemitter3 "^3.1.0"
|
||||
@ -1556,20 +1556,20 @@
|
||||
memoizerific "^1.11.3"
|
||||
qs "^6.6.0"
|
||||
|
||||
"@storybook/client-logger@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.1.10.tgz#f83a8717924dd222e0a6df82ae74701f27e0bb35"
|
||||
integrity sha512-vB1NoFWRTgcERwodhbgoDwI00eqU8++nXI7GhMS1CY8haZaSp3gyKfHRWyfH+M+YjQuGBRUcvIk4gK6OtSrDOw==
|
||||
"@storybook/client-logger@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.1.9.tgz#87e2f7578416269adeccd407584010bc353f14d3"
|
||||
integrity sha512-1+Otcn0EFgWNviDPNCR5LtUViADlboz9fmpZc7UY7bgaY5FVNIUO01E4T43tO7fduiRZoEvdltwTuQRm260Vjw==
|
||||
dependencies:
|
||||
core-js "^3.0.1"
|
||||
|
||||
"@storybook/components@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.1.10.tgz#4b6436f0b5bb2483fb231bee263d173a9ed7d241"
|
||||
integrity sha512-QUQeeQp1xNWiL4VlxFAea0kqn2zvBfmfPlUddOFO9lBhT6pVy0xYPjXjbTVWjVcYzZpyUNWw5GplqrR5jhlaCA==
|
||||
"@storybook/components@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.1.9.tgz#2a5258780fff07172d103287759946dbb4b13e2d"
|
||||
integrity sha512-F4xcRlifSAfqkuFWtCKRvQDahXyfWBWV2Wa+kYy4YGwEfm3kKtIHVlgdgARL22g9BdYpRFEOJ+42juOu5YvIeQ==
|
||||
dependencies:
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/theming" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
"@storybook/theming" "5.1.9"
|
||||
core-js "^3.0.1"
|
||||
global "^4.3.2"
|
||||
markdown-to-jsx "^6.9.1"
|
||||
@ -1587,32 +1587,32 @@
|
||||
recompose "^0.30.0"
|
||||
simplebar-react "^1.0.0-alpha.6"
|
||||
|
||||
"@storybook/core-events@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.1.10.tgz#5aed88c572036b6bd6dfff28976ee96e6e175d7a"
|
||||
integrity sha512-Lvu/rNcgS+XCkQKSGdNpUSWjpFF9AOSHPXsvkwHbRwJYdMDn3FznlXfDUiubOWtsziXHB6vl3wkKDlH+ckb32Q==
|
||||
"@storybook/core-events@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.1.9.tgz#441a6297e2ccfa743e15d1db1f4ac445b91f40d8"
|
||||
integrity sha512-jHe2uyoLj9i6fntHtOj5azfGdLOb75LF0e1xXE8U2SX7Zp3uwbLAcfJ+dPStdc/q+f/wBiip3tH1dIjaNuUiMw==
|
||||
dependencies:
|
||||
core-js "^3.0.1"
|
||||
|
||||
"@storybook/core@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.1.10.tgz#53d23d07716aa2721e1572d44a7f05967d7da39e"
|
||||
integrity sha512-zkNjufOFrLpFpmr73F/gaJh0W0vWqXIo5zrKvQt1LqmMeCU/v8MstHi4XidlK43UpeogfaXl5tjNCQDO/bd0Dw==
|
||||
"@storybook/core@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.1.9.tgz#8b30507676531fd41ac333b7c71b1c0db6b8da35"
|
||||
integrity sha512-P3aavCnl3Cl3WMXVERjQqnqV1Z8tN0tyOTqqiGb1fMxITSE8uZNvp33Dl0K3jr1PBl9trW+2t7eHH4h0sguLlQ==
|
||||
dependencies:
|
||||
"@babel/plugin-proposal-class-properties" "^7.3.3"
|
||||
"@babel/plugin-proposal-object-rest-spread" "^7.3.2"
|
||||
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
|
||||
"@babel/plugin-transform-react-constant-elements" "^7.2.0"
|
||||
"@babel/preset-env" "^7.4.5"
|
||||
"@storybook/addons" "5.1.10"
|
||||
"@storybook/channel-postmessage" "5.1.10"
|
||||
"@storybook/client-api" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/core-events" "5.1.10"
|
||||
"@storybook/node-logger" "5.1.10"
|
||||
"@storybook/router" "5.1.10"
|
||||
"@storybook/theming" "5.1.10"
|
||||
"@storybook/ui" "5.1.10"
|
||||
"@storybook/addons" "5.1.9"
|
||||
"@storybook/channel-postmessage" "5.1.9"
|
||||
"@storybook/client-api" "5.1.9"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
"@storybook/core-events" "5.1.9"
|
||||
"@storybook/node-logger" "5.1.9"
|
||||
"@storybook/router" "5.1.9"
|
||||
"@storybook/theming" "5.1.9"
|
||||
"@storybook/ui" "5.1.9"
|
||||
airbnb-js-shims "^1 || ^2"
|
||||
autoprefixer "^9.4.9"
|
||||
babel-plugin-add-react-displayname "^0.0.5"
|
||||
@ -1666,10 +1666,10 @@
|
||||
webpack-dev-middleware "^3.7.0"
|
||||
webpack-hot-middleware "^2.25.0"
|
||||
|
||||
"@storybook/node-logger@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.1.10.tgz#92c80b46177687cd8fda1f93a055c22711984154"
|
||||
integrity sha512-Z4UKh7QBOboQhUF5S/dKOx3OWWCNZGwYu8HZa/O+P68+XnQDhuZCYwqWG49xFhZd0Jb0W9gdUL2mWJw5POG9PA==
|
||||
"@storybook/node-logger@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.1.9.tgz#4aacf0096811fde1639fc9d1d2d521f7220dd4be"
|
||||
integrity sha512-rcSuI5n53hDMHW83gl5TR0Yn885/i2XY0AzX1DsbTeGOl3x5LhrCSZsZWetKGcx7zsO4n7o5mQszLuN1JlyE8A==
|
||||
dependencies:
|
||||
chalk "^2.4.2"
|
||||
core-js "^3.0.1"
|
||||
@ -1677,10 +1677,10 @@
|
||||
pretty-hrtime "^1.0.3"
|
||||
regenerator-runtime "^0.12.1"
|
||||
|
||||
"@storybook/router@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.1.10.tgz#d3cffd3f1105eb665882f389746ccabbb98c3c16"
|
||||
integrity sha512-BdG6/essPZFHCP2ewCG0gYFQfmuuTSHXAB5fd/rwxLSYj1IzNznC5OxkvnSaTr4rgoxxaW/z1hbN1NuA0ivlFA==
|
||||
"@storybook/router@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.1.9.tgz#8cd97bea4f2acf8ec5f6694d06fb0633dde33417"
|
||||
integrity sha512-eAmeerE/OTIwCV7WBnb1BPINVN1GTSMsUXLNWpqSISuyWJ+NZAJlObFkvXoc57QSQlv0cvXlm1FMkmRt8ku1Hw==
|
||||
dependencies:
|
||||
"@reach/router" "^1.2.1"
|
||||
core-js "^3.0.1"
|
||||
@ -1688,14 +1688,14 @@
|
||||
memoizerific "^1.11.3"
|
||||
qs "^6.6.0"
|
||||
|
||||
"@storybook/theming@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.1.10.tgz#f9bd519cdf9cccf730656e3f5fd56a339dd07c9f"
|
||||
integrity sha512-5cN1lmdVUwAR8U3T49Lfb8JW5RBvxBSPGZpUmbLGz1zi0tWBJgYXoGtw4RbTBjV9kCQOXkHGH12AsdDxHh931w==
|
||||
"@storybook/theming@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.1.9.tgz#c425f5867fae0db79e01112853b1808332a5f1a2"
|
||||
integrity sha512-4jIFJwTWVf9tsv27noLoFHlKC2Jl9DHV3q+rxGPU8bTNbufCu4oby82SboO5GAKuS3eu1cxL1YY9pYad9WxfHg==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.9"
|
||||
"@emotion/styled" "^10.0.7"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
common-tags "^1.8.0"
|
||||
core-js "^3.0.1"
|
||||
deep-object-diff "^1.1.0"
|
||||
@ -1706,19 +1706,19 @@
|
||||
prop-types "^15.7.2"
|
||||
resolve-from "^5.0.0"
|
||||
|
||||
"@storybook/ui@5.1.10":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.1.10.tgz#4262b1b09efa43d125d694452ae879b89071edd1"
|
||||
integrity sha512-ezkoVtzoKh93z2wzkqVIqyrIzTkj8tizgAkoPa7mUAbLCxu6LErHITODQoyEiJWI4Epy3yU9GYXFWwT71hdwsA==
|
||||
"@storybook/ui@5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.1.9.tgz#406667469e6dbdf320086647d8d80776bb051a51"
|
||||
integrity sha512-guzKv4VYM+06BzMXeO3QqlX0IwUHyeS6lwdPCL8Oy2V4Gi2IYHHiD6Hr1NgnBO18j9luxE38f4Ii7gEIzXMFbQ==
|
||||
dependencies:
|
||||
"@storybook/addons" "5.1.10"
|
||||
"@storybook/api" "5.1.10"
|
||||
"@storybook/channels" "5.1.10"
|
||||
"@storybook/client-logger" "5.1.10"
|
||||
"@storybook/components" "5.1.10"
|
||||
"@storybook/core-events" "5.1.10"
|
||||
"@storybook/router" "5.1.10"
|
||||
"@storybook/theming" "5.1.10"
|
||||
"@storybook/addons" "5.1.9"
|
||||
"@storybook/api" "5.1.9"
|
||||
"@storybook/channels" "5.1.9"
|
||||
"@storybook/client-logger" "5.1.9"
|
||||
"@storybook/components" "5.1.9"
|
||||
"@storybook/core-events" "5.1.9"
|
||||
"@storybook/router" "5.1.9"
|
||||
"@storybook/theming" "5.1.9"
|
||||
copy-to-clipboard "^3.0.8"
|
||||
core-js "^3.0.1"
|
||||
core-js-pure "^3.0.1"
|
||||
@ -1747,11 +1747,11 @@
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
"@storybook/vue@~5.1.9":
|
||||
version "5.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/vue/-/vue-5.1.10.tgz#37916c93faf2eca21497b359748109727ccf3216"
|
||||
integrity sha512-UeRbQ5bOWUTx5oBMfPf+ZtP5E5X74nFFhrkg0yNakohW6pLuTVoci/G8hDJ4wsjT7PgNjoE1/dggf4JKCU9tjA==
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/vue/-/vue-5.1.9.tgz#ff37730e3d9575b389dddc6870a07c34c7a53e47"
|
||||
integrity sha512-ssBQOHdArHFn/FXVsXqi+FiiSvnulux6CIjmaZTjWMgktDa1Hp7TWFN3rlYCM+WxO2KBtydK5AyRWd8+r9YelQ==
|
||||
dependencies:
|
||||
"@storybook/core" "5.1.10"
|
||||
"@storybook/core" "5.1.9"
|
||||
common-tags "^1.8.0"
|
||||
core-js "^3.0.1"
|
||||
global "^4.3.2"
|
||||
@ -2312,11 +2312,6 @@ acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.5, acorn@^6.0.7:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
|
||||
integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
|
||||
|
||||
acorn@^6.2.0:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51"
|
||||
integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==
|
||||
|
||||
address@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
|
||||
@ -3444,7 +3439,7 @@ bluebird@^3.1.1, bluebird@^3.5.1, bluebird@^3.5.3:
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.4.tgz#d6cc661595de30d5b3af5fcedd3c0b3ef6ec5714"
|
||||
integrity sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==
|
||||
|
||||
bluebird@^3.3.5, bluebird@^3.5.5:
|
||||
bluebird@^3.3.5:
|
||||
version "3.5.5"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
|
||||
integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==
|
||||
@ -3719,27 +3714,6 @@ cacache@^11.0.2, cacache@^11.3.2:
|
||||
unique-filename "^1.1.1"
|
||||
y18n "^4.0.0"
|
||||
|
||||
cacache@^12.0.2:
|
||||
version "12.0.2"
|
||||
resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.2.tgz#8db03205e36089a3df6954c66ce92541441ac46c"
|
||||
integrity sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==
|
||||
dependencies:
|
||||
bluebird "^3.5.5"
|
||||
chownr "^1.1.1"
|
||||
figgy-pudding "^3.5.1"
|
||||
glob "^7.1.4"
|
||||
graceful-fs "^4.1.15"
|
||||
infer-owner "^1.0.3"
|
||||
lru-cache "^5.1.1"
|
||||
mississippi "^3.0.0"
|
||||
mkdirp "^0.5.1"
|
||||
move-concurrently "^1.0.1"
|
||||
promise-inflight "^1.0.1"
|
||||
rimraf "^2.6.3"
|
||||
ssri "^6.0.1"
|
||||
unique-filename "^1.1.1"
|
||||
y18n "^4.0.0"
|
||||
|
||||
cache-base@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
|
||||
@ -3853,9 +3827,9 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000939, caniuse-lite@^1.0.30000957, can
|
||||
integrity sha512-rUBIbap+VJfxTzrM4akJ00lkvVb5/n5v3EGXfWzSH5zT8aJmGzjA8HWhJ4U6kCpzxozUSnB+yvAYDRPY6mRpgQ==
|
||||
|
||||
caniuse-lite@^1.0.30000955:
|
||||
version "1.0.30000988"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000988.tgz#742f35ec1b8b75b9628d705d7652eea1fef983db"
|
||||
integrity sha512-lPj3T8poYrRc/bniW5SQPND3GRtSrQdUM/R4mCYTbZxyi3jQiggLvZH4+BYUuX0t4TXjU+vMM7KFDQg+rSzZUQ==
|
||||
version "1.0.30000985"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f"
|
||||
integrity sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w==
|
||||
|
||||
caniuse-lite@^1.0.30000973:
|
||||
version "1.0.30000973"
|
||||
@ -4218,7 +4192,7 @@ commander@2.17.x:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
|
||||
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
|
||||
|
||||
commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0:
|
||||
commander@^2.18.0, commander@^2.19.0, commander@~2.20.0:
|
||||
version "2.20.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||
@ -4465,18 +4439,23 @@ core-js@^3.0.1, core-js@^3.0.4:
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.4.tgz#3a2837fc48e582e1ae25907afcd6cf03b0cc7a07"
|
||||
integrity sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==
|
||||
|
||||
core-js@~2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
|
||||
integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
corejs-upgrade-webpack-plugin@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/corejs-upgrade-webpack-plugin/-/corejs-upgrade-webpack-plugin-2.2.0.tgz#503293bf1fdcb104918eb40d0294e4776ad6923a"
|
||||
integrity sha512-J0QMp9GNoiw91Kj/dkIQFZeiCXgXoja/Wlht1SPybxerBWh4NCmb0pOgCv61lrlQZETwvVVfAFAA3IqoEO9aqQ==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/corejs-upgrade-webpack-plugin/-/corejs-upgrade-webpack-plugin-2.1.0.tgz#6afa44672486353ae639c297548c0686b64fb325"
|
||||
integrity sha512-gc+S4t8VT9YFSgOPrhZlD6kDoGZtUq71QwXxS2neGNPhli0veKhbzzilODIpy73TjXGUrCHCpevK8vBnzUPuhw==
|
||||
dependencies:
|
||||
resolve-from "^5.0.0"
|
||||
webpack "^4.38.0"
|
||||
webpack "^4.33.0"
|
||||
|
||||
cors@^2.8.4:
|
||||
version "2.8.5"
|
||||
@ -5285,9 +5264,9 @@ ejs@^2.6.1:
|
||||
integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==
|
||||
|
||||
electron-to-chromium@^1.3.122:
|
||||
version "1.3.208"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.208.tgz#6df90b89e8b9af139db3c8d7a6b935db0801e61c"
|
||||
integrity sha512-ljgZXaKSfRg32jEl1V8zRJaT3u653jxfZRztKQWM/I1kE+ifBCQKRY+jOPzb4JS48a4czvT/LQfjdiDq5qjU4g==
|
||||
version "1.3.200"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f"
|
||||
integrity sha512-PUurrpyDA74MuAjJRD+79ss5BqJlU3mdArRbuu4wO/dt6jc3Ic/6BDmFJxkdwbfq39cHf/XKm2vW98XSvut9Dg==
|
||||
|
||||
electron-to-chromium@^1.3.133:
|
||||
version "1.3.137"
|
||||
@ -7128,11 +7107,6 @@ indexof@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
|
||||
integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
|
||||
|
||||
infer-owner@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
|
||||
integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
@ -8339,11 +8313,11 @@ launch-editor@^2.2.1:
|
||||
shell-quote "^1.6.1"
|
||||
|
||||
lazy-universal-dotenv@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38"
|
||||
integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ==
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.0.tgz#e71f07f89d8de6bbf491478e4503df3c96729b8d"
|
||||
integrity sha512-Mbf5AeGOs74lE5BdQXHFJ7Rt383jxnWKNfW2EWL0Pibnhea5JRStRIiUpdTenyMxCGuCjlMpYQhhay1XZBSSQA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.0"
|
||||
"@babel/runtime" "^7.0.0"
|
||||
app-root-dir "^1.0.2"
|
||||
core-js "^3.0.4"
|
||||
dotenv "^8.0.0"
|
||||
@ -8489,6 +8463,11 @@ lodash.debounce@^4.0.8:
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
|
||||
|
||||
lodash.includes@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
||||
@ -8817,9 +8796,9 @@ merge-stream@^1.0.1:
|
||||
readable-stream "^2.0.1"
|
||||
|
||||
merge2@^1.2.3:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.4.tgz#c9269589e6885a60cf80605d9522d4b67ca646e3"
|
||||
integrity sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5"
|
||||
integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==
|
||||
|
||||
methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
@ -11133,9 +11112,9 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-clientside-effect@^1.2.0:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz#6212fb0e07b204e714581dd51992603d1accc837"
|
||||
integrity sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A==
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.1.tgz#feb81abe9531061d4987941c15a00f2b3d0b6071"
|
||||
integrity sha512-foSwZatJak6r+F4OqJ8a+MOWcBi3jwa7/RPdJIDZI1Ck0dn/FJZkkFu7YK+SiZxsCZIrotolxHSobcnBHgIjfw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.0.0"
|
||||
|
||||
@ -12241,14 +12220,6 @@ source-map-support@^0.5.6, source-map-support@~0.5.10:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map-support@~0.5.12:
|
||||
version "0.5.13"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
|
||||
integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map-url@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||
@ -12736,16 +12707,16 @@ tar@^4:
|
||||
yallist "^3.0.2"
|
||||
|
||||
telejson@^2.2.1:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/telejson/-/telejson-2.2.2.tgz#d61d721d21849a6e4070d547aab302a9bd22c720"
|
||||
integrity sha512-YyNwnKY0ilabOwYgC/J754En1xOe5PBIUIw+C9e0+5HjVVcnQE5/gdu2yET2pmSbp5bxIDqYNjvndj2PUkIiYA==
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/telejson/-/telejson-2.2.1.tgz#d9ee7e7eba0c81d9378257342fde7142a03787e2"
|
||||
integrity sha512-JtFAnITek+Z9t+uQjVl4Fxur9Z3Bi3flytBLc3KZVXmMUHLXdtAxiP0g8IBkHvKn1kQIYZC57IG0jjGH1s64HQ==
|
||||
dependencies:
|
||||
global "^4.3.2"
|
||||
is-function "^1.0.1"
|
||||
is-regex "^1.0.4"
|
||||
is-symbol "^1.0.2"
|
||||
isobject "^3.0.1"
|
||||
lodash "^4.17.11"
|
||||
lodash.get "^4.4.2"
|
||||
memoizerific "^1.11.3"
|
||||
|
||||
term-size@^1.2.0:
|
||||
@ -12774,22 +12745,7 @@ terser-webpack-plugin@^1.1.0:
|
||||
webpack-sources "^1.1.0"
|
||||
worker-farm "^1.5.2"
|
||||
|
||||
terser-webpack-plugin@^1.2.4:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz#61b18e40eaee5be97e771cdbb10ed1280888c2b4"
|
||||
integrity sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==
|
||||
dependencies:
|
||||
cacache "^12.0.2"
|
||||
find-cache-dir "^2.1.0"
|
||||
is-wsl "^1.1.0"
|
||||
schema-utils "^1.0.0"
|
||||
serialize-javascript "^1.7.0"
|
||||
source-map "^0.6.1"
|
||||
terser "^4.1.2"
|
||||
webpack-sources "^1.4.0"
|
||||
worker-farm "^1.7.0"
|
||||
|
||||
terser-webpack-plugin@^1.3.0:
|
||||
terser-webpack-plugin@^1.2.4, terser-webpack-plugin@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz#69aa22426299f4b5b3775cbed8cb2c5d419aa1d4"
|
||||
integrity sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==
|
||||
@ -12823,15 +12779,6 @@ terser@^4.0.0:
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.10"
|
||||
|
||||
terser@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.1.2.tgz#b2656c8a506f7ce805a3f300a2ff48db022fa391"
|
||||
integrity sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
test-exclude@^5.2.3:
|
||||
version "5.2.3"
|
||||
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0"
|
||||
@ -13672,7 +13619,7 @@ vue-sweetalert-icons@~3.2.0:
|
||||
resolved "https://registry.yarnpkg.com/vue-sweetalert-icons/-/vue-sweetalert-icons-3.2.0.tgz#2926d3af5590b81c0ba3b104212922fc1709396d"
|
||||
integrity sha512-N18uG8++ZfdCnXO0gHNTmwpB2mAE8WWrwjGeWGa8CnHu6l1emn4RG6E8r1P9crVJ+fx3R9gTUezC+cdVu0mN7w==
|
||||
|
||||
vue-template-compiler@^2.6.10, vue-template-compiler@~2.6.10:
|
||||
vue-template-compiler@^2.6.10:
|
||||
version "2.6.10"
|
||||
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz#323b4f3495f04faa3503337a82f5d6507799c9cc"
|
||||
integrity sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==
|
||||
@ -13821,14 +13768,6 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.3.0:
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
webpack-sources@^1.4.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.1.tgz#b91b2c5b1c4e890ff50d1d35b7fa3657040da1da"
|
||||
integrity sha512-XSz38193PTo/1csJabKaV4b53uRVotlMgqJXm3s3eje0Bu6gQTxYDqpD38CmQfDBA+gN+QqaGjasuC8I/7eW3Q==
|
||||
dependencies:
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
webpack@^4.33.0:
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.33.0.tgz#c30fc4307db432e5c5e3333aaa7c16a15a3b277e"
|
||||
@ -13859,35 +13798,6 @@ webpack@^4.33.0:
|
||||
watchpack "^1.5.0"
|
||||
webpack-sources "^1.3.0"
|
||||
|
||||
webpack@^4.38.0:
|
||||
version "4.38.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.38.0.tgz#6d77108404b08883c78f4e7e45a43c4e5c47c931"
|
||||
integrity sha512-lbuFsVOq8PZY+1Ytz/mYOvYOo+d4IJ31hHk/7iyoeWtwN33V+5HYotSH+UIb9tq914ey0Hot7z6HugD+je3sWw==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.8.5"
|
||||
"@webassemblyjs/helper-module-context" "1.8.5"
|
||||
"@webassemblyjs/wasm-edit" "1.8.5"
|
||||
"@webassemblyjs/wasm-parser" "1.8.5"
|
||||
acorn "^6.2.0"
|
||||
ajv "^6.1.0"
|
||||
ajv-keywords "^3.1.0"
|
||||
chrome-trace-event "^1.0.0"
|
||||
enhanced-resolve "^4.1.0"
|
||||
eslint-scope "^4.0.0"
|
||||
json-parse-better-errors "^1.0.2"
|
||||
loader-runner "^2.3.0"
|
||||
loader-utils "^1.1.0"
|
||||
memory-fs "~0.4.1"
|
||||
micromatch "^3.1.8"
|
||||
mkdirp "~0.5.0"
|
||||
neo-async "^2.5.0"
|
||||
node-libs-browser "^2.0.0"
|
||||
schema-utils "^1.0.0"
|
||||
tapable "^1.1.0"
|
||||
terser-webpack-plugin "^1.1.0"
|
||||
watchpack "^1.5.0"
|
||||
webpack-sources "^1.3.0"
|
||||
|
||||
webpackbar@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-3.2.0.tgz#bdaad103fad11a4e612500e72aaae98b08ba493f"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user