diff --git a/client/apps/edit/components/content/sections/image_collection/index.coffee b/client/apps/edit/components/content/sections/image_collection/index.coffee index e37515b63..767be3ebf 100644 --- a/client/apps/edit/components/content/sections/image_collection/index.coffee +++ b/client/apps/edit/components/content/sections/image_collection/index.coffee @@ -12,7 +12,7 @@ DragContainer = React.createFactory require '../../../../../../components/drag_d { div, section, ul, li } = React.DOM components = require('@artsy/reaction-force/dist/components/publishing/index').default -ImageSetPreview = React.createFactory components.ImagesetPreviewClassic +ImageSetPreview = React.createFactory components.ImageSetPreviewClassic module.exports = React.createClass displayName: 'SectionImageCollection' diff --git a/client/apps/edit/components/content2/section_container/index.coffee b/client/apps/edit/components/content2/section_container/index.coffee index e3c34676d..d32b380d6 100644 --- a/client/apps/edit/components/content2/section_container/index.coffee +++ b/client/apps/edit/components/content2/section_container/index.coffee @@ -6,14 +6,13 @@ React = require 'react' _ = require 'underscore' -SectionText = React.createFactory require '../sections/text/index.coffee' -SectionVideo = React.createFactory require '../../content/sections/video/index.coffee' -SectionSlideshow = React.createFactory require '../../content/sections/slideshow/index.coffee' -SectionEmbed = React.createFactory require '../../content/sections/embed/index.coffee' -SectionFullscreen = React.createFactory require '../../content/sections/fullscreen/index.coffee' -SectionCallout = React.createFactory require '../../content/sections/callout/index.coffee' -SectionImageCollection = React.createFactory require '../sections/image_collection/index.coffee' -SectionImage = React.createFactory require '../../content/sections/image/index.coffee' +Text = React.createFactory require '../sections/text/index.coffee' +Video = React.createFactory require '../../content/sections/video/index.coffee' +Slideshow = React.createFactory require '../../content/sections/slideshow/index.coffee' +Embed = React.createFactory require '../../content/sections/embed/index.coffee' +Fullscreen = React.createFactory require '../../content/sections/fullscreen/index.coffee' +ImageCollection = React.createFactory require '../sections/image_collection/index.coffee' +Image = React.createFactory require '../../content/sections/image/index.coffee' { div, nav, button } = React.DOM icons = -> require('../../icons.jade') arguments... @@ -64,15 +63,14 @@ module.exports = React.createClass dangerouslySetInnerHTML: __html: $(icons()).filter('.remove').html() } (switch @props.section.get('type') - when 'text' then SectionText - when 'video' then SectionVideo - when 'slideshow' then SectionSlideshow - when 'embed' then SectionEmbed - when 'fullscreen' then SectionFullscreen - when 'callout' then SectionCallout - when 'image_set' then SectionImageCollection - when 'image_collection' then SectionImageCollection - when 'image' then SectionImage + when 'text' then Text + when 'video' then Video + when 'slideshow' then Slideshow + when 'embed' then Embed + when 'fullscreen' then Fullscreen + when 'image_set' then ImageCollection + when 'image_collection' then ImageCollection + when 'image' then Image )( section: @props.section sections: @props.sections diff --git a/client/apps/edit/components/content2/section_container/test/index.coffee b/client/apps/edit/components/content2/section_container/test/index.coffee index cd3673433..73469ba09 100644 --- a/client/apps/edit/components/content2/section_container/test/index.coffee +++ b/client/apps/edit/components/content2/section_container/test/index.coffee @@ -38,7 +38,7 @@ describe 'SectionContainer', -> dragOver: 4 article: new Article } - @SectionContainer.__set__ 'SectionText', -> + @SectionContainer.__set__ 'Text', -> @component = ReactDOM.render React.createElement(@SectionContainer, @props ), $("
")[0], => setTimeout => @component.setState = sinon.stub() diff --git a/client/apps/edit/components/content2/section_list/index.coffee b/client/apps/edit/components/content2/section_list/index.coffee index e7cd85847..e90bb9a27 100644 --- a/client/apps/edit/components/content2/section_list/index.coffee +++ b/client/apps/edit/components/content2/section_list/index.coffee @@ -7,7 +7,7 @@ React = require 'react' SectionContainer = React.createFactory require '../section_container/index.coffee' SectionTool = React.createFactory require '../section_tool/index.coffee' DragContainer = React.createFactory require '../../../../../components/drag_drop/index.coffee' -RichTextParagraph = React.createFactory require '../../../../../components/rich_text/components/input_paragraph.coffee' +Paragraph = React.createFactory require '../../../../../components/rich_text2/components/paragraph.coffee' { div } = React.DOM module.exports = React.createClass @@ -39,7 +39,7 @@ module.exports = React.createClass if @state.editingIndex or @state.editingIndex is 0 then false else true setPostscript: (html) -> - html = null if html is '

' + html = null unless html.length @props.article.set('postscript', html) @props.saveArticle() @@ -50,7 +50,7 @@ module.exports = React.createClass ref: 'sections' }, SectionTool { sections: @props.sections, index: -1, key: 1 } - if @props.sections.length > 0 + if @props.sections.length DragContainer { items: @props.sections.models onDragEnd: @onDragEnd @@ -59,27 +59,32 @@ module.exports = React.createClass article: @props.article }, @props.sections.map (section, i) => - [ - SectionContainer { - sections: @props.sections - section: section - index: i - editing: @state.editingIndex is i - ref: 'section' + i - key: section.cid - channel: @props.channel - onSetEditing: @onSetEditing - article: @props.article - } - SectionTool { sections: @props.sections, index: i, key: i } - ] + unless section.get('type') is 'callout' + [ + SectionContainer { + sections: @props.sections + section: section + index: i + editing: @state.editingIndex is i + ref: 'section' + i + key: section.cid + channel: @props.channel + onSetEditing: @onSetEditing + article: @props.article + } + SectionTool { sections: @props.sections, index: i, key: i } + ] if @props.channel.isEditorial() div { className: 'edit-sections__postscript' 'data-layout': 'column_width' }, - RichTextParagraph { - text: @props.article.get('postscript') or '' + Paragraph { + html: @props.article.get('postscript') or '' onChange: @setPostscript placeholder: 'Postscript (optional)' + type: 'postscript' + linked: true + layout: @props.article.get('layout') } + # TODO - Author Preview diff --git a/client/apps/edit/components/content2/section_list/index.styl b/client/apps/edit/components/content2/section_list/index.styl index 2c2994c4a..72534bf2e 100644 --- a/client/apps/edit/components/content2/section_list/index.styl +++ b/client/apps/edit/components/content2/section_list/index.styl @@ -6,15 +6,13 @@ .edit-sections__postscript max-width standard-body-w-margin margin 0 auto - padding 60px 20px 20px - font-style italic - Garamond s23 - p - margin-top 1em - margin-bottom 1em + padding 20px .public-DraftEditorPlaceholder-root position absolute color gray-dark-color + top 27px + Garamond s23 + font-style italic .standard max-width standard-max-width diff --git a/client/apps/edit/components/content2/section_list/test/index.coffee b/client/apps/edit/components/content2/section_list/test/index.coffee index 3174a9010..43ecb7e57 100644 --- a/client/apps/edit/components/content2/section_list/test/index.coffee +++ b/client/apps/edit/components/content2/section_list/test/index.coffee @@ -20,18 +20,18 @@ describe 'SectionList', -> global.HTMLElement = () => {} @SectionList = benv.require resolve(__dirname, '../index') DragContainer = benv.require resolve(__dirname, '../../../../../../components/drag_drop/index') - RichTextParagraph = benv.require resolve( - __dirname, '../../../../../../components/rich_text/components/input_paragraph.coffee' + Paragraph = benv.require resolve( + __dirname, '../../../../../../components/rich_text2/components/paragraph.coffee' ) @SectionList.__set__ 'SectionTool', @SectionTool = sinon.stub() @SectionContainer = benv.requireWithJadeify( resolve(__dirname, '../../section_container/index'), ['icons'] ) - @SectionContainer.__set__ 'SectionText', text = sinon.stub() - @SectionContainer.__set__ 'SectionImageCollection', image_collection = sinon.stub() + @SectionContainer.__set__ 'Text', text = sinon.stub() + @SectionContainer.__set__ 'ImageCollection', image_collection = sinon.stub() @SectionList.__set__ 'SectionContainer', React.createFactory @SectionContainer @SectionList.__set__ 'DragContainer', React.createFactory DragContainer - @SectionList.__set__ 'RichTextParagraph', React.createFactory RichTextParagraph + @SectionList.__set__ 'Paragraph', React.createFactory Paragraph @props = { article: new Backbone.Model {layout: 'feature'} sections: @sections = new Sections [ diff --git a/client/apps/edit/components/content2/sections/header/index.coffee b/client/apps/edit/components/content2/sections/header/index.coffee index ef76f9e0b..39b27d58e 100644 --- a/client/apps/edit/components/content2/sections/header/index.coffee +++ b/client/apps/edit/components/content2/sections/header/index.coffee @@ -1,9 +1,8 @@ React = require 'react' moment = require 'moment' -RichTextParagraph = React.createFactory require '../../../../../../components/rich_text2/components/input_paragraph.coffee' +Paragraph = React.createFactory require '../../../../../../components/rich_text2/components/paragraph.coffee' { div, p, textarea } = React.DOM - module.exports = React.createClass displayName: 'SectionHeader' @@ -23,10 +22,14 @@ module.exports = React.createClass div { className: 'edit-header__lead-paragraph' }, - RichTextParagraph { - text: @props.article.get('lead_paragraph') + Paragraph { + html: @props.article.get('lead_paragraph') onChange: @setLeadParagraph - placeholder: 'Lead paragraph (optional)' + placeholder: 'Lead Paragraph (optional)' + type: 'lead_paragraph' + linked: false + linebreaks: false + layout: @props.article.get('layout') } render: -> @@ -48,7 +51,7 @@ module.exports = React.createClass onKeyUp: @setTitle ref: 'title' } - unless @props.article.get('title')?.length > 0 + unless @props.article.get('title')?.length div { className: 'edit-required' } if layout is 'classic' @@ -60,5 +63,5 @@ module.exports = React.createClass @props.article.get('author').name p { className: 'date' }, @props.article.getPublishDate() - if layout is 'standard' and @props.article.get('lead_paragraph').length + if layout is 'standard' and @props.article.get('lead_paragraph')?.length @renderLeadParagraph() diff --git a/client/apps/edit/components/content2/sections/header/index.styl b/client/apps/edit/components/content2/sections/header/index.styl index 652a30121..f51c4cc95 100644 --- a/client/apps/edit/components/content2/sections/header/index.styl +++ b/client/apps/edit/components/content2/sections/header/index.styl @@ -2,6 +2,7 @@ padding-top 60px .public-DraftEditorPlaceholder-root position absolute + top 1em color gray-dark-color &__title position relative @@ -82,5 +83,4 @@ garamond l-body max-width classic-body-width margin 20px auto 0 auto - .public-DraftEditorPlaceholder-root - color gray-dark-color + diff --git a/client/apps/edit/components/content2/sections/header/test/index.coffee b/client/apps/edit/components/content2/sections/header/test/index.coffee index cf56cf482..21bcbf062 100644 --- a/client/apps/edit/components/content2/sections/header/test/index.coffee +++ b/client/apps/edit/components/content2/sections/header/test/index.coffee @@ -19,8 +19,8 @@ describe 'SectionHeader: Classic', -> benv.expose $: benv.require 'jquery' global.HTMLElement = () => {} SectionHeader = benv.require resolve(__dirname, '../index.coffee') - RichTextParagraph = benv.require resolve(__dirname, '../../../../../../../components/rich_text2/components/input_paragraph.coffee') - SectionHeader.__set__ 'RichTextParagraph', React.createFactory RichTextParagraph + Paragraph = benv.require resolve(__dirname, '../../../../../../../components/rich_text2/components/paragraph.coffee') + SectionHeader.__set__ 'Paragraph', React.createFactory Paragraph @article = new Article _.extend fixtures().articles, layout: 'classic' author: @@ -69,7 +69,7 @@ describe 'SectionHeader: Classic', -> describe 'Lead Paragraph', -> it 'renders a lead paragraph component', -> - $(ReactDOM.findDOMNode(@component)).html().should.containEql '
' + $(ReactDOM.findDOMNode(@component)).html().should.containEql '
' it 'Can display a saved lead paragraph', -> $(ReactDOM.findDOMNode(@component)).html().should.containEql 'Just before the lines start forming...' @@ -112,8 +112,8 @@ describe 'SectionHeader: Standard', -> benv.expose $: benv.require 'jquery' global.HTMLElement = () => {} SectionHeader = benv.require resolve(__dirname, '../index.coffee') - RichTextParagraph = benv.require resolve(__dirname, '../../../../../../../components/rich_text2/components/input_paragraph.coffee') - SectionHeader.__set__ 'RichTextParagraph', React.createFactory RichTextParagraph + Paragraph = benv.require resolve(__dirname, '../../../../../../../components/rich_text2/components/paragraph.coffee') + SectionHeader.__set__ 'Paragraph', React.createFactory Paragraph @article = new Article _.extend fixtures().articles, layout: 'standard' author: @@ -143,15 +143,15 @@ describe 'SectionHeader: Standard', -> describe 'Lead Paragraph', -> it 'renders a lead paragraph component if field has text', -> - $(ReactDOM.findDOMNode(@component)).html().should.containEql '
' + $(ReactDOM.findDOMNode(@component)).html().should.containEql '
' + + it 'Can display a saved lead paragraph', -> + $(ReactDOM.findDOMNode(@component)).text().should.containEql 'Just before the lines start forming...' it 'does not render lead paragraph component if field is empty', -> @component.props.article.set('lead_paragraph', '') @component.forceUpdate() - $(ReactDOM.findDOMNode(@component)).html().should.not.containEql '
' - - it 'Can display a saved lead paragraph', -> - $(ReactDOM.findDOMNode(@component)).html().should.containEql 'Just before the lines start forming...' + $(ReactDOM.findDOMNode(@component)).html().should.not.containEql '
' it '#setLeadParagraph sets and saves article lead paragraph on change', -> @component.setLeadParagraph('

A new paragraph

') diff --git a/client/apps/edit/components/content2/sections/image_collection/index.coffee b/client/apps/edit/components/content2/sections/image_collection/index.coffee index 67f6ba7e1..3103904c7 100644 --- a/client/apps/edit/components/content2/sections/image_collection/index.coffee +++ b/client/apps/edit/components/content2/sections/image_collection/index.coffee @@ -10,9 +10,8 @@ Controls = React.createFactory require './components/controls.coffee' DragContainer = React.createFactory require '../../../../../../components/drag_drop/index.coffee' { fillWidth } = require '../../../../../../components/fill_width/index.coffee' { div, section, ul, li } = React.DOM - components = require('@artsy/reaction-force/dist/components/publishing/index').default -ImagesetPreviewClassic = React.createFactory components.ImagesetPreviewClassic +ImageSetPreviewClassic = React.createFactory components.ImageSetPreviewClassic module.exports = React.createClass displayName: 'SectionImageCollection' @@ -115,7 +114,7 @@ module.exports = React.createClass }, if hasImages if !@props.editing and @props.section.get('type') is 'image_set' - ImagesetPreviewClassic { + ImageSetPreviewClassic { images: images } else diff --git a/client/apps/edit/components/content2/sections/text/index.coffee b/client/apps/edit/components/content2/sections/text/index.coffee index 0feb03b19..775711d9b 100644 --- a/client/apps/edit/components/content2/sections/text/index.coffee +++ b/client/apps/edit/components/content2/sections/text/index.coffee @@ -3,39 +3,27 @@ ReactDOM = require 'react-dom' _s = require 'underscore.string' sd = require('sharify').data window.process = {env: {NODE_ENV: sd.NODE_ENV}} +components = require('@artsy/reaction-force/dist/components/publishing/index').default +Config = require './draft_config.coffee' +Nav = React.createFactory require '../../../../../../components/rich_text2/components/nav.coffee' +InputUrl = React.createFactory require '../../../../../../components/rich_text2/components/input_url.coffee' +Text = React.createFactory components.Text +Utils = require '../../../../../../components/rich_text2/utils/index.coffee' { CompositeDecorator, ContentState, Editor, EditorState, RichUtils, Modifier } = require 'draft-js' -{ blockTypes, - blockRenderMap, - decorators, - inlineStyles } = require './draft_config.coffee' -{ convertFromRichHtml, - convertToRichHtml, - getExistingLinkData, - getSelectionDetails, - getSelectionLocation, - keyBindingFnFull, - moveSelection, - setContentStartEnd, - setSelectionToStart, - standardizeSpacing, - stickyControlsBox, - stripCharacterStyles, - stripGoogleStyles } = require '../../../../../../components/rich_text2/utils/index.coffee' editor = (props) -> React.createElement Editor, props { div } = React.DOM -EditNav = React.createFactory require '../../../../../../components/rich_text2/components/edit_nav.coffee' -InputUrl = React.createFactory require '../../../../../../components/rich_text2/components/input_url.coffee' + module.exports = React.createClass displayName: 'SectionText' getInitialState: -> - editorState: EditorState.createEmpty(new CompositeDecorator(decorators(@props.article.get('layout')))) + editorState: EditorState.createEmpty(new CompositeDecorator(Config.decorators(@props.article.get('layout')))) focus: false html: null selectionTarget: null @@ -47,12 +35,12 @@ module.exports = React.createClass componentDidMount: -> if @props.section.get('body')?.length - html = standardizeSpacing @props.section.get('body') + html = Utils.standardizeSpacing @props.section.get('body') unless @props.article.get('layout') is 'classic' - html = setContentStartEnd(html, @props.article.get('layout'), @props.isStartText, @props.isEndText) - blocksFromHTML = convertFromRichHtml html - editorState = EditorState.createWithContent(blocksFromHTML, new CompositeDecorator(decorators(@props.article.get('layout')))) - editorState = setSelectionToStart(editorState) if @props.editing + html = Utils.setContentStartEnd(html, @props.article.get('layout'), @props.isStartText, @props.isEndText) + blocksFromHTML = Utils.convertFromRichHtml html + editorState = EditorState.createWithContent(blocksFromHTML, new CompositeDecorator(Config.decorators(@props.article.get('layout')))) + editorState = Utils.setSelectionToStart(editorState) if @props.editing @setState html: html editorState: editorState @@ -62,7 +50,7 @@ module.exports = React.createClass componentDidUpdate: (prevProps) -> if @props.isEndText isnt prevProps.isEndText or @props.isStartText isnt prevProps.isStartText unless @props.article.get('layout') is 'classic' - html = setContentStartEnd(@props.section.get('body'), @props.article.get('layout'), @props.isStartText, @props.isEndText) + html = Utils.setContentStartEnd(@props.section.get('body'), @props.article.get('layout'), @props.isStartText, @props.isEndText) @props.section.set('body', html) if @props.editing and @props.editing isnt prevProps.editing @focus() @@ -70,7 +58,7 @@ module.exports = React.createClass @refs.editor.blur() onChange: (editorState) -> - html = convertToRichHtml editorState, @props.article.get('layout') + html = Utils.convertToRichHtml editorState, @props.article.get('layout') @setState editorState: editorState, html: html @props.section.set('body', html) @@ -84,7 +72,7 @@ module.exports = React.createClass @refs.editor.focus() handleReturn: (e) -> - selection = getSelectionDetails(@state.editorState) + selection = Utils.getSelectionDetails(@state.editorState) # dont split from the first block, to avoid creating empty blocks # dont split from the middle of a paragraph if selection.isFirstBlock or selection.anchorOffset @@ -102,16 +90,16 @@ module.exports = React.createClass @props.onSetEditing index handleBackspace: (e) -> - selection = getSelectionDetails(@state.editorState) + selection = Utils.getSelectionDetails(@state.editorState) # only merge a section if cursor is in first character of first block if selection.isFirstBlock and selection.anchorOffset is 0 and - @props.sections.models[@props.index - 1].get('type') is 'text' + @props.sections.models[@props.index - 1]?.get('type') is 'text' mergeIntoHTML = @props.sections.models[@props.index - 1].get('body') @props.sections.models[@props.index - 1].destroy() newHTML = mergeIntoHTML + @state.html - blocksFromHTML = convertFromRichHtml newHTML + blocksFromHTML = Utils.convertFromRichHtml newHTML newSectionState = EditorState.push(@state.editorState, blocksFromHTML, null) - newSectionState = setSelectionToStart newSectionState + newSectionState = Utils.setSelectionToStart newSectionState @onChange newSectionState @props.onSetEditing @props.index - 1 @@ -119,7 +107,7 @@ module.exports = React.createClass direction = 0 direction = -1 if e.key in ['ArrowUp', 'ArrowLeft'] direction = 1 if e.key in ['ArrowDown', 'ArrowRight'] - selection = getSelectionDetails @state.editorState + selection = Utils.getSelectionDetails @state.editorState # if cursor is arrowing forward from last charachter of last block, # or cursor is arrowing back from first character of first block, # jump to adjacent section @@ -129,7 +117,7 @@ module.exports = React.createClass else if e.key in ['ArrowLeft', 'ArrowRight'] # manually move cursor to make up for draft's missing l/r arrow fallbacks shift = if e.shiftKey then true else false - newEditorState = moveSelection @state.editorState, selection, direction, shift + newEditorState = Utils.moveSelection @state.editorState, selection, direction, shift @onChange(newEditorState) else return true @@ -146,7 +134,7 @@ module.exports = React.createClass currentState = EditorState.push(editorState, currentContent, 'remove-range') newSectionContent = ContentState.createFromBlockArray newBlockArray newSectionState = EditorState.push(editorState, newSectionContent, null) - newSectionHtml = convertToRichHtml(newSectionState) + newSectionHtml = Utils.convertToRichHtml(newSectionState) @onChange currentState @props.sections.add {type: 'text', body: newSectionHtml}, {at: @props.index + 1} return 'handled' @@ -155,10 +143,10 @@ module.exports = React.createClass { editorState } = @state unless html html = '
' + text + '
' - html = stripGoogleStyles(html) - blocksFromHTML = convertFromRichHtml html + html = Utils.stripGoogleStyles(html) + blocksFromHTML = Utils.convertFromRichHtml html convertedHtml = blocksFromHTML.getBlocksAsArray().map (contentBlock) => - unstyled = stripCharacterStyles contentBlock, true + unstyled = Utils.stripCharacterStyles contentBlock, true unless unstyled.getType() in @availableBlocks() or unstyled.getType() is 'LINK' unstyled = unstyled.set 'type', 'unstyled' return unstyled @@ -173,13 +161,13 @@ module.exports = React.createClass noLinks = RichUtils.toggleLink editorState, selection, null noBlocks = RichUtils.toggleBlockType noLinks, 'unstyled' noStyles = noBlocks.getCurrentContent().getBlocksAsArray().map (contentBlock) => - stripCharacterStyles contentBlock + Utils.stripCharacterStyles contentBlock newState = ContentState.createFromBlockArray noStyles if !selection.isCollapsed() @onChange EditorState.push(editorState, newState, null) availableBlocks: -> - blockMap = blockRenderMap(@props.article.get('layout'), @state.hasFeatures) + blockMap = Config.blockRenderMap(@props.article.get('layout'), @state.hasFeatures) available = Object.keys(blockMap.toObject()) return Array.from(available) @@ -194,14 +182,14 @@ module.exports = React.createClass @handleBackspace e else if e in ['italic', 'bold'] if @props.article.get('layout') is 'classic' and - getSelectionDetails(@state.editorState).anchorType is 'header-three' + Utils.getSelectionDetails(@state.editorState).anchorType is 'header-three' return 'handled' newState = RichUtils.handleKeyCommand @state.editorState, e @onChange newState if newState else if e is 'strikethrough' @toggleInlineStyle 'STRIKETHROUGH' else if e is 'link-prompt' - className = getExistingLinkData(@state.editorState).className + className = Utils.getExistingLinkData(@state.editorState).className return @promptForLink() unless className?.includes 'is-follow-link' @promptForLink 'artist' @@ -232,19 +220,19 @@ module.exports = React.createClass return 'handled' toggleInlineStyle: (inlineStyle) -> - selection = getSelectionDetails(@state.editorState) + selection = Utils.getSelectionDetails(@state.editorState) if selection.anchorType is 'header-three' and @props.article.get('layout') is 'classic' block = @state.editorState.getCurrentContent().getBlockForKey(selection.anchorKey) - stripCharacterStyles block + Utils.stripCharacterStyles block else @onChange RichUtils.toggleInlineStyle(@state.editorState, inlineStyle) promptForLink: (pluginType) -> selectionTarget = null unless window.getSelection().isCollapsed - location = getSelectionLocation $(ReactDOM.findDOMNode(@refs.editor)).offset() - selectionTarget = stickyControlsBox(location, 25, 200) - url = getExistingLinkData(@state.editorState).url + location = Utils.getSelectionLocation $(ReactDOM.findDOMNode(@refs.editor)).offset() + selectionTarget = Utils.stickyControlsBox(location, 25, 200) + url = Utils.getExistingLinkData(@state.editorState).url @setState showUrlInput: true showMenu: false @@ -282,9 +270,9 @@ module.exports = React.createClass checkSelection: -> if !window.getSelection().isCollapsed - location = getSelectionLocation $(ReactDOM.findDOMNode(@refs.editor)).offset() + location = Utils.getSelectionLocation $(ReactDOM.findDOMNode(@refs.editor)).offset() selectionTargetL = if @state.hasFeatures then 125 else 100 - @setState showMenu: true, selectionTarget: stickyControlsBox(location, -93, selectionTargetL) + @setState showMenu: true, selectionTarget: Utils.stickyControlsBox(location, -93, selectionTargetL) else @setState showMenu: false @@ -295,42 +283,43 @@ module.exports = React.createClass className: 'edit-section--text' + isEditing onClick: @focus }, - if @state.showMenu - EditNav { - hasFeatures: @state.hasFeatures - blocks: blockTypes @props.article.get('layout'), @state.hasFeatures - toggleBlock: @toggleBlockType - styles: inlineStyles @props.article.get('layout'), @state.hasFeatures - toggleStyle: @toggleInlineStyle - promptForLink: @promptForLink - makePlainText: @makePlainText - position: @state.selectionTarget - } - div { - className: 'edit-section--text__input' - onMouseUp: @checkSelection - onKeyUp: @checkSelection - }, - editor { - ref: 'editor' - editorState: @state.editorState - spellCheck: true - onChange: @onChange - decorators: decorators - handleKeyCommand: @handleKeyCommand - keyBindingFn: keyBindingFnFull - handlePastedText: @onPaste - blockRenderMap: blockRenderMap @props.article.get('layout'), @state.hasFeatures - handleReturn: @handleReturn - onTab: @handleTab - onUpArrow: @handleChangeSection - onDownArrow: @handleChangeSection - } - if @props.editing and @state.showUrlInput - InputUrl { - removeLink: @removeLink - confirmLink: @confirmLink - selectionTarget: @state.selectionTarget - pluginType: @state.pluginType - urlValue: @state.urlValue + Text { layout: @props.article.get 'layout' }, + if @state.showMenu + Nav { + hasFeatures: @state.hasFeatures + blocks: Config.blockTypes @props.article.get('layout'), @state.hasFeatures + toggleBlock: @toggleBlockType + styles: Config.inlineStyles @props.article.get('layout'), @state.hasFeatures + toggleStyle: @toggleInlineStyle + promptForLink: @promptForLink + makePlainText: @makePlainText + position: @state.selectionTarget + } + div { + className: 'edit-section--text__input' + onMouseUp: @checkSelection + onKeyUp: @checkSelection + }, + editor { + ref: 'editor' + editorState: @state.editorState + spellCheck: true + onChange: @onChange + decorators: Config.decorators + handleKeyCommand: @handleKeyCommand + keyBindingFn: Utils.keyBindingFnFull + handlePastedText: @onPaste + blockRenderMap: Config.blockRenderMap @props.article.get('layout'), @state.hasFeatures + handleReturn: @handleReturn + onTab: @handleTab + onUpArrow: @handleChangeSection + onDownArrow: @handleChangeSection } + if @props.editing and @state.showUrlInput + InputUrl { + removeLink: @removeLink + confirmLink: @confirmLink + selectionTarget: @state.selectionTarget + pluginType: @state.pluginType + urlValue: @state.urlValue + } diff --git a/client/apps/edit/components/content2/sections/text/index.styl b/client/apps/edit/components/content2/sections/text/index.styl index 7d7419ae0..3d6de940d 100644 --- a/client/apps/edit/components/content2/sections/text/index.styl +++ b/client/apps/edit/components/content2/sections/text/index.styl @@ -17,8 +17,6 @@ ul li .public-DraftStyleDefault-ltr, li.public-DraftStyleDefault-unorderedListItem .public-DraftStyleDefault-ltr list-style disc - li - padding .5em 0 nav &.has-plugins button[name='remove-formatting'], @@ -29,89 +27,6 @@ .artist-follow background-image none !important &:before - content url(/icons/circle_plus.svg) - padding-left 10px - vertical-align -8.5px - &:after - content 'Follow' - garamond('s-body') - text-transform none - letter-spacing 0px + content url(/icons/circle_plus.svg) !important -.classic .edit-section--text - garamond l-body - p - padding-top .75em - padding-bottom .75em - h2 - garamond l-header - font-size 28px - line-height 1.2em - padding-top .5em - h3 - avant-garde body - line-height 27px - span - font-style normal !important - blockquote - garamond l-headline - text-align center - -.standard .edit-section--text, -.feature .edit-section--text - Garamond s23 - p - padding-top 1em - padding-bottom 1em - &:first-child - padding-top 0 - &:last-child - padding-bottom 0 - h2 - Garamond s40 - h3 - Unica s19 - padding-top 23px - blockquote - padding-top 46px - padding-bottom 46px - .content-end - background-color black - height 15px - width @height - border-radius 50% - display inline-block - margin-left 15px - -.standard .edit-section--text - blockquote - Garamond s50 - -.feature .edit-section--text - blockquote - Unica s69 - h1 - Unica s40 - text-align center - padding-bottom 46px - padding-top 107px - position relative - &:before - position absolute - top 69px - right calc(50% \- 7.5px) - content '.' - height 15px - width @height - background black - border-radius 50% - color rgba(0,0,0,0) - .content-start - Unica s69, medium - float left - line-height .5em - margin-right 10px - margin-top .298em - text-transform uppercase - diff --git a/client/apps/edit/components/content2/sections/text/test/index.coffee b/client/apps/edit/components/content2/sections/text/test/index.coffee index eb9ef4778..eea5c9064 100644 --- a/client/apps/edit/components/content2/sections/text/test/index.coffee +++ b/client/apps/edit/components/content2/sections/text/test/index.coffee @@ -38,13 +38,13 @@ describe 'Section Text', -> InputUrl = benv.requireWithJadeify( resolve(__dirname, '../../../../../../../components/rich_text2/components/input_url'), ['icons'] ) - EditNav = benv.requireWithJadeify( - resolve(__dirname, '../../../../../../../components/rich_text2/components/edit_nav'), ['icons'] + Nav = benv.requireWithJadeify( + resolve(__dirname, '../../../../../../../components/rich_text2/components/nav'), ['icons'] ) @SectionText.__set__ 'InputUrl', React.createFactory InputUrl - @SectionText.__set__ 'EditNav', React.createFactory EditNav - @SectionText.__set__ 'stickyControlsBox', sinon.stub().returns {top: 20, left: 40} - @SectionText.__set__ 'getSelectionLocation', sinon.stub().returns({top: 20, left: 40}) + @SectionText.__set__ 'Nav', React.createFactory Nav + @SectionText.__set__ 'Utils.stickyControlsBox', sinon.stub().returns {top: 20, left: 40} + @SectionText.__set__ 'Utils.getSelectionLocation', sinon.stub().returns({top: 20, left: 40}) @sections = new Backbone.Collection [ { body: '

01 here is a link.

In 2016, K mounted a solo show at prescient Berlin gallery KOW, restaging his installation It’s Spring and the Weather is Great so let’s close all object matters (2012), for which he created seven step ladders with microphones and instruments attached for a performance initially meant to take place at Speakers’ Corner in London’s Hyde Park that was eventually mounted in 2010 at the Serpentine Galleries.



' diff --git a/client/components/rich_text2/components/input_paragraph.coffee b/client/components/rich_text2/components/input_paragraph.coffee deleted file mode 100644 index c861ba333..000000000 --- a/client/components/rich_text2/components/input_paragraph.coffee +++ /dev/null @@ -1,105 +0,0 @@ -# A basic paragraph component including bold and italic by default - -# RichTextParagraph { -# text *required -# onChange *required -# placeholder -# styleMap: ['italic', 'underline'] #overrides default styles -# } - -React = require 'react' -sd = require('sharify').data -window.process = {env: {NODE_ENV: sd.NODE_ENV}} -{ ContentState, - Editor, - EditorState, - RichUtils, - Modifier } = require 'draft-js' -{ convertToHTML, convertFromHTML } = require 'draft-convert' -{ div } = React.DOM -editor = (props) -> React.createElement Editor, props - -module.exports = React.createClass - displayName: 'RichTextParagraph' - - getInitialState: -> - editorState: EditorState.createEmpty() - focus: false - styleMap: @props.styleMap or ['bold', 'italic'] - - componentDidMount: -> - if $(@props.text).text().length - blocksFromHTML = @convertFromHTML(@props.text) - @setState - html: @props.text - editorState: EditorState.createWithContent(blocksFromHTML) - - onChange: (editorState) -> - html = @convertToHtml editorState - @setState editorState: editorState, html: html - @props.onChange(html) - - focus: -> - @setState focus: true - @refs.editor.focus() - - onBlur: -> - @setState focus: false - - convertFromHTML: (html) -> - blocksFromHTML = convertFromHTML({})(html) - return blocksFromHTML - - convertToHtml: (editorState) -> - html = convertToHTML({})(editorState.getCurrentContent()) - html = html.replace(/ /g, '  ') - return html - - onPaste: (text, html) -> - { editorState } = @state - unless html - html = '
' + text + '
' - blocksFromHTML = @convertFromHTML(html) - convertedHtml = blocksFromHTML.getBlocksAsArray().map (contentBlock) => - unstyled = @stripPastedStyles contentBlock - unless unstyled.getType() is 'unstyled' - unstyled = unstyled.set('type', 'unstyled') - return unstyled - blockMap = ContentState.createFromBlockArray(convertedHtml, blocksFromHTML.entityMap).blockMap - newState = Modifier.replaceWithFragment(editorState.getCurrentContent(), editorState.getSelection(), blockMap) - this.onChange(EditorState.push(editorState, newState, 'insert-fragment')) - return true - - stripPastedStyles: (contentBlock) -> - styleMap = @state.styleMap.map (style) -> - return style.toUpperCase() - characterList = contentBlock.getCharacterList().map (character) -> - if character.get('style') not in styleMap - character.set('style', character.get('style').clear()) - unstyled = contentBlock.set('characterList', characterList) - return unstyled - - handleKeyCommand: (e) -> - if e in @state.styleMap - newState = RichUtils.handleKeyCommand @state.editorState, e - if newState - @onChange newState - return true - return false - - render: -> - div { className: 'rich-text--paragraph' }, - div { - className: 'rich-text--paragraph__input' - onClick: @focus - onBlur: @onBlur - }, - editor { - ref: 'editor' - placeholder: @props.placeholder - editorState: @state.editorState - spellCheck: true - onChange: @onChange - handlePastedText: @onPaste - handleKeyCommand: @handleKeyCommand - } diff --git a/client/components/rich_text2/components/edit_nav.coffee b/client/components/rich_text2/components/nav.coffee similarity index 98% rename from client/components/rich_text2/components/edit_nav.coffee rename to client/components/rich_text2/components/nav.coffee index 9f5be29a5..4bf35eed7 100644 --- a/client/components/rich_text2/components/edit_nav.coffee +++ b/client/components/rich_text2/components/nav.coffee @@ -4,7 +4,7 @@ _ = require 'underscore' icons = -> require('../utils/icons.jade') arguments... module.exports = React.createClass - displayName: 'EditNav' + displayName: 'RichTextNav' onToggle: (e) -> e.preventDefault() diff --git a/client/components/rich_text2/components/paragraph.coffee b/client/components/rich_text2/components/paragraph.coffee new file mode 100644 index 000000000..b1b009d45 --- /dev/null +++ b/client/components/rich_text2/components/paragraph.coffee @@ -0,0 +1,259 @@ +# A basic paragraph component: supports bold and italic styles +# optionally allows links and stripping of linebreaks +# or format in types 'postscript', 'caption' and 'lead paragraph' + +# Paragraph { +# html *required +# onChange *required +# placeholder +# layout: article.layout +# postscript: default=false +# linked: default=false +# stripLinebreaks: default=false +# type: 'postscript' | 'caption' | 'lead paragraph' +# } + +React = require 'react' +ReactDOM = require 'react-dom' +sd = require('sharify').data +window.process = {env: {NODE_ENV: sd.NODE_ENV}} +Config = require '../utils/config.coffee' +Utils = require '../utils/index.coffee' +{ ContentState, + CompositeDecorator, + Editor, + EditorState, + Entity, + RichUtils, + Modifier } = require 'draft-js' +{ convertToHTML, convertFromHTML } = require 'draft-convert' +{ div, a } = React.DOM +editor = (props) -> React.createElement Editor, props +components = require('@artsy/reaction-force/dist/components/publishing/index').default +Nav = React.createFactory require './nav.coffee' +InputUrl = React.createFactory require './input_url.coffee' +Text = React.createFactory components.Text + +module.exports = React.createClass + displayName: 'Paragraph' + + getInitialState: -> + editorState: EditorState.createEmpty( + new CompositeDecorator Config.decorators(@hasLinks()) + ) + focus: false + showUrlInput: false + showNav: false + urlValue: '' + selectionTarget: null + + componentDidMount: -> + if $(@props.html).text().length + html = Utils.standardizeSpacing @props.html + html = @stripLinebreaks(html) if @props.stripLinebreaks + blocksFromHTML = @convertFromHTML(html) + @setState + html: html + editorState: EditorState.createWithContent( + blocksFromHTML, + new CompositeDecorator Config.decorators(@hasLinks()) + ) + + hasLinks: -> + return true if @props.linked or @props.type in ['caption', 'postscript'] + + onChange: (editorState) -> + html = @convertToHtml editorState + @setState editorState: editorState, html: html + @props.onChange(html) + + focus: -> + @setState focus: true + @refs.editor.focus() + + onBlur: -> + @setState + focus: false + showNav: false + + convertFromHTML: (html) -> + html = @stripLinebreaks(html) if @props.stripLinebreaks + blocksFromHTML = convertFromHTML({ + htmlToEntity: (nodeName, node) -> + if nodeName is 'a' + data = {url: node.href} + return Entity.create( + 'LINK', + 'MUTABLE', + data + ) + })(html) + return blocksFromHTML + + convertToHtml: (editorState) -> + html = convertToHTML({ + entityToHTML: (entity, originalText) -> + if entity.type is 'LINK' + return a { href: entity.data.url} + return originalText + })(editorState.getCurrentContent()) + html = Utils.standardizeSpacing html + html = if html is '

' then '' else html + return html + + availableBlocks: -> + blockMap = Config.blockRenderMap() + available = Object.keys(blockMap.toObject()) + return Array.from(available) + + handleKeyCommand: (e) -> + return 'handled' if @props.stripLinebreaks is true and e is 'split-block' + if e is 'link-prompt' + @promptForLink() if @hasLinks() + return 'handled' + if e in ['bold', 'italic'] + return 'handled' if @props.postscript and e is 'italic' + return 'handled' if @props.caption and e is 'bold' + newState = RichUtils.handleKeyCommand @state.editorState, e + @onChange newState if newState + return 'not-handled' + + toggleInlineStyle: (inlineStyle) -> + selection = Utils.getSelectionDetails(@state.editorState) + @onChange RichUtils.toggleInlineStyle(@state.editorState, inlineStyle) + + + stripLinebreaks: (html) -> + html = html.replace(/<\/p>

/g, '') + return html + + onPaste: (text, html) -> + { editorState } = @state + unless html + html = '

' + text + '
' + html = Utils.standardizeSpacing html + html = Utils.stripGoogleStyles html + html = @stripLinebreaks(html) if @props.stripLinebreaks + html = html.replace(/<\/p>

/g, '') + blocksFromHTML = @convertFromHTML html + convertedHtml = blocksFromHTML.getBlocksAsArray().map (contentBlock) => + unstyled = Utils.stripCharacterStyles contentBlock, true + unless unstyled.getType() in @availableBlocks() or unstyled.getType() is 'LINK' + unstyled = unstyled.set 'type', 'unstyled' + return unstyled + blockMap = ContentState.createFromBlockArray(convertedHtml, blocksFromHTML.getBlocksAsArray()).blockMap + newState = Modifier.replaceWithFragment( + editorState.getCurrentContent() + editorState.getSelection() + blockMap + ) + newState = EditorState.push(editorState, newState, 'insert-fragment') + @onChange newState + return true + + promptForLink: (e) -> + { editorState } = @state + e.preventDefault() if e + selection = editorState.getSelection() + selectionTarget = {top: 0, left: 0} + url = '' + if !selection.isCollapsed() + location = Utils.getSelectionLocation $(ReactDOM.findDOMNode(@refs.editor)).offset() + selectionTarget = Utils.stickyControlsBox(location, 25, 200) + contentState = editorState.getCurrentContent() + startKey = selection.getStartKey() + startOffset = selection.getStartOffset() + blockWithLinkAtBeginning = contentState.getBlockForKey(startKey) + linkKey = blockWithLinkAtBeginning.getEntityAt(startOffset) + if linkKey + linkInstance = contentState.getEntity(linkKey) + url = linkInstance.getData().url + @setState + showUrlInput: true + showNav: false + urlValue: url + selectionTarget: selectionTarget + + confirmLink: (url) -> + { editorState } = @state + contentState = editorState.getCurrentContent() + contentStateWithEntity = contentState.createEntity( + 'LINK' + 'MUTABLE' + {url: url} + ) + entityKey = contentStateWithEntity.getLastCreatedEntityKey() + newEditorState = EditorState.set editorState, { currentContent: contentStateWithEntity } + @setState({ + showUrlInput: false + showNav: false + urlValue: '' + selectionTarget: null + }) + @onChange RichUtils.toggleLink( + newEditorState + newEditorState.getSelection() + entityKey + ) + + removeLink: (e) -> + e.preventDefault() + { editorState } = @state + selection = editorState.getSelection() + if !selection.isCollapsed() + @setState({ + showUrlInput: false + urlValue: '' + editorState: RichUtils.toggleLink(editorState, selection, null) + }) + + printUrlInput: -> + if @state.showUrlInput + InputUrl { + selectionTarget: @state.selectionTarget + removeLink: @removeLink + confirmLink: @confirmLink + urlValue: @state.urlValue + } + + checkSelection: -> + if !window.getSelection().isCollapsed + location = Utils.getSelectionLocation $(ReactDOM.findDOMNode(@refs.editor)).offset() + selectionTargetL = Config.inlineStyles(@props.type).length * 25 + selectionTargetL = selectionTargetL + 25 if @hasLinks() + @setState showNav: true, selectionTarget: Utils.stickyControlsBox(location, -43, selectionTargetL) + else + @setState showNav: false + + render: -> + Text { + layout: @props.layout + postscript: @props.type is 'postscript' + }, + if @state.showNav + Nav { + styles: Config.inlineStyles(@props.type) + toggleStyle: @toggleInlineStyle + promptForLink: @promptForLink if @hasLinks() + position: @state.selectionTarget + } + div { + className: 'rich-text--paragraph' + onClick: @focus + onBlur: @onBlur + onMouseUp: @checkSelection + onKeyUp: @checkSelection + }, + editor { + ref: 'editor' + placeholder: @props.placeholder + editorState: @state.editorState + spellCheck: true + onChange: @onChange + blockRenderMap: Config.blockRenderMap() + handleReturn: @handleReturn + handleKeyCommand: @handleKeyCommand + keyBindingFn: Utils.keyBindingFnCaption + handlePastedText: @onPaste + } + @printUrlInput() diff --git a/client/components/rich_text2/index.styl b/client/components/rich_text2/index.styl index 8214e4872..e4c90d7e8 100644 --- a/client/components/rich_text2/index.styl +++ b/client/components/rich_text2/index.styl @@ -81,6 +81,8 @@ border none border-right 1px solid gray-darkest-color transition color .15s + &:last-child + border-right none &:hover color gray-color &[name='ITALIC'], diff --git a/client/components/rich_text2/test/input_paragraph.test.coffee b/client/components/rich_text2/test/input_paragraph.test.coffee deleted file mode 100644 index 7cb8b753b..000000000 --- a/client/components/rich_text2/test/input_paragraph.test.coffee +++ /dev/null @@ -1,96 +0,0 @@ -benv = require 'benv' -{ resolve } = require 'path' -sinon = require 'sinon' - -# FIXME: Invariant Violation: dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering. -describe.skip 'RichTextParagraph', -> - - beforeEach (done) -> - benv.setup => - benv.expose - $: benv.require 'jquery' - React: require 'react' - ReactDOM: require 'react-dom' - ReactTestUtils: require 'react-addons-test-utils' - ReactDOMServer: require 'react-dom/server' - Draft: require 'draft-js' - window.jQuery = $ - @r = - find: ReactTestUtils.findRenderedDOMComponentWithClass - simulate: ReactTestUtils.Simulate - @d = - EditorState: Draft.EditorState - global.HTMLElement = () => {} - global.HTMLAnchorElement = () => {} - @RichTextParagraph = benv.require resolve __dirname, '../components/input_paragraph' - @props = { - text: '

Here is the lead paragraph for this article.

' - placeholder: 'Lead paragraph (optional)' - onChange: sinon.stub() - } - @rendered = ReactDOMServer.renderToString React.createElement(@RichTextParagraph, @props) - - @component = ReactDOM.render React.createElement(@RichTextParagraph, @props), (@$el = $ "
")[0], => setTimeout => - @component.state.editorState.getSelection().isCollapsed = sinon.stub().returns false - selection = @component.state.editorState.getSelection() - newSelection = selection.merge({ - anchorKey: @component.state.editorState.getCurrentContent().getFirstBlock().key - anchorOffset: 0 - focusKey: @component.state.editorState.getCurrentContent().getFirstBlock().key - focusOffset: 7 - }) - newEditorState = @d.EditorState.acceptSelection(@component.state.editorState, newSelection) - @component.onChange newEditorState - done() - - afterEach -> - benv.teardown() - - it 'Shows a placeholder if provided and empty', -> - $(@rendered).text().should.eql 'Lead paragraph (optional)' - - it 'Renders an existing lead paragraph', -> - $(ReactDOM.findDOMNode(@component)).text().should.eql 'Here is the lead paragraph for this article.' - @component.state.html.should.eql '

Here is  the lead paragraph for  this article.

' - - it 'Can toggle bold styles by default', -> - @component.handleKeyCommand('bold') - @component.state.html.should.eql '

Here is  the lead paragraph for  this article.

' - - it 'Can toggle italic styles by default', -> - @component.handleKeyCommand('italic') - @component.state.html.should.eql '

Here is  the lead paragraph for  this article.

' - - it 'Ignores unsuppored styles', -> - @component.handleKeyCommand('underline') - @component.state.html.should.eql '

Here is  the lead paragraph for  this article.

' - - it 'Can override default styles via props.styleMap', -> - @props.styleMap = ['bold'] - @props.text = '

Here is the a paragraph for this article.

' - component = ReactDOM.render React.createElement(@RichTextParagraph, @props), (@$el = $ "
")[0] - component.state.editorState.getSelection().isCollapsed = sinon.stub().returns false - selection = component.state.editorState.getSelection() - newSelection = selection.merge({ - anchorKey: component.state.editorState.getCurrentContent().getFirstBlock().key - anchorOffset: 0 - focusKey: component.state.editorState.getCurrentContent().getFirstBlock().key - focusOffset: 7 - }) - newEditorState = @d.EditorState.acceptSelection(component.state.editorState, newSelection) - component.onChange newEditorState - - component.handleKeyCommand('italic') - component.state.html.should.eql '

Here is the a paragraph for this article.

' - - component.handleKeyCommand('bold') - component.state.html.should.eql '

Here is the a paragraph for this article.

' - - it 'Strips unsuported html out of pasted text', -> - @component.onPaste 'Available at: Espacio Valverde Galleries Sector, Booth 9F01', '

Available at: Espacio Valverde • Galleries Sector, Booth 9F01

' - @component.state.html.should.eql '

Available at: Espacio Valverde • Galleries Sector, Booth 9F01  the lead paragraph for  this article.

' - - it 'Sends converted html to parent onChange', -> - @component.onChange @component.state.editorState - @component.props.onChange.called.should.eql true - @component.props.onChange.args[0][0].should.eql '

Here is  the lead paragraph for  this article.

' diff --git a/client/components/rich_text2/test/edit_nav.test.coffee b/client/components/rich_text2/test/nav.test.coffee similarity index 89% rename from client/components/rich_text2/test/edit_nav.test.coffee rename to client/components/rich_text2/test/nav.test.coffee index 4913d34e9..0766c8b79 100644 --- a/client/components/rich_text2/test/edit_nav.test.coffee +++ b/client/components/rich_text2/test/nav.test.coffee @@ -13,14 +13,14 @@ r = { blockTypes, inlineStyles } = require '../../../apps/edit/components/content2/sections/text/draft_config.coffee' -describe 'RichText: EditNav', -> +describe 'RichText: Nav', -> describe 'Classic: partner', -> beforeEach (done) -> benv.setup => benv.expose $: benv.require 'jquery' - @EditNav = benv.requireWithJadeify( - resolve(__dirname, '../components/edit_nav'), ['icons'] + @Nav = benv.requireWithJadeify( + resolve(__dirname, '../components/nav'), ['icons'] ) @props = { hasFeatures: false @@ -32,7 +32,7 @@ describe 'RichText: EditNav', -> makePlainText: @makePlainText = sinon.stub() position: { top: 20, left: 20 } } - @component = ReactDOM.render React.createElement(@EditNav, @props), (@$el = $ "
")[0], => setTimeout => + @component = ReactDOM.render React.createElement(@Nav, @props), (@$el = $ "
")[0], => setTimeout => done() afterEach -> @@ -81,8 +81,8 @@ describe 'RichText: EditNav', -> beforeEach (done) -> benv.setup => benv.expose $: benv.require 'jquery' - @EditNav = benv.requireWithJadeify( - resolve(__dirname, '../components/edit_nav'), ['icons'] + @Nav = benv.requireWithJadeify( + resolve(__dirname, '../components/nav'), ['icons'] ) @props = { hasFeatures: true @@ -94,7 +94,7 @@ describe 'RichText: EditNav', -> makePlainText: @makePlainText = sinon.stub() position: { top: 20, left: 20 } } - @component = ReactDOM.render React.createElement(@EditNav, @props), (@$el = $ "
")[0], => setTimeout => + @component = ReactDOM.render React.createElement(@Nav, @props), (@$el = $ "
")[0], => setTimeout => done() afterEach -> @@ -128,8 +128,8 @@ describe 'RichText: EditNav', -> beforeEach (done) -> benv.setup => benv.expose $: benv.require 'jquery' - @EditNav = benv.requireWithJadeify( - resolve(__dirname, '../components/edit_nav'), ['icons'] + @Nav = benv.requireWithJadeify( + resolve(__dirname, '../components/nav'), ['icons'] ) @props = { hasFeatures: true @@ -141,7 +141,7 @@ describe 'RichText: EditNav', -> makePlainText: @makePlainText = sinon.stub() position: { top: 20, left: 20 } } - @component = ReactDOM.render React.createElement(@EditNav, @props), (@$el = $ "
")[0], => setTimeout => + @component = ReactDOM.render React.createElement(@Nav, @props), (@$el = $ "
")[0], => setTimeout => done() afterEach -> @@ -176,8 +176,8 @@ describe 'RichText: EditNav', -> beforeEach (done) -> benv.setup => benv.expose $: benv.require 'jquery' - @EditNav = benv.requireWithJadeify( - resolve(__dirname, '../components/edit_nav'), ['icons'] + @Nav = benv.requireWithJadeify( + resolve(__dirname, '../components/nav'), ['icons'] ) @props = { hasFeatures: true @@ -189,7 +189,7 @@ describe 'RichText: EditNav', -> makePlainText: @makePlainText = sinon.stub() position: { top: 20, left: 20 } } - @component = ReactDOM.render React.createElement(@EditNav, @props), (@$el = $ "
")[0], => setTimeout => + @component = ReactDOM.render React.createElement(@Nav, @props), (@$el = $ "
")[0], => setTimeout => done() afterEach -> diff --git a/client/components/rich_text2/test/paragraph.test.coffee b/client/components/rich_text2/test/paragraph.test.coffee new file mode 100644 index 000000000..528e2c754 --- /dev/null +++ b/client/components/rich_text2/test/paragraph.test.coffee @@ -0,0 +1,215 @@ +benv = require 'benv' +{ resolve } = require 'path' +sinon = require 'sinon' +React = require 'react' +ReactDOM = require 'react-dom' +ReactTestUtils = require 'react-addons-test-utils' +ReactDOMServer = require 'react-dom/server' +Draft = require 'draft-js' +{ EditorState, Modifier } = require 'draft-js' + +r = + find: ReactTestUtils.findRenderedDOMComponentWithClass + simulate: ReactTestUtils.Simulate + +describe 'Rich Text: Paragraph', -> + + beforeEach (done) -> + benv.setup => + benv.expose + $: benv.require 'jquery' + window.jQuery = $ + global.Node = () => {} + global.HTMLElement = () => {} + global.HTMLAnchorElement = () => {} + window.getSelection = sinon.stub().returns( + isCollapsed: false + getRangeAt: sinon.stub().returns( + getClientRects: sinon.stub.returns([{ + bottom: 170 + height: 25 + left: 425 + right: 525 + top: 145 + width: 95 + }]) + ) + ) + @Paragraph = benv.require resolve __dirname, '../components/paragraph' + @Paragraph.__set__ 'Modifier', Modifier + @Paragraph.__set__ 'EditorState', EditorState + @Utils = benv.require resolve __dirname, '../utils' + @Paragraph.__set__ 'Utils', @Utils + Config = require '../utils/config.coffee' + @Paragraph.__set__ 'Config', Config + Nav = benv.requireWithJadeify( + resolve(__dirname, '../components/nav'), ['icons'] + ) + @Paragraph.__set__ 'Nav', React.createFactory Nav + InputUrl = benv.requireWithJadeify( + resolve(__dirname, '../components/input_url'), ['icons'] + ) + @Paragraph.__set__ 'InputUrl', React.createFactory InputUrl + @Paragraph.__set__ 'Utils.stickyControlsBox', sinon.stub().returns {top: 20, left: 40} + @Paragraph.__set__ 'Utils.getSelectionLocation', sinon.stub().returns({top: 40, left: 20}) + @Paragraph.__set__ 'Utils.stripGoogleStyles', @stripGoogleStyles = sinon.stub().returns('

hello

here again.

') + @leadParagraph = '

Here is the lead paragraph for this article.

' + @postscript = '

Illustration by Tomi Um.

' + @props = { + html: @postscript + placeholder: 'Postscript (optional)' + onChange: sinon.stub() + linked: true + } + @component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => setTimeout => + @component.stickyControlsBox = sinon.stub().returns {top: 20, left: 40} + @component.state.editorState.getSelection().isCollapsed = sinon.stub().returns false + selection = @component.state.editorState.getSelection() + newSelection = selection.merge({ + anchorKey: @component.state.editorState.getCurrentContent().getFirstBlock().key + anchorOffset: 0 + focusKey: @component.state.editorState.getCurrentContent().getFirstBlock().key + focusOffset: 12 + }) + newEditorState = EditorState.acceptSelection(@component.state.editorState, newSelection) + @component.onChange newEditorState + done() + + afterEach -> + benv.teardown() + + describe 'Render', -> + + it 'Shows a placeholder if provided and empty', -> + component = ReactDOMServer.renderToString React.createElement(@Paragraph, @props) + $(component).text().should.containEql 'Postscript (optional)' + + it 'Renders existing html', -> + $(ReactDOM.findDOMNode(@component)).text().should.containEql 'Illustration by Tomi Um.' + + it 'Renders existing link entities', -> + $(ReactDOM.findDOMNode(@component)).html().should.containEql '' + + describe 'Key commands', -> + + it 'Can toggle bold styles', -> + @component.setState = sinon.stub() + @component.handleKeyCommand('bold') + @component.setState.args[0][0].html.should.containEql 'Illustration' + + it 'Can toggle italic styles', -> + @component.setState = sinon.stub() + @component.handleKeyCommand('italic') + @component.setState.args[0][0].html.should.containEql 'Illustration' + + it 'Can toggle a link prompt', -> + @component.setState = sinon.stub() + @component.handleKeyCommand('link-prompt') + @component.setState.args[0][0].selectionTarget.should.eql { top: 20, left: 40 } + @component.setState.args[0][0].showUrlInput.should.eql true + + describe 'Nav', -> + + it 'Prints Italic and Bold buttons by default', -> + @props.linked = null + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + component.setState showNav: true + $(ReactDOM.findDOMNode(component)).html().should.containEql '' + $(ReactDOM.findDOMNode(component)).html().should.not.containEql '' + + it 'Does not show bold if type is caption', -> + @props.linked = null + @props.type = 'caption' + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + component.setState showNav: true + $(ReactDOM.findDOMNode(component)).html().should.containEql '' + + it 'Can toggle bold styles', -> + @component.setState showNav: true + @component.setState = sinon.stub() + r.simulate.mouseDown r.find @component, 'BOLD' + @component.setState.args[0][0].html.should.containEql 'Illustration' + + it 'Can toggle italic styles', -> + @component.setState showNav: true + @component.setState = sinon.stub() + r.simulate.mouseDown r.find @component, 'ITALIC' + @component.setState.args[0][0].html.should.containEql 'Illustration' + + it 'Can toggle a link prompt', -> + @component.setState showNav: true + @component.setState = sinon.stub() + r.simulate.mouseDown r.find @component, 'link' + @component.setState.args[0][0].selectionTarget.should.eql { top: 20, left: 40 } + @component.setState.args[0][0].showUrlInput.should.eql true + + describe 'Links', -> + + it '#hasLinks returns true if props.linked', -> + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + haslinks = component.hasLinks() + haslinks.should.eql true + + it '#hasLinks returns true if type is postscript', -> + @props.type = 'postscript' + @props.linked = null + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + haslinks = component.hasLinks() + haslinks.should.eql true + + it '#hasLinks returns true if type is caption', -> + @props.type = 'caption' + @props.linked = null + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + haslinks = component.hasLinks() + haslinks.should.eql true + + it '#confirmLink can save a link as html', -> + @component.confirmLink('http://artsy.net') + (@component.state.html.match(/
+ + it 'allows linebreaks by default', -> + @props.html = '

Here one paragraph.

Here is second paragraph

' + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + $(ReactDOM.findDOMNode(component)).find('p').length.should.eql 2 + + it 'strips linebreaks if props.stripLinebreaks', -> + @props.stripLinebreaks = true + @props.html = '

Here one paragraph.

Here is second paragraph

' + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + $(ReactDOM.findDOMNode(component)).find('p').length.should.eql 1 + + it 'interrupts key command for linebreak if props.stripLinebreaks', -> + @props.stripLinebreaks = true + @props.html = '

Here one paragraph.

Here is second paragraph

' + component = ReactDOM.render React.createElement(@Paragraph, @props), (@$el = $ "
")[0], => + keyResponse = component.handleKeyCommand('split-block') + keyResponse.should.eql 'handled' + + describe '#onPaste', -> + + it 'calls stripGoogleStyles', -> + @component.onChange = sinon.stub() + @component.onPaste('hello here again.', '

hello

here again.

') + @stripGoogleStyles.called.should.eql true + + it 'calls standardizeSpacing', -> + @Utils.standardizeSpacing = sinon.stub() + @component.onChange = sinon.stub() + @component.onPaste('hello here again.', '

hello

here again.

') + @Utils.standardizeSpacing.called.should.eql true diff --git a/client/components/rich_text2/utils/config.coffee b/client/components/rich_text2/utils/config.coffee new file mode 100644 index 000000000..7223111f0 --- /dev/null +++ b/client/components/rich_text2/utils/config.coffee @@ -0,0 +1,25 @@ +Immutable = require 'immutable' +Decorators = require './decorators.coffee' + +exports.blockRenderMap = -> + return Immutable.Map({ + 'unstyled': {element: 'p'} + }) + +exports.inlineStyles = (type) -> + # for menu display only + styles = [ ] + if type isnt 'postscript' + styles.push({label: 'I', name: 'ITALIC'}) + if type isnt 'caption' + styles.push({label: 'B', name: 'BOLD'}) + return styles + +exports.decorators = (linked) -> + decorators = [] + if linked + decorators.push({ + strategy: Decorators.findLinkEntities + component: Decorators.Link + }) + return decorators \ No newline at end of file diff --git a/package.json b/package.json index ce1d740f5..24e16417c 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,8 @@ "deploy": "sh scripts/deploy.sh" }, "dependencies": { + "@artsy/reaction-force": "^0.3.2", "@artsy/express-reloadable": "^1.0.2", - "@artsy/reaction-force": "^0.1.49", "airtable": "^0.4.5", "artsy-backbone-mixins": "git://github.com/artsy/artsy-backbone-mixins.git", "artsy-ezel-components": "git://github.com/artsy/artsy-ezel-components.git", diff --git a/yarn.lock b/yarn.lock index 95ffc1921..2aca27a5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,12 +8,12 @@ dependencies: chokidar "^1.7.0" -"@artsy/reaction-force@^0.1.49": - version "0.1.49" - resolved "https://registry.yarnpkg.com/@artsy/reaction-force/-/reaction-force-0.1.49.tgz#3899011c56a37b9fdeb92e06532ddc40d3fb4a8d" +"@artsy/reaction-force@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@artsy/reaction-force/-/reaction-force-0.3.2.tgz#aa3fee9c1bc57b76dcdfadeecf8e169d7bbfe46e" dependencies: - "@storybook/addon-options" "^3.1.2" - "@storybook/react" "^3.1.3" + "@storybook/addon-options" "^3.2.1" + "@storybook/react" "^3.2.0" artsy-passport "^2.0.3" artsy-xapp "^1.0.4" babel-polyfill "^6.23.0" @@ -26,9 +26,11 @@ isomorphic-fetch "^2.2.1" isomorphic-relay "^0.7.4" lodash "^4.17.4" + moment-timezone "^0.5.13" numeral "^2.0.4" prop-types "^15.5.10" react "^15.5.4" + react-markdown "^2.5.0" react-relay "https://github.com/alloy/relay/releases/download/v0.9.3/react-relay-0.9.3.tgz" react-sizeme "^2.3.2" react-styled-flexboxgrid "^2.0.0" @@ -45,44 +47,44 @@ component-type "^1.2.1" join-component "^1.1.0" -"@storybook/addon-actions@^3.1.6": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-3.1.6.tgz#0cbf00ede57ff00d1dfe02e554043d6963940064" +"@storybook/addon-actions@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-3.2.0.tgz#e5d7f63fec89cae1b98bbc124694153b7409317f" dependencies: - "@storybook/addons" "^3.1.6" + "@storybook/addons" "^3.2.0" deep-equal "^1.0.1" json-stringify-safe "^5.0.1" - prop-types "^15.5.8" - react-inspector "^2.0.0" + prop-types "^15.5.10" + react-inspector "^2.1.1" uuid "^3.1.0" -"@storybook/addon-links@^3.1.6": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-3.1.6.tgz#62c8a839e54ff0adb04c6023dae467b336ced5d9" +"@storybook/addon-links@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-3.2.0.tgz#28c73d1fd7fa37591139f3fb16e60a43113ad643" dependencies: - "@storybook/addons" "^3.1.6" + "@storybook/addons" "^3.2.0" -"@storybook/addon-options@^3.1.2": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/addon-options/-/addon-options-3.1.6.tgz#0cf3a24e075f4802fda42a13a2199646b0e2303d" +"@storybook/addon-options@^3.2.1": + version "3.2.4" + resolved "https://registry.yarnpkg.com/@storybook/addon-options/-/addon-options-3.2.4.tgz#4bf7de5a6b1ec3e9f901136385b9fbbd40d1ae7f" dependencies: - "@storybook/addons" "^3.1.6" + "@storybook/addons" "^3.2.0" -"@storybook/addons@^3.1.6": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-3.1.6.tgz#29ef2348550f5a74d5e83dd75d04714cac751c39" +"@storybook/addons@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-3.2.0.tgz#e1446cc5613af179701673276267cee71859bf41" -"@storybook/channel-postmessage@^3.1.6": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-3.1.6.tgz#867768a2ca2efbd796432300fe5e9b834d9c2ca5" +"@storybook/channel-postmessage@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-3.2.0.tgz#612ff53120bf266660cb9328bac9ad671228a2f7" dependencies: - "@storybook/channels" "^3.1.6" + "@storybook/channels" "^3.2.0" global "^4.3.2" json-stringify-safe "^5.0.1" -"@storybook/channels@^3.1.6": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-3.1.6.tgz#81d61591bf7613dd2bcd81d26da40aeaa2899034" +"@storybook/channels@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-3.2.0.tgz#d75395212db76b49e3335f50cce5bc763cf0b5c6" "@storybook/react-fuzzy@^0.4.0": version "0.4.0" @@ -93,20 +95,20 @@ fuse.js "^3.0.1" prop-types "^15.5.9" -"@storybook/react@^3.1.3": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-3.1.6.tgz#9393bb987ff08ee5f49c4557d12eb84377dee5d2" +"@storybook/react@^3.2.0": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-3.2.5.tgz#fd56815fe0fb521bd47051c650b6dce024ff7301" dependencies: - "@storybook/addon-actions" "^3.1.6" - "@storybook/addon-links" "^3.1.6" - "@storybook/addons" "^3.1.6" - "@storybook/channel-postmessage" "^3.1.6" - "@storybook/ui" "^3.1.6" + "@storybook/addon-actions" "^3.2.0" + "@storybook/addon-links" "^3.2.0" + "@storybook/addons" "^3.2.0" + "@storybook/channel-postmessage" "^3.2.0" + "@storybook/ui" "^3.2.5" airbnb-js-shims "^1.1.1" autoprefixer "^7.1.1" - babel-core "^6.24.1" + babel-core "^6.25.0" babel-loader "^7.0.0" - babel-plugin-react-docgen "^1.5.0" + babel-plugin-react-docgen "^1.6.0" babel-preset-es2015 "^6.24.1" babel-preset-es2016 "^6.24.1" babel-preset-react "^6.24.1" @@ -114,7 +116,7 @@ babel-preset-stage-0 "^6.24.1" babel-runtime "^6.23.0" case-sensitive-paths-webpack-plugin "^2.0.0" - chalk "^1.1.3" + chalk "^2.0.1" commander "^2.9.0" common-tags "^1.4.0" configstore "^3.1.0" @@ -128,27 +130,28 @@ json-loader "^0.5.4" json-stringify-safe "^5.0.1" json5 "^0.5.1" + lodash.flattendeep "^4.4.0" lodash.pick "^4.4.0" postcss-flexbugs-fixes "^3.0.0" postcss-loader "^2.0.5" prop-types "^15.5.10" qs "^6.4.0" - react-modal "^1.7.7" + react-modal "^2.2.4" redux "^3.6.0" request "^2.81.0" serve-favicon "^2.4.3" - shelljs "^0.7.7" + shelljs "^0.7.8" style-loader "^0.17.0" url-loader "^0.5.8" util-deprecate "^1.0.2" - uuid "^3.0.1" - webpack "^2.5.1" + uuid "^3.1.0" + webpack "^2.5.1 || ^3.0.0" webpack-dev-middleware "^1.10.2" webpack-hot-middleware "^2.18.0" -"@storybook/ui@^3.1.6": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-3.1.6.tgz#5d47c6003a2d78c06ede43861089747d986d918e" +"@storybook/ui@^3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-3.2.5.tgz#9e8cfe14dd49d3bb42f4ea1a3be90411a47c14fc" dependencies: "@storybook/react-fuzzy" "^0.4.0" babel-runtime "^6.23.0" @@ -158,16 +161,19 @@ global "^4.3.2" json-stringify-safe "^5.0.1" keycode "^2.1.8" + lodash.debounce "4.0.8" lodash.pick "^4.4.0" lodash.sortby "^4.7.0" mantra-core "^1.7.0" podda "^1.2.2" - prop-types "^15.5.8" + prop-types "^15.5.10" qs "^6.4.0" - react-inspector "^2.0.0" + react-icons "^2.2.5" + react-inspector "^2.1.1" react-komposer "^2.0.0" - react-modal "^1.7.6" - react-split-pane "^0.1.63" + react-modal "^2.2.4" + react-split-pane "^0.1.65" + react-treebeard "^2.0.3" redux "^3.6.0" JSONStream@^1.0.3: @@ -262,10 +268,14 @@ airtable@^0.4.5: request "2.79.0" xhr "2.3.3" -ajv-keywords@^1.0.0, ajv-keywords@^1.1.1: +ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" +ajv-keywords@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0" + ajv@^4.7.0, ajv@^4.9.1: version "4.11.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" @@ -282,6 +292,15 @@ ajv@^5.0.0: json-schema-traverse "^0.3.0" json-stable-stringify "^1.0.1" +ajv@^5.1.5: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -336,6 +355,12 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" +ansi-styles@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + "antigravity@git://github.com/artsy/antigravity.git": version "0.1.3" resolved "git://github.com/artsy/antigravity.git#e6a20591a6be418facca1b4670db24f11208cfdd" @@ -390,6 +415,10 @@ array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" +array-find@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8" + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -832,9 +861,9 @@ babel-plugin-module-resolver@^2.7.1: glob "^7.1.1" resolve "^1.2.0" -babel-plugin-react-docgen@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-1.5.0.tgz#0339717ad51f4a5ce4349330b8266ea5a56f53b4" +babel-plugin-react-docgen@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-1.7.0.tgz#87e72d3d54b182a30706b740bb4d116f59aadc80" dependencies: babel-types "^6.24.1" lodash "4.x.x" @@ -1599,6 +1628,10 @@ boom@2.x.x: dependencies: hoek "2.x.x" +bowser@^1.0.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.7.2.tgz#b94cc6925ba6b5e07c421a58e601ce4611264572" + bowser@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.7.0.tgz#169de4018711f994242bff9a8009e77a1f35e003" @@ -1888,9 +1921,9 @@ camelcase@^1.0.1, camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" caniuse-api@^1.5.2: version "1.6.1" @@ -1928,6 +1961,10 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +chain-function@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc" + chalk@0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" @@ -1948,6 +1985,14 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + character-parser@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-1.2.1.tgz#c0dde4ab182713b919b970959a123ecc1a30fcd6" @@ -1962,7 +2007,7 @@ cheerio@^0.19.0: htmlparser2 "~3.8.1" lodash "^3.2.0" -chokidar@^1.0.0, chokidar@^1.0.1, chokidar@^1.4.3, chokidar@^1.6.1, chokidar@^1.7.0: +chokidar@^1.0.0, chokidar@^1.0.1, chokidar@^1.6.1, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -2080,7 +2125,7 @@ coffeeify@*, coffeeify@^1.0.0: convert-source-map "^1.1.2" through "^2.3.8" -color-convert@^1.3.0: +color-convert@^1.3.0, color-convert@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" dependencies: @@ -2165,6 +2210,24 @@ commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" +commonmark-react-renderer@^4.2.4: + version "4.3.3" + resolved "https://registry.yarnpkg.com/commonmark-react-renderer/-/commonmark-react-renderer-4.3.3.tgz#9c4bca138bc83287bae792ccf133738be9cbc6fa" + dependencies: + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.isplainobject "^4.0.6" + pascalcase "^0.1.1" + xss-filters "^1.2.6" + +commonmark@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/commonmark/-/commonmark-0.24.0.tgz#b80de0182c546355643aa15db12bfb282368278f" + dependencies: + entities "~ 1.1.1" + mdurl "~ 1.0.1" + string.prototype.repeat "^0.2.0" + component-emitter@^1.2.0, component-emitter@~1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -2372,7 +2435,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2: create-hash "^1.1.0" inherits "^2.0.1" -create-react-class@^15.5.2, create-react-class@^15.6.0: +create-react-class@^15.6.0: version "15.6.0" resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4" dependencies: @@ -2380,6 +2443,14 @@ create-react-class@^15.5.2, create-react-class@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -2791,6 +2862,10 @@ dom-converter@~0.1: dependencies: utila "~0.3" +dom-helpers@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a" + dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -2907,10 +2982,6 @@ electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.14: version "1.3.14" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.14.tgz#64af0f9efd3c3c6acd57d71f83b49ca7ee9c4b43" -element-class@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/element-class/-/element-class-0.2.2.tgz#9d3bbd0767f9013ef8e1c8ebe722c1402a60050e" - element-resize-detector@^1.1.12: version "1.1.12" resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.1.12.tgz#8b3fd6eedda17f9c00b360a0ea2df9927ae80ba2" @@ -2943,20 +3014,20 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" -enhanced-resolve@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.1.0.tgz#9f4b626f577245edcf4b2ad83d86e17f4f421dec" +enhanced-resolve@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" dependencies: graceful-fs "^4.1.2" memory-fs "^0.4.0" object-assign "^4.0.1" - tapable "^0.2.5" + tapable "^0.2.7" entities@1.0: version "1.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" -entities@~1.1.1: +"entities@~ 1.1.1", entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -3351,9 +3422,21 @@ evp_bytestokey@^1.0.0: dependencies: create-hash "^1.1.1" -exenv@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.0.tgz#3835f127abf075bfe082d0aed4484057c78e3c89" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exenv@^1.2.0, exenv@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" exit-hook@^1.0.0: version "1.1.1" @@ -3494,6 +3577,10 @@ fast-deep-equal@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-0.1.0.tgz#5c6f4599aba6b333ee3342e2ed978672f1001f8d" +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -3813,6 +3900,10 @@ get-stdin@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + getpass@^0.1.1: version "0.1.6" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" @@ -4163,7 +4254,7 @@ https-proxy-agent@^0.3.5: debug "2" extend "3" -hyphenate-style-name@^1.0.2: +hyphenate-style-name@^1.0.1, hyphenate-style-name@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" @@ -4228,6 +4319,10 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + indent-string@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-1.2.2.tgz#db99bcc583eb6abbb1e48dcbb1999a986041cb6b" @@ -4269,9 +4364,16 @@ inline-source-map@~0.6.0: dependencies: source-map "~0.5.3" -inline-style-prefixer@^3.0.2: - version "3.0.6" - resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.6.tgz#b27fe309b4168a31eaf38c8e8c60ab9e7c11731f" +inline-style-prefixer@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz#c153c7e88fd84fef5c602e95a8168b2770671fe7" + dependencies: + bowser "^1.0.0" + hyphenate-style-name "^1.0.1" + +inline-style-prefixer@^3.0.6: + version "3.0.7" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.7.tgz#0ccc92e5902fe6e0d28d975c4258443f880615f8" dependencies: bowser "^1.6.0" css-in-js-utils "^1.0.3" @@ -4498,7 +4600,7 @@ is-resolvable@^1.0.0: dependencies: tryit "^1.0.1" -is-stream@^1.0.1: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4516,10 +4618,6 @@ is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - isarray@0.0.1, isarray@~0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -4582,6 +4680,7 @@ jade@^1.11.0: jstransformer "0.0.2" mkdirp "~0.5.0" transformers "2.1.0" + uglify-js "^2.4.19" void-elements "~2.0.1" with "~4.0.0" @@ -4869,16 +4968,6 @@ lexical-scope@^1.2.0: dependencies: astw "^2.0.0" -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -4892,15 +4981,6 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@^0.2.16: - version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" - loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" @@ -4991,6 +5071,14 @@ lodash.create@3.1.1: lodash._basecreate "^3.0.0" lodash._isiterateecall "^3.0.0" +lodash.debounce@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + lodash.isarguments@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" @@ -5084,6 +5172,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3 dependencies: js-tokens "^3.0.0" +lru-cache@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lsmod@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lsmod/-/lsmod-1.0.0.tgz#9a00f76dca36eb23fa05350afe1b585d4299e64b" @@ -5122,10 +5217,20 @@ math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" +"mdurl@~ 1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -5199,6 +5304,10 @@ mime@*, mime@1.3.4, mime@1.3.x, mime@^1.2.11, mime@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -5283,7 +5392,13 @@ module-deps@^4.0.8: through2 "^2.0.0" xtend "^4.0.0" -moment@^2.10.6, moment@^2.11.1: +moment-timezone@^0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.13.tgz#99ce5c7d827262eb0f1f702044177f60745d7b90" + dependencies: + moment ">= 2.9.0" + +"moment@>= 2.9.0", moment@^2.10.6, moment@^2.11.1: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" @@ -5509,6 +5624,12 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + npmlog@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" @@ -5686,11 +5807,13 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" dependencies: + execa "^0.7.0" lcid "^1.0.0" + mem "^1.1.0" os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" @@ -5717,6 +5840,10 @@ output-file-sync@^1.1.0: mkdirp "^0.5.1" object-assign "^4.1.0" +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + p-limit@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" @@ -5787,6 +5914,10 @@ parseurl@~1.3.1: dependencies: tape "^4.5.1" +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + passport-facebook@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/passport-facebook/-/passport-facebook-2.1.1.tgz#c39d0b52ae4d59163245a4e21a7b9b6321303311" @@ -5868,6 +5999,10 @@ path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" @@ -5880,14 +6015,6 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -6323,7 +6450,13 @@ prop-by-string@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prop-by-string/-/prop-by-string-1.0.1.tgz#a3768a9412de26bbcf982eb19fb8d5ecf573101a" -prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.5.9: +prop-types@15.5.8: + version "15.5.8" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394" + dependencies: + fbjs "^0.8.9" + +prop-types@^15.5.1, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.5.9: version "15.5.10" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154" dependencies: @@ -6354,6 +6487,10 @@ ps-tree@0.0.x: dependencies: event-stream "~0.5" +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + public-encrypt@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" @@ -6419,6 +6556,15 @@ querystringify@0.0.x: version "0.0.4" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" +radium@^0.19.0: + version "0.19.4" + resolved "https://registry.yarnpkg.com/radium/-/radium-0.19.4.tgz#56aa49fde6181d2f5e1fa57b4710ffd0c23de820" + dependencies: + array-find "^1.0.0" + exenv "^1.2.1" + inline-style-prefixer "^2.0.5" + prop-types "^15.5.8" + random-bytes@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" @@ -6514,9 +6660,21 @@ react-html-attributes@^1.3.0: dependencies: html-element-attributes "^1.0.0" -react-inspector@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-2.0.0.tgz#c945932f2c2bf2fab7873c6e07d83881404b9313" +react-icon-base@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/react-icon-base/-/react-icon-base-2.0.7.tgz#0bd18736bd6ce79ca6d69ce8387a07fb8d4ceffe" + dependencies: + prop-types "15.5.8" + +react-icons@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-2.2.5.tgz#f942501c21a4cc0456ce2bbee5032c93f6051dcf" + dependencies: + react-icon-base "2.0.7" + +react-inspector@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-2.1.4.tgz#2123fab74f68ae3136fbd02392fadb764326d04d" dependencies: babel-runtime "^6.23.0" is-dom "^1.0.9" @@ -6541,15 +6699,21 @@ react-komposer@^2.0.0: react-stubber "^1.0.0" shallowequal "^0.2.2" -react-modal@^1.7.6, react-modal@^1.7.7: - version "1.9.7" - resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-1.9.7.tgz#07ef56790b953e3b98ef1e2989e347983c72871d" +react-markdown@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-2.5.0.tgz#b1c61904fee5895886803bd9df7db23c3dc3a89e" dependencies: - create-react-class "^15.5.2" - element-class "^0.2.0" - exenv "1.2.0" - lodash.assign "^4.2.0" - prop-types "^15.5.7" + commonmark "^0.24.0" + commonmark-react-renderer "^4.2.4" + in-publish "^2.0.0" + prop-types "^15.5.1" + +react-modal@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-2.2.4.tgz#a32483c3555bd7677f09bca65d82f51da3abcbc0" + dependencies: + exenv "^1.2.0" + prop-types "^15.5.10" react-dom-factories "^1.0.0" "react-relay@https://github.com/alloy/relay/releases/download/v0.9.3/react-relay-0.9.3.tgz": @@ -6575,12 +6739,12 @@ react-sizeme@^2.3.2: invariant "^2.2.2" lodash "^4.17.4" -react-split-pane@^0.1.63: - version "0.1.63" - resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.63.tgz#fadb3960cc659911dd05ffbc88acee4be9f53583" +react-split-pane@^0.1.65: + version "0.1.66" + resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.66.tgz#369085dd07ec1237bda123e73813dcc7dc6502c1" dependencies: - inline-style-prefixer "^3.0.2" - prop-types "^15.5.8" + inline-style-prefixer "^3.0.6" + prop-types "^15.5.10" react-style-proptype "^3.0.0" react-static-container@^1.0.1: @@ -6605,6 +6769,27 @@ react-styled-flexboxgrid@^2.0.0, react-styled-flexboxgrid@^2.0.3: dependencies: lodash.isinteger "^4.0.4" +react-transition-group@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.0.tgz#b51fc921b0c3835a7ef7c571c79fc82c73e9204f" + dependencies: + chain-function "^1.0.0" + dom-helpers "^3.2.0" + loose-envify "^1.3.1" + prop-types "^15.5.6" + warning "^3.0.0" + +react-treebeard@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/react-treebeard/-/react-treebeard-2.0.3.tgz#cd644209c1be2fe2be3ae4bca8350ed6abf293d6" + dependencies: + babel-runtime "^6.23.0" + deep-equal "^1.0.1" + prop-types "^15.5.8" + radium "^0.19.0" + shallowequal "^0.2.2" + velocity-react "^1.3.1" + react-url-query@^1.1.4: version "1.2.0" resolved "https://registry.yarnpkg.com/react-url-query/-/react-url-query-1.2.0.tgz#35e4985ec6172cab257ac6d0d33cd4051a4c8fe8" @@ -6637,13 +6822,6 @@ read-only-stream@^2.0.0: dependencies: readable-stream "^2.0.2" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -6651,14 +6829,6 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -7224,6 +7394,16 @@ shasum@^1.0.0: json-stable-stringify "~0.0.0" sha.js "~2.4.4" +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + shell-quote@^1.4.2, shell-quote@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" @@ -7233,7 +7413,7 @@ shell-quote@^1.4.2, shell-quote@^1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" -shelljs@^0.7.5, shelljs@^0.7.7: +shelljs@^0.7.5: version "0.7.7" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" dependencies: @@ -7241,6 +7421,14 @@ shelljs@^0.7.5, shelljs@^0.7.7: interpret "^1.0.0" rechoir "^0.6.2" +shelljs@^0.7.8: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + shellwords@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.0.tgz#66afd47b6a12932d9071cbfd98a52e785cd0ba14" @@ -7325,9 +7513,9 @@ source-list-map@^0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" -source-list-map@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1" +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" source-map-support@^0.4.2: version "0.4.15" @@ -7472,7 +7660,7 @@ string-template@~0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" -string-width@^1.0.1, string-width@^1.0.2: +string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" dependencies: @@ -7503,6 +7691,10 @@ string.prototype.padstart@^3.0.0: es-abstract "^1.4.3" function-bind "^1.0.2" +string.prototype.repeat@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf" + string.prototype.trim@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" @@ -7531,16 +7723,14 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + strip-json-comments@~0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-0.1.3.tgz#164c64e370a8a3cc00c9e01b539e569823f0ee54" @@ -7647,7 +7837,7 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.1.0, supports-color@^3.2.3: +supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: @@ -7659,6 +7849,12 @@ supports-color@^4.0.0: dependencies: has-flag "^2.0.0" +supports-color@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.1.tgz#65a4bb2631e90e02420dba5554c375a4754bb836" + dependencies: + has-flag "^2.0.0" + svg-tag-names@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/svg-tag-names/-/svg-tag-names-1.1.1.tgz#9641b29ef71025ee094c7043f7cdde7d99fbd50a" @@ -7704,9 +7900,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tapable@^0.2.5, tapable@~0.2.5: - version "0.2.6" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.6.tgz#206be8e188860b514425375e6f1ae89bfb01fd8d" +tapable@^0.2.7: + version "0.2.8" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" tape@^4.5.1: version "4.6.3" @@ -7909,7 +8105,7 @@ ua-parser@^0.3.5: dependencies: yamlparser ">=0.0.2" -uglify-js@2.x.x, uglify-js@^2.6.2, uglify-js@^2.8.27: +uglify-js@2.x.x, uglify-js@^2.4.19, uglify-js@^2.6.2, uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: @@ -7939,6 +8135,14 @@ uglifyify@^3.0.1: through "~2.3.4" uglify-js "2.x.x" +uglifyjs-webpack-plugin@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" + dependencies: + source-map "^0.5.6" + uglify-js "^2.8.29" + webpack-sources "^1.0.1" + uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -8097,6 +8301,19 @@ vary@^1, vary@~1.1.0, vary@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" +velocity-animate@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/velocity-animate/-/velocity-animate-1.5.0.tgz#fc8771d8dfe1136ff02a707e10fbb0957c4b030f" + +velocity-react@^1.3.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/velocity-react/-/velocity-react-1.3.3.tgz#d6d47276cfc8be2a75623879b20140ac58c1b82b" + dependencies: + lodash "^3.10.1" + prop-types "^15.5.8" + react-transition-group "^1.1.2" + velocity-animate "^1.4.0" + vendors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22" @@ -8135,12 +8352,12 @@ watchify@^3.9.0: through2 "^2.0.0" xtend "^4.0.0" -watchpack@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.3.1.tgz#7d8693907b28ce6013e7f3610aa2a1acf07dad87" +watchpack@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac" dependencies: async "^2.1.2" - chokidar "^1.4.3" + chokidar "^1.7.0" graceful-fs "^4.1.2" webidl-conversions@^2.0.0: @@ -8173,38 +8390,39 @@ webpack-hot-middleware@^2.18.0: querystring "^0.2.0" strip-ansi "^3.0.0" -webpack-sources@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" +webpack-sources@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.1.tgz#c7356436a4d13123be2e2426a05d1dad9cbe65cf" dependencies: - source-list-map "^1.1.1" + source-list-map "^2.0.0" source-map "~0.5.3" -webpack@^2.5.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.6.1.tgz#2e0457f0abb1ac5df3ab106c69c672f236785f07" +"webpack@^2.5.1 || ^3.0.0": + version "3.5.5" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.5.5.tgz#3226f09fc8b3e435ff781e7af34f82b68b26996c" dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" - ajv "^4.7.0" - ajv-keywords "^1.1.1" + ajv "^5.1.5" + ajv-keywords "^2.0.0" async "^2.1.2" - enhanced-resolve "^3.0.0" + enhanced-resolve "^3.4.0" + escope "^3.6.0" interpret "^1.0.0" json-loader "^0.5.4" json5 "^0.5.1" loader-runner "^2.3.0" - loader-utils "^0.2.16" + loader-utils "^1.1.0" memory-fs "~0.4.1" mkdirp "~0.5.0" node-libs-browser "^2.0.0" source-map "^0.5.3" - supports-color "^3.1.0" - tapable "~0.2.5" - uglify-js "^2.8.27" - watchpack "^1.3.1" - webpack-sources "^0.2.3" - yargs "^6.0.0" + supports-color "^4.2.1" + tapable "^0.2.7" + uglifyjs-webpack-plugin "^0.4.6" + watchpack "^1.4.0" + webpack-sources "^1.0.1" + yargs "^8.0.2" whatwg-encoding@^1.0.1: version "1.0.1" @@ -8233,11 +8451,11 @@ whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.2.12: +which@^1.2.12, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -8372,6 +8590,10 @@ xmldom@0.1.x: version "0.1.27" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" +xss-filters@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/xss-filters/-/xss-filters-1.2.7.tgz#59fa1de201f36f2f3470dcac5f58ccc2830b0a9a" + xss@^0.2.7: version "0.2.18" resolved "https://registry.yarnpkg.com/xss/-/xss-0.2.18.tgz#6df5fb5ca28bdc51e78624ff63f19e13ebd73bab" @@ -8393,6 +8615,10 @@ y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + yaml@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/yaml/-/yaml-0.2.3.tgz#b5450e92e76ef36b5dd24e3660091ebaeef3e5c7" @@ -8401,29 +8627,29 @@ yamlparser@>=0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/yamlparser/-/yamlparser-0.0.2.tgz#32393e6afc70c8ca066b6650ac6738b481678ebc" -yargs-parser@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" dependencies: - camelcase "^3.0.0" + camelcase "^4.1.0" -yargs@^6.0.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" +yargs@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" dependencies: - camelcase "^3.0.0" + camelcase "^4.1.0" cliui "^3.2.0" decamelize "^1.1.1" get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" require-directory "^2.1.1" require-main-filename "^1.0.1" set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" + string-width "^2.0.0" + which-module "^2.0.0" y18n "^3.2.1" - yargs-parser "^4.2.0" + yargs-parser "^7.0.0" yargs@~3.10.0: version "3.10.0"