Showing with 1,088 additions and 621 deletions.
  1. +24 −0 CHANGELOG.md
  2. BIN assetsources/TabIcons.afdesign
  3. BIN { → assetsources}/design.sketch
  4. +1 −0 assetsources/svg/Audio.svg
  5. +1 −0 assetsources/svg/Chapters.svg
  6. +1 −0 assetsources/svg/Download.svg
  7. +1 −0 assetsources/svg/Info.svg
  8. +1 −0 assetsources/svg/Share.svg
  9. +1 −0 assetsources/svg/Transcripts.svg
  10. +7 −0 assetsources/svg/optimize.sh
  11. +1 −3 build/blocks/entry.js
  12. +8 −11 build/blocks/optimization.js
  13. +3 −2 build/blocks/output.js
  14. +2 −2 build/blocks/plugins.js
  15. +1 −0 build/blocks/resolve.js
  16. +1 −1 build/blocks/rules.js
  17. +2 −2 build/webpack.config.cdn.js
  18. +106 −1 cypress/integration/tab-info.spec.js
  19. +2 −2 docs/.vuepress/components/PodloveWebPlayer.vue
  20. +1 −1 docs/.vuepress/public/fixtures/chapters/fg55.json
  21. +3 −3 docs/.vuepress/public/fixtures/example.json
  22. +4 −2 docs/config.md
  23. +17 −20 package.json
  24. +8 −6 src/components/icons/AudioIcon.vue
  25. +2 −2 src/components/icons/ChaptersIcon.vue
  26. +3 −4 src/components/icons/DownloadIcon.vue
  27. +4 −3 src/components/icons/InfoIcon.vue
  28. +4 −4 src/components/icons/ShareIcon.vue
  29. +6 −8 src/components/icons/TranscriptsIcon.vue
  30. +21 −24 src/components/tabs/Tabs.vue
  31. +48 −5 src/components/tabs/chapters/ChapterEntry.vue
  32. +22 −3 src/components/tabs/info/Info.vue
  33. +1 −1 src/components/tabs/share/channels/ChannelFacebook.vue
  34. +1 −1 src/components/tabs/share/channels/ChannelGooglePlus.vue
  35. +1 −1 src/components/tabs/share/channels/ChannelMail.vue
  36. +1 −1 src/components/tabs/share/channels/ChannelPinterest.vue
  37. +1 −1 src/components/tabs/share/channels/ChannelReddit.vue
  38. +1 −1 src/components/tabs/share/channels/ChannelTwitter.vue
  39. +1 −1 src/components/tabs/transcripts/Entry.vue
  40. +3 −1 src/effects/chapters.js
  41. +29 −10 src/effects/chapters.test.js
  42. +10 −10 src/effects/player.test.js
  43. +14 −43 src/effects/transcripts/active.js
  44. +0 −34 src/effects/transcripts/active.test.js
  45. +1 −1 src/effects/transcripts/fetch.js
  46. +11 −35 src/effects/transcripts/search.js
  47. +11 −3 src/embed/embed.js
  48. +0 −1 src/embed/share.js
  49. +0 −1 src/embed/window.js
  50. +1 −1 src/statics/example/episode.js
  51. +1 −0 src/store/chapters/reducer.test.js
  52. +2 −1 src/store/episode/reducer.js
  53. +2 −1 src/store/show/reducer.js
  54. +8 −0 src/styles/_font.scss
  55. +4 −1 src/styles/_global.scss
  56. BIN src/styles/fonts/FiraSans-Bold.eot
  57. BIN src/styles/fonts/FiraSans-Bold.woff
  58. BIN src/styles/fonts/FiraSans-Bold.woff2
  59. +21 −0 src/utils/binary-search.js
  60. +24 −0 src/utils/binary-search.test.js
  61. +3 −2 src/utils/chapters.js
  62. +1 −0 src/utils/chapters.test.js
  63. +23 −0 src/utils/dom.js
  64. +1 −1 src/utils/dom.test.js
  65. +2 −2 src/utils/storage.js
  66. +4 −4 src/utils/storage.test.js
  67. +14 −0 src/utils/text-search.js
  68. +22 −0 src/utils/text-search.test.js
  69. +1 −1 src/utils/time.js
  70. +2 −2 src/utils/url.js
  71. +0 −11 src/vendor.js
  72. +560 −339 yarn.lock
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
<a name="4.1.6"></a>
## [4.1.6](https://github.com/podlove/podlove-web-player/compare/v4.1.5...v4.1.6) (2018-09-30)


### Bug Fixes

* add FiraSans-Bold (fira sans v8 600) webfont to improve rendering of bold in safari, change scss for chapter links to explicitly use bold when active ([fe856a8](https://github.com/podlove/podlove-web-player/commit/fe856a8))
* **chapters:** fix alt click interaction over the link part by making it based on the progressContainer vs. the event target ([f52e723](https://github.com/podlove/podlove-web-player/commit/f52e723))
* **chapters:** remove wrong click guard on onChapterClick, change to use linkHover state to guard to be in line with what is displayed ([8e3a3e0](https://github.com/podlove/podlove-web-player/commit/8e3a3e0))
* **package:** update detect-browser to version 3.0.1 ([e035721](https://github.com/podlove/podlove-web-player/commit/e035721))
* **package:** update iframe-resizer to version 3.6.2 ([2fb175e](https://github.com/podlove/podlove-web-player/commit/2fb175e))
* **package:** update lodash to version 4.17.11 ([df4cded](https://github.com/podlove/podlove-web-player/commit/df4cded))
* **package:** update lunr to version 2.3.3 ([ba4042e](https://github.com/podlove/podlove-web-player/commit/ba4042e))
* **package:** update mobile-detect to version 1.4.3 ([d1e74ba](https://github.com/podlove/podlove-web-player/commit/d1e74ba))
* **package:** update vue-i18n to version 8.1.0 ([4a13ecb](https://github.com/podlove/podlove-web-player/commit/4a13ecb))
* **tabs:** remove false 0.5 opacity of transcript icon, unify tab icon stroke widths and positions ([acc4fde](https://github.com/podlove/podlove-web-player/commit/acc4fde))


### Features

* **chapters:** add support for the "href" property in chapters by showing it in the chapters tab ([f7240f2](https://github.com/podlove/podlove-web-player/commit/f7240f2))



<a name="4.1.5"></a>
## [4.1.5](https://github.com/podlove/podlove-web-player/compare/v4.1.4...v4.1.5) (2018-08-25)

Expand Down
Binary file added assetsources/TabIcons.afdesign
Binary file not shown.
File renamed without changes.
1 change: 1 addition & 0 deletions assetsources/svg/Audio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assetsources/svg/Chapters.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assetsources/svg/Download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assetsources/svg/Info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assetsources/svg/Share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assetsources/svg/Transcripts.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions assetsources/svg/optimize.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
# requires svgo: brew install svgo
for f in *.svg; do
echo $f":";
svgo --enable={sortAttrs} --multipass --pretty $f -o - | sed 's/svg /svg width="25" height="25" /g' | sed 's/fill="#fff"/:fill="color || '"'"'currentColor'"'"'"/g' | sed 's/stroke="#fff"/:stroke="color || '"'"'currentColor'"'"'"/g'
echo;
done
4 changes: 1 addition & 3 deletions build/blocks/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ const prod = prefix => ({
embed: path.resolve(sourceDir, 'embed', 'embed.js'),
'extensions/external-events': path.resolve(sourceDir, 'extensions', 'external-events.js'),
[prepend('window', prefix)]: path.resolve(sourceDir, 'embed', 'window.js'),
[prepend('share', prefix)]: path.resolve(sourceDir, 'embed', 'share.js'),
[prepend('vendor', prefix)]: path.resolve(sourceDir, 'vendor.js')
[prepend('share', prefix)]: path.resolve(sourceDir, 'embed', 'share.js')
})

const dev = () => ({
embed: path.resolve(sourceDir, 'embed', 'embed.js'),
'extensions/external-events': path.resolve(sourceDir, 'extensions', 'external-events.js'),
window: path.resolve(sourceDir, 'embed', 'window.js'),
share: path.resolve(sourceDir, 'embed', 'share.js'),
vendor: path.resolve(sourceDir, 'vendor.js'),
example: path.resolve(sourceDir, 'statics', 'example', 'example.js')
})

Expand Down
19 changes: 8 additions & 11 deletions build/blocks/optimization.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
const { prepend } = require('./dir')
const ignoredChunks = ['embed', 'extensions/external-events']

const ignoredAssets = ['embed', 'extensions/external-events']

module.exports = prefix => ({
module.exports = (prefix = '') => ({
splitChunks: {
cacheGroups: {
default: false,
common: false,
vendors: false,
vendor: {
name: 'vendor',
chunks: chunk => ~[prepend('window', prefix), prepend('share', prefix)].indexOf(chunk.name),
name: prepend('vendor', prefix),
test: prepend('vendor', prefix),
enforce: true
test: /node_modules/
},
styles: {
name: prepend('style', prefix),
name: 'style',
test: /\.(s?css|vue)$/,
enforce: true,
chunks: chunk => !~ignoredAssets.indexOf(chunk.name),
chunks: chunk => chunk.name && !~ignoredChunks.indexOf(chunk.name),
minChunks: 1
}
}
},
runtimeChunk: false
}
})
5 changes: 3 additions & 2 deletions build/blocks/output.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { distDir } = require('./dir')
const { distDir, prepend } = require('./dir')

module.exports = publicPath => ({
module.exports = (publicPath, prefix = '') => ({
path: distDir,
filename: '[name].js',
chunkFilename: prepend('[name].js', prefix),
publicPath
})
4 changes: 2 additions & 2 deletions build/blocks/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const { sourceDir, prepend } = require('./dir')

const vue = () => new VueLoaderPlugin()

const css = () => new MiniCssExtractPlugin({
filename: `[name].css`
const css = (prefix = '') => new MiniCssExtractPlugin({
filename: prepend('[name].css', prefix)
})

const minifyCss = () => new OptimizeCSSAssetsPlugin({})
Expand Down
1 change: 1 addition & 0 deletions build/blocks/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = () => ({
utils: path.resolve(sourceDir, 'utils'),
shared: path.resolve(sourceDir, 'components', 'shared'),
icons: path.resolve(sourceDir, 'components', 'icons'),
components: path.resolve(sourceDir, 'components'),
lang: path.resolve(sourceDir, 'lang'),
core: path.resolve(sourceDir, 'core'),
styles: path.resolve(sourceDir, 'styles')
Expand Down
2 changes: 1 addition & 1 deletion build/blocks/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const autoprefixer = require('autoprefixer')
const cssClean = require('postcss-clean')

const { prepend , sourceDir} = require('./dir')
const {prepend, sourceDir} = require('./dir')

const vue = () => ({
test: /\.vue$/,
Expand Down
4 changes: 2 additions & 2 deletions build/webpack.config.cdn.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const { entry, output, resolve, optimization, rules, plugins } = require('./bloc
module.exports = {
mode: 'production',
entry: entry.prod(version),
output: output(BASE),
output: output(BASE, version),

optimization: optimization(version),

Expand All @@ -24,7 +24,7 @@ module.exports = {

plugins: [
plugins.vue(),
plugins.css(),
plugins.css(version),
plugins.minifyCss(),
plugins.version(),
plugins.base(`${BASE}${version}`),
Expand Down
107 changes: 106 additions & 1 deletion cypress/integration/tab-info.spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
/* eslint-env mocha */
/* globals cy */
/* globals cy, expect */
const { setState } = require('../helpers/state')
const domSelectors = require('../selectors')

const allowedMarkup = [
'<strong>bold text</strong>',
'<em>italic text</em>',
'<i>also italic text</i>',
'<br>',
'<p>A paragraph</p>',
'<ul>',
'<li>A unordered list item</li>',
'<li>Another unordered list item</li>',
'</ul>',
'<ol>',
'<li>An ordered list item</li>',
'<li>Another ordered list item</li>',
'</ol>',
{
test: '<a href="/path/to/somewhere">A link</a>',
expected: '<a target="_blank" href="/path/to/somewhere">A link</a>'
}
]

const prohibitedMarkup = [
'<script>foo</script>',
'<iframe />'
]

describe('Info Tab', () => {
let selectors

Expand Down Expand Up @@ -88,6 +113,46 @@ describe('Info Tab', () => {
cy.tab('info')
selectors.tabs.info.episode.summary().should('not.exist')
})

it(`allows custom markup`, function () {
this.episode.summary = allowedMarkup.map(input => {
if (typeof input === 'string') {
return input
}

return input.test
}).join('')

cy.window().then(setState(this.episode, this.audio, this.show, this.runtime))
cy.tab('info')
selectors.tabs.info.episode.summary().then($el => {
const summaryHtml = $el.html()
allowedMarkup.forEach(markup => {
let expected
if (typeof markup === 'string') {
expected = markup
} else {
expected = markup.expected
}

expect(summaryHtml).to.contain(expected)
})
})
})

it(`doesn't allow malicious markup`, function () {
this.episode.summary = ['foo', ...prohibitedMarkup].join('')

cy.window().then(setState(this.episode, this.audio, this.show, this.runtime))
cy.tab('info')
selectors.tabs.info.episode.summary().then($el => {
const summaryHtml = $el.html()

prohibitedMarkup.forEach(markup => {
expect(summaryHtml).not.to.contain(markup)
})
})
})
})

describe('Link', () => {
Expand Down Expand Up @@ -151,6 +216,46 @@ describe('Info Tab', () => {
cy.tab('info')
selectors.tabs.info.show.summary().should('not.exist')
})

it(`allows custom markup`, function () {
this.show.show.summary = allowedMarkup.map(input => {
if (typeof input === 'string') {
return input
}

return input.test
}).join('')

cy.window().then(setState(this.episode, this.audio, this.show, this.runtime))
cy.tab('info')
selectors.tabs.info.show.summary().then($el => {
const summaryHtml = $el.html()
allowedMarkup.forEach(markup => {
let expected
if (typeof markup === 'string') {
expected = markup
} else {
expected = markup.expected
}

expect(summaryHtml).to.contain(expected)
})
})
})

it(`doesn't allow malicious markup`, function () {
this.show.show.summary = ['foo', ...prohibitedMarkup].join('')

cy.window().then(setState(this.episode, this.audio, this.show, this.runtime))
cy.tab('info')
selectors.tabs.info.show.summary().then($el => {
const summaryHtml = $el.html()

prohibitedMarkup.forEach(markup => {
expect(summaryHtml).not.to.contain(markup)
})
})
})
})

describe('Link', () => {
Expand Down
4 changes: 2 additions & 2 deletions docs/.vuepress/components/PodloveWebPlayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<script>
export default {
name: 'PodloveWebPlayer',
props: ['config', 'mode', 'id'],
props: ['config', 'mode', 'id', 'extend'],
mounted: function () {
window.podlovePlayer(this.$el, this.config).then(store => {
window.podlovePlayer(this.$el, this.config, this.extend).then(store => {
this.$emit('ready', store)
return store
}).then(window.registerExternalEvents(this.id))
Expand Down
2 changes: 1 addition & 1 deletion docs/.vuepress/public/fixtures/chapters/fg55.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
{
"start":"00:01:15.911",
"title":"Universit\u00e4ts-Sternwarte M\u00fcnchen",
"href":"",
"href":"https://www.usm.uni-muenchen.de",
"image":""
},
{
Expand Down
6 changes: 3 additions & 3 deletions docs/.vuepress/public/fixtures/example.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
{
"start": "00:52:04.099",
"title": "SUBSCRIBE 9",
"href": "",
"href": "https://das-sendezentrum.de/subscribe/sub9/",
"image": "https://picsum.photos/400/400/?random&image=5"
},
{
Expand All @@ -97,7 +97,7 @@
{
"start": "01:54:38.442",
"title": "IPv6",
"href": "",
"href": "http://test.schrimpe.de/",
"image": "https://picsum.photos/400/400/?random&image=9"
},
{
Expand Down Expand Up @@ -139,7 +139,7 @@
{
"start": "03:49:50.662",
"title": "Blade Runner 2049",
"href": "",
"href": "https://en.wikipedia.org/wiki/Blade_Runner_2049",
"image": ""
},
{
Expand Down
6 changes: 4 additions & 2 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ navigation: 5
|-----------|---------------------------------------|
| start | Chapter Start Time in Format hh:mm:ss |
| title | Chapter Title |
| href | Chapter Link URL (optional) |
| image | Chapter Image URL (optional) |

_Not providing chapters will disable all chapter related functions._

Expand All @@ -67,8 +69,8 @@ _Not providing chapters will disable all chapter related functions._
{ start:"00:01:39", title: 'Begrüßung'},
{ start:"00:04:58", title: 'IETF Meeting Netzwerk'},
{ start:"00:18:37", title: 'Kalender'},
{ start:"00:33:40", title: 'Freak Show Bingo'},
{ start:"00:35:37", title: 'Wikipedia'},
{ start:"00:33:40", title: 'Freak Show Bingo', image: 'https://picsum.photos/400/400/?random&image=6'},
{ start:"00:35:37", title: 'Wikipedia', href: 'https://wikipedia.de'},
{ start:"01:17:26", title: 'iPhone Akkukalibration'},
{ start:"01:24:55", title: 'Alte iPads und iPod touches'},
{ start:"01:31:02", title: 'Find My Friends'},
Expand Down
Loading