File viewer v2 #1826

Merged
btzr-io merged 17 commits from fix-viewer into master 2018-08-06 03:53:57 +02:00
26 changed files with 961 additions and 165 deletions

View file

@ -8,13 +8,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
### Added
* Wallet Encryption/Decryption user flows ([#1785](https://github.com/lbryio/lbry-desktop/pull/1785))
* Add FAQ to Publishing Area ([#1833](https://github.com/lbryio/lbry-desktop/pull/1833))
* Better preview for content ([#620](https://github.com/lbryio/lbry-desktop/pull/620))
* Add new markdown and docx viewer ([#1826](https://github.com/lbryio/lbry-desktop/pull/1826))
* Add new viewer for human-readable text files ([#1826](https://github.com/lbryio/lbry-desktop/pull/1826))
* Add csv and json viewer ([#1410](https://github.com/lbryio/lbry-desktop/pull/1410))
### Changed
* Pass error message from spee.ch API during thumbnail upload ([#1840](https://github.com/lbryio/lbry-desktop/pull/1840))
* Use router pattern for rendering file viewer ([#1544](https://github.com/lbryio/lbry-desktop/pull/1544))
### Fixed
* **Wallet -> Get Credits** page now shows correct ShapeShift status when it's avialable ([#1836](https://github.com/lbryio/lbry-desktop/issue))
* **Wallet -> Get Credits** page now shows correct ShapeShift status when it's avialable ([#1836](https://github.com/lbryio/lbry-desktop/issues/1836))
* Fix middle click link error ([#1843](https://github.com/lbryio/lbry-desktop/issues/1843)}
* Problem with search auto-complete menu when scrolling over file viewer ([#1847](https://github.com/lbryio/lbry-desktop/issues/1847))
## [0.23.0] - 2018-07-25

View file

@ -35,7 +35,9 @@
},
"dependencies": {
"bluebird": "^3.5.1",
"breakdance": "^3.0.1",
"classnames": "^2.2.5",
"codemirror": "^5.39.2",
"country-data": "^0.0.31",
"dom-scroll-into-view": "^1.2.1",
"electron-dl": "^1.11.0",
@ -51,6 +53,7 @@
"keytar": "^4.2.1",
"lbry-redux": "lbryio/lbry-redux#b4fffe863df316bc73183567ab978221ee623b8c",
"localforage": "^1.7.1",
"mammoth": "^1.4.6",
"mime": "^2.3.1",
"mixpanel-browser": "^2.17.1",
"moment": "^2.22.0",

View file

@ -6,7 +6,7 @@ import MarkdownPreview from 'component/common/markdown-preview';
import SimpleMDE from 'react-simplemde-editor';
import 'simplemde/dist/simplemde.min.css'; // eslint-disable-line import/no-extraneous-dependencies
import Toggle from 'react-toggle';
import { openEditorMenu } from 'util/contextMenu';
import { openEditorMenu, stopContextMenu } from 'util/contextMenu';
type Props = {
name: string,
@ -57,15 +57,10 @@ export class FormField extends React.PureComponent<Props> {
</select>
);
} else if (type === 'markdown') {
const stopContextMenu = event => {
event.preventDefault();
event.stopPropagation();
};
const handleEvents = {
contextmenu(codeMirror, event) {
openEditorMenu(event, codeMirror);
},
contextmenu: openEditorMenu,
};
input = (
<div className="form-field--SimpleMDE" onContextMenu={stopContextMenu}>
<SimpleMDE

View file

@ -3,13 +3,18 @@ import React from 'react';
import LoadingScreen from 'component/common/loading-screen';
import PdfViewer from 'component/viewers/pdfViewer';
import ThreeViewer from 'component/viewers/threeViewer';
import DocumentViewer from 'component/viewers/documentViewer';
import DocxViewer from 'component/viewers/docxViewer';
import HtmlViewer from 'component/viewers/htmlViewer';
type Props = {
mediaType: string,
source: {
filePath: string,
fileName: string,
fileType: string,
downloadPath: string,
stream: opts => void,
blob: callback => void,
},
currentTheme: string,
};
@ -17,22 +22,36 @@ type Props = {
class FileRender extends React.PureComponent<Props> {
renderViewer() {
const { source, mediaType, currentTheme } = this.props;
const viewerProps = { source, theme: currentTheme };
// Extract relevant data to render file
const { blob, stream, fileName, fileType, contentType, downloadPath } = source;
// Human-readable files (scripts and plain-text files)
const readableFiles = ['text', 'document', 'script'];
// Supported mediaTypes
const mediaTypes = {
'3D-file': <ThreeViewer {...viewerProps} />,
'3D-file': <ThreeViewer source={{ fileType, downloadPath }} theme={currentTheme} />,
// Add routes to viewer...
};
// Supported fileType
const fileTypes = {
pdf: <PdfViewer {...viewerProps} />,
pdf: <PdfViewer source={downloadPath} />,
docx: <DocxViewer source={downloadPath} />,
html: <HtmlViewer source={downloadPath} />,
// Add routes to viewer...
};
const { fileType } = source;
const viewer = mediaType && source && (mediaTypes[mediaType] || fileTypes[fileType]);
// Check for a valid fileType or mediaType
let viewer = fileTypes[fileType] || mediaTypes[mediaType];
// Check for Human-readable files
if (!viewer && readableFiles.includes(mediaType)) {
viewer = <DocumentViewer source={{ stream, fileType, contentType }} theme={currentTheme} />;
}
// Message Error
const unsupportedMessage = __("Sorry, looks like we can't preview this file.");
const unsupported = <LoadingScreen status={unsupportedMessage} spinner={false} />;

View file

@ -9,9 +9,9 @@ import FileRender from 'component/fileRender';
import Thumbnail from 'component/common/thumbnail';
import LoadingScreen from 'component/common/loading-screen';
class VideoPlayer extends React.PureComponent {
class MediaPlayer extends React.PureComponent {
static MP3_CONTENT_TYPES = ['audio/mpeg3', 'audio/mpeg'];
static FILE_MEDIA_TYPES = ['e-book', 'comic-book', 'document', '3D-file'];
static FILE_MEDIA_TYPES = ['text', 'script', 'e-book', 'comic-book', 'document', '3D-file'];
constructor(props) {
super(props);
@ -54,7 +54,7 @@ class VideoPlayer extends React.PureComponent {
};
// use renderAudio override for mp3
if (VideoPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
if (MediaPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
this.renderAudio(container, null, false);
}
// Render custom viewer: FileRender
@ -105,7 +105,7 @@ class VideoPlayer extends React.PureComponent {
if (this.playableType() && !startedPlaying && downloadCompleted) {
const container = this.media.children[0];
if (VideoPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
if (MediaPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
this.renderAudio(this.media, true);
} else {
player.render(this.file(), container, {
@ -158,10 +158,10 @@ class VideoPlayer extends React.PureComponent {
}
file() {
const { downloadPath, filename } = this.props;
const { downloadPath, fileName } = this.props;
return {
name: filename,
name: fileName,
createReadStream: opts => fs.createReadStream(downloadPath, opts),
};
}
@ -183,27 +183,30 @@ class VideoPlayer extends React.PureComponent {
// This files are supported using a custom viewer
const { mediaType } = this.props;
return VideoPlayer.FILE_MEDIA_TYPES.indexOf(mediaType) > -1;
return MediaPlayer.FILE_MEDIA_TYPES.indexOf(mediaType) > -1;
}
renderFile() {
// This is what render-media does with unplayable files
const { filename, downloadPath, contentType, mediaType } = this.props;
const { fileName, downloadPath, contentType, mediaType } = this.props;
toBlobURL(fs.createReadStream(downloadPath), contentType, (err, url) => {
if (err) {
this.setState({ unsupported: true });
return false;
}
// File to render
const fileSource = {
downloadPath,
filePath: url,
fileType: path.extname(filename).substring(1),
};
// Update state
this.setState({ fileSource });
});
// File to render
const fileSource = {
fileName,
contentType,
downloadPath,
fileType: path.extname(fileName).substring(1),
};
// Readable stream from file
fileSource.stream = opts => fs.createReadStream(downloadPath, opts);
// Blob url from stream
fileSource.blob = callback =>
toBlobURL(fs.createReadStream(downloadPath), contentType, callback);
// Update state
this.setState({ fileSource });
}
renderAudio(container, autoplay) {
@ -284,5 +287,5 @@ class VideoPlayer extends React.PureComponent {
}
}
export default VideoPlayer;
export default MediaPlayer;
/* eslint-disable */

View file

@ -163,7 +163,7 @@ class FileViewer extends React.PureComponent<Props> {
</div>
) : (
<Player
filename={fileInfo.file_name}
fileName={fileInfo.file_name}
poster={poster}
downloadPath={fileInfo.download_path}
mediaType={mediaType}

View file

@ -0,0 +1,67 @@
// @flow
import React from 'react';
import CodeMirror from 'codemirror/lib/codemirror';
import { openSnippetMenu, stopContextMenu } from 'util/contextMenu';
// Addons
import 'codemirror/addon/selection/mark-selection';
// Syntax mode
import 'codemirror/mode/go/go';
import 'codemirror/mode/jsx/jsx';
import 'codemirror/mode/css/css';
import 'codemirror/mode/xml/xml';
import 'codemirror/mode/php/php';
import 'codemirror/mode/ruby/ruby';
import 'codemirror/mode/clike/clike';
import 'codemirror/mode/shell/shell';
import 'codemirror/mode/python/python';
import 'codemirror/mode/markdown/markdown';
import 'codemirror/mode/javascript/javascript';
type Props = {
theme: string,
value: string,
contentType: string,
};
class CodeViewer extends React.PureComponent<Props> {
constructor(props) {
super(props);
this.codeMirror = null;
this.textarea = React.createRef();
}
componentDidMount() {
const { theme, contentType } = this.props;
// Init CodeMirror
this.codeMirror = CodeMirror.fromTextArea(this.textarea.current, {
// Auto detect syntax with file contentType
mode: contentType,
// Adaptive theme
theme: theme === 'dark' ? 'one-dark' : 'default',
// Hide the cursor
readOnly: true,
// Styled text selection
styleSelectedText: true,
// Additional config opts
dragDrop: false,
lineNumbers: true,
lineWrapping: true,
});
// Add events
this.codeMirror.on('contextmenu', openSnippetMenu);
}
render() {
const { value } = this.props;
return (
<div className="code-viewer" onContextMenu={stopContextMenu}>
<textarea ref={this.textarea} disabled value={value} />
</div>
);
}
}
export default CodeViewer;

View file

@ -0,0 +1,79 @@
// @flow
import React from 'react';
import LoadingScreen from 'component/common/loading-screen';
import CodeViewer from 'component/viewers/codeViewer';
import MarkdownPreview from 'component/common/markdown-preview';
type Props = {
theme: string,
source: {
stream: opts => void,
fileType: string,
contentType: string,
},
};
class DocumentViewer extends React.PureComponent<Props> {
constructor(props) {
super(props);
this.state = {
error: null,
content: null,
loading: true,
};
}
componentDidMount() {
const { source } = this.props;
const stream = source.stream('utf8');
let data = '';
stream.on('data', chunk => {
data += chunk;
});
stream.on('end', () => {
this.setState({ content: data, loading: false });
});
stream.on('error', error => {
this.setState({ error: true, loading: false });
});
}
renderDocument(content = null) {
let viewer = null;
const { source, theme } = this.props;
const { fileType, contentType } = source;
const markdownType = ['md', 'markdown'];
if (markdownType.includes(fileType)) {
// Render markdown
viewer = <MarkdownPreview content={content} promptLinks />;
} else {
// Render plain text
viewer = <CodeViewer value={content} contentType={contentType} theme={theme} />;
}
return viewer;
}
render() {
const { error, loading, content } = this.state;
const isReady = content && !error;
const loadingMessage = __('Rendering document.');
const errorMessage = __("Sorry, looks like we can't load the document.");
return (
<div className="file-render__viewer document-viewer">
{loading && !error && <LoadingScreen status={loadingMessage} spinner />}
{error && <LoadingScreen status={errorMessage} spinner={!error} />}
{isReady && this.renderDocument(content)}
</div>
);
}
}
export default DocumentViewer;

View file

@ -0,0 +1,74 @@
// @flow
import React from 'react';
import mammoth from 'mammoth';
import Breakdance from 'breakdance';
import LoadingScreen from 'component/common/loading-screen';
import MarkdownPreview from 'component/common/markdown-preview';
type Props = {
source: string,
};
class DocxViewer extends React.PureComponent<Props> {
constructor(props) {
super(props);
this.state = {
error: null,
content: null,
loading: true,
};
}
componentDidMount() {
const { source } = this.props;
// Overwrite element and styles
const options = {
styleMap: [
"p[style-name='Title'] => h1:fresh",
"p[style-name='Heading 1'] => h1:fresh",
"p[style-name='Heading 2'] => h2:fresh",
"p[style-name='Heading 3'] => h3:fresh",
"p[style-name='Section Title'] => h1:fresh",
"p[style-name='Subsection Title'] => h2:fresh",
"p[style-name='Aside Heading'] => div.aside > h2:fresh",
"p[style-name='Aside Text'] => div.aside > p:fresh",
],
};
// Parse docx to html
mammoth
.convertToHtml({ path: source }, options)
.then(result => {
// Remove images and tables
const breakdance = new Breakdance({ omit: ['table', 'img'] });
// Convert html to markdown
const markdown = breakdance.render(result.value);
this.setState({ content: markdown, loading: false });
})
.catch(error => {
this.setState({ error: true, loading: false });
})
.done();
}
render() {
const { content, error, loading } = this.state;
const loadingMessage = __('Rendering document.');
const errorMessage = __("Sorry, looks like we can't load the document.");
return (
<div className="document-viewer file-render__viewer">
{loading && <LoadingScreen status={loadingMessage} spinner />}
{error && <LoadingScreen status={errorMessage} spinner={false} />}
{content && (
<div className="document-viewer__content">
<MarkdownPreview content={content} promptLinks />
</div>
)}
</div>
);
}
}
export default DocxViewer;

View file

@ -0,0 +1,20 @@
// @flow
import React from 'react';
import { stopContextMenu } from 'util/contextMenu';
type Props = {
source: string,
};
class HtmlViewer extends React.PureComponent<Props> {
render() {
const { source } = this.props;
return (
<div className="file-render__viewer" onContextMenu={stopContextMenu}>
<iframe sandbox="" title={__('File preview')} src={`file://${source}`} />
</div>
);
}
}
export default HtmlViewer;

View file

@ -1,12 +1,9 @@
// @flow
import React from 'react';
import { stopContextMenu } from 'util/contextMenu';
type Props = {
source: {
fileType: string,
filePath: string,
downloadPath: string,
},
source: string,
};
class PdfViewer extends React.PureComponent<Props> {
@ -15,20 +12,11 @@ class PdfViewer extends React.PureComponent<Props> {
this.viewer = React.createRef();
}
// TODO: Enable context-menu
stopContextMenu = event => {
event.preventDefault();
event.stopPropagation();
};
render() {
const { source } = this.props;
return (
<div className="file-render__viewer" onContextMenu={this.stopContextMenu}>
<webview
ref={this.viewer}
src={`chrome://pdf-viewer/index.html?src=file://${source.downloadPath}`}
/>
<div className="file-render__viewer" onContextMenu={stopContextMenu}>
<webview ref={this.viewer} src={`chrome://pdf-viewer/index.html?src=file://${source}`} />
</div>
);
}

View file

@ -14,7 +14,7 @@ type Props = {
autoRotate: boolean,
source: {
fileType: string,
filePath: string,
downloadPath: string,
},
};

View file

@ -17,13 +17,13 @@ const Loader = (fileType, manager) => {
return fileTypes[fileType] ? fileTypes[fileType]() : null;
};
const ThreeLoader = ({ fileType, filePath }, renderModel, managerEvents) => {
const ThreeLoader = ({ fileType = null, downloadPath = null }, renderModel, managerEvents) => {
if (fileType) {
const manager = Manager(managerEvents);
const loader = Loader(fileType, manager);
if (loader) {
loader.load(filePath, data => {
loader.load(`file://${downloadPath}`, data => {
renderModel(fileType, data);
});
}

View file

@ -51,8 +51,9 @@ class FilePage extends React.Component<Props> {
'text',
'model',
'image',
'3D-file',
'script',
'document',
'3D-file',
// Bypass unplayable files
// TODO: Find a better way to detect supported types
'application',

View file

@ -156,6 +156,7 @@ p {
}
.page {
z-index: 0;
position: absolute;
top: var(--header-height);
left: 0;
@ -251,7 +252,7 @@ p {
/* Custom text selection */
*::selection {
background: var(--color-primary-light);
background: var(--text-selection-bg);
color: var(--text-selection-color);
}

View file

@ -62,9 +62,11 @@ $large-breakpoint: 1921px;
--text-help-color: var(--color-help);
--text-max-width: 660px;
--text-link-padding: 4px;
--text-selection-bg: var(--color-purple);
--text-selection-color: #fff;
/* Text Selectiom */
--text-selection-bg: var(--color-primary-light);
--text-selection-color: var(--color-white);
--editor-text-selection-bg: rgba(57, 148, 131, 0.8);
/* Form */
--form-label-color: rgba(0, 0, 0, 0.54);

View file

@ -2,6 +2,7 @@
@import '_reset.scss';
@import '_vars.scss';
@import '_gui.scss';
@import 'component/_syntax-highlighter.scss';
@import 'component/_table.scss';
@import 'component/_button.scss';
@import 'component/_card.scss';
@ -26,3 +27,4 @@
@import 'component/_file-render.scss';
@import 'component/_search.scss';
@import 'component/_toggle.scss';
@import 'component/_search.scss';

View file

@ -101,25 +101,6 @@
}
}
.file-render {
width: 100%;
height: 100%;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
overflow: hidden;
.file-render__viewer {
width: 100%;
height: 100%;
background: black;
}
}
img {
max-height: 100%;
max-width: 100%;

View file

@ -9,17 +9,79 @@
bottom: 0;
z-index: 1;
overflow: hidden;
}
.file-render__viewer {
margin: 0;
.file-render__viewer {
margin: 0;
width: 100%;
height: 100%;
background-color: black;
iframe,
webview {
width: 100%;
height: 100%;
background: black;
iframe,
webview {
width: 100%;
height: 100%;
}
}
}
.document-viewer {
overflow: auto;
background-color: var(--card-bg);
font-size: calc(var(--font-size-subtext-multiple) * 1em);
}
.document-viewer .markdown-preview {
height: 100%;
overflow: auto;
padding: $spacing-vertical $spacing-width;
}
.code-viewer,
.document-viewer__content {
overflow: auto;
width: 100%;
height: 100%;
}
/* Code-viewer */
.code-viewer .CodeMirror {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
min-height: 100px;
/* Block native text selection */
user-select: none;
.CodeMirror-code {
font-size: 1em;
font-weight: 350;
line-height: 1.5em;
font-family: Menlo, Consolas, 'DejaVu Sans Mono', inconsolata, monospace;
letter-spacing: 0.3px;
word-spacing: 1px;
}
.CodeMirror-linenumber {
color: var(--card-text-color);
}
.CodeMirror .CodeMirror-lines {
padding: 4px 0;
}
.CodeMirror-line {
padding-left: 16px;
}
.CodeMirror-gutters {
border-right: 1px solid var(--color-divider);
background: var(--color-bg-alt);
padding-right: 8px;
}
.cm-invalidchar {
display: none;
}
}

View file

@ -1,96 +1,88 @@
.CodeMirror {
background: var(--color-canvas) !important;
border: 0px !important;
border-radius: 0px !important;
color: var(--text-color) !important;
box-shadow: var(--box-shadow-layer);
border: 0px;
border-radius: 0px;
background: var(--card-bg);
color: var(--text-color);
}
.editor-toolbar {
opacity: 1 !important;
border: 0 !important;
opacity: 1;
border: 0;
background: var(--color-bg-alt);
border-radius: 0 !important;
border-radius: 0;
box-shadow: var(--box-shadow-layer);
}
.editor-toolbar:hover {
opacity: 1;
}
.editor-toolbar i.separator {
border: 0 !important;
border-right: var(--divider) !important;
border: 0;
}
.editor-toolbar.fullscreen {
background: var(--color-bg) !important;
background: var(--color-bg-alt);
}
div.editor-toolbar a {
opacity: 0.64;
.editor-toolbar.fullscreen::before,
.editor-toolbar.fullscreen::after {
display: none;
}
.editor-toolbar a {
opacity: 0.6;
color: var(--text-color) !important;
transition: opacity 0.3s ease;
}
.editor-toolbar a.active,
.editor-toolbar a:hover {
opacity: 1;
background: var(--button-bg) !important;
border-color: transparent !important;
background: var(--button-bg);
border-color: transparent;
}
.editor-toolbar.disabled-for-preview a:not(.no-disable) {
background: var(--color-bg-alt) !important;
border-color: transparent !important;
background: var(--color-bg-alt);
border-color: transparent;
opacity: 0.3;
}
.editor-statusbar {
color: var(--form-label-color) !important;
color: var(--form-label-color);
}
.editor-preview {
font-size: calc(var(--font-size-subtext-multiple) * 1em);
background: var(--color-bg) !important;
background: var(--color-bg);
border: 0;
}
.editor-preview-side {
background: var(--color-bg-alt) !important;
border: 1px solid var(--input-border-color) !important;
}
.CodeMirror .CodeMirror-code .cm-tag {
color: #63a35c;
}
.CodeMirror .CodeMirror-code .cm-attribute {
color: #795da3;
}
.CodeMirror .CodeMirror-code .cm-string {
color: #183691;
}
.CodeMirror .CodeMirror-selected {
background: var(--text-selection-bg) !important;
color: var(--text-selection-color) !important;
}
.CodeMirror .CodeMirror-cursor {
border-color: var(--color-primary) !important;
}
.CodeMirror .CodeMirror-code .cm-comment {
background: rgba(0, 0, 0, 0.05);
}
.CodeMirror .CodeMirror-code .cm-link {
color: #7f8c8d;
}
.CodeMirror .CodeMirror-code .cm-url {
color: #aab2b3;
border-color: var(--color-primary);
}
.CodeMirror .CodeMirror-placeholder {
opacity: 0.5;
}
/* Fix selection */
.CodeMirror-line::selection,
.CodeMirror-line > span::selection,
.CodeMirror-line > span > span::selection {
background: var(--text-selection-bg);
}
.CodeMirror .CodeMirror-selected {
background: transparent;
}
.CodeMirror .CodeMirror-selectedtext {
background: var(--editor-text-selection-bg) !important;
color: var(--text-selection-color) !important;
}
.CodeMirror .cm-spell-error:not(.cm-url):not(.cm-comment):not(.cm-tag):not(.cm-word) {
background: none;
text-decoration: underline;

View file

@ -63,6 +63,11 @@
}
}
/* Image */
img {
margin: 16px 0;
}
/* Horizontal Rule */
hr {
border: 1px solid var(--color-divider);

View file

@ -0,0 +1,147 @@
/*
Name: one-dark 1.1.1
Author: Török Ádám (http://github.com/Aerobird98)
Original Atom One Dark Theme (https://github.com/atom/one-dark-ui & https://github.com/atom/one-dark-syntax)
*/
/* basic */
.CodeMirror.cm-s-one-dark {
color: #abb2bf;
}
.CodeMirror.cm-s-one-dark .CodeMirror-lines {
color: #abb2bf !important;
background-color: transparent;
}
.CodeMirror.cm-s-one-dark .CodeMirror-cursor {
border-left: 2px solid #56b6c2 !important;
}
/* addon: edit/machingbrackets.js & addon: edit/matchtags.js */
.CodeMirror.cm-s-one-dark .CodeMirror-matchingbracket,
.CodeMirror.cm-s-one-dark .CodeMirror-matchingtag {
border-bottom: 2px solid #56b6c2;
color: #abb2bf !important;
background-color: transparent;
}
.CodeMirror.cm-s-one-dark .CodeMirror-nonmatchingbracket {
border-bottom: 2px solid #e06c75;
color: #abb2bf !important;
background-color: transparent;
}
/* addon: fold/foldgutter.js */
.CodeMirror.cm-s-one-dark .CodeMirror-foldmarker,
.CodeMirror.cm-s-one-dark .CodeMirror-foldgutter,
.CodeMirror.cm-s-one-dark .CodeMirror-foldgutter-open,
.CodeMirror.cm-s-one-dark .CodeMirror-foldgutter-folded {
border: none;
text-shadow: none;
color: #5c6370 !important;
background-color: transparent;
}
/* addon: selection/active-line.js */
.CodeMirror.cm-s-one-dark .CodeMirror-activeline-background {
background-color: rgba(153, 187, 255, 0.04);
}
/* basic syntax */
.CodeMirror.cm-s-one-dark .cm-header {
color: #e06c75;
}
.CodeMirror.cm-s-one-dark .cm-quote {
color: #5c6370;
font-style: italic;
}
.CodeMirror.cm-s-one-dark .cm-negative {
color: #e06c75;
}
.CodeMirror.cm-s-one-dark .cm-positive {
color: #e06c75;
}
.CodeMirror.cm-s-one-dark .cm-strong {
color: #d19a66;
font-weight: bold;
}
.CodeMirror.cm-s-one-dark .cm-header .cm-strong {
color: #d19a66;
font-weight: bold;
}
.CodeMirror.cm-s-one-dark .cm-em {
color: #c678dd;
font-style: italic;
}
.CodeMirror.cm-s-one-dark .cm-header .cm-em {
color: #c678dd;
font-style: italic;
}
.CodeMirror.cm-s-one-dark .cm-tag {
color: #e06c75;
}
.CodeMirror.cm-s-one-dark .cm-attribute {
color: #d19a66;
}
.CodeMirror.cm-s-one-dark .cm-link {
color: #98c379;
border-bottom: solid 1px #98c379;
}
.CodeMirror.cm-s-one-dark .cm-builtin {
color: #e06c75;
}
.CodeMirror.cm-s-one-dark .cm-keyword {
color: #c678dd;
}
.CodeMirror.cm-s-one-dark .cm-def {
color: #e5c07b;
} /* original: #d19a66; */
.CodeMirror.cm-s-one-dark .cm-atom {
color: #d19a66;
}
.CodeMirror.cm-s-one-dark .cm-number {
color: #d19a66;
}
.CodeMirror.cm-s-one-dark .cm-property {
color: #56b6c2;
} /* original: #abb2bf */
.CodeMirror.cm-s-one-dark .cm-qualifier {
color: #d19a66;
}
.CodeMirror.cm-s-one-dark .cm-variable {
color: #e06c75;
}
.CodeMirror.cm-s-one-dark .cm-string {
color: #98c379;
}
.CodeMirror.cm-s-one-dark .cm-punctuation {
color: #abb2bf;
}
.CodeMirror.cm-s-one-dark .cm-operator {
color: #56b6c2;
} /* original: #abb2bf */
.CodeMirror.cm-s-one-dark .cm-meta {
color: #abb2bf;
}
.CodeMirror.cm-s-one-dark .cm-bracket {
color: #abb2bf;
}
.CodeMirror.cm-s-one-dark .cm-comment {
color: #5c6370;
font-style: italic;
}
.CodeMirror.cm-s-one-dark .cm-error {
color: #e06c75;
}
/* css syntax corrections */
.CodeMirror.cm-s-one-dark .cm-m-css.cm-variable {
color: #828997;
}
.CodeMirror.cm-s-one-dark .cm-m-css.cm-property {
color: #abb2bf;
}
.CodeMirror.cm-s-one-dark .cm-m-css.cm-atom {
color: #56b6c2;
}
.CodeMirror.cm-s-one-dark .cm-m-css.cm-builtin {
color: #56b6c2;
}
/* lua syntax corrections */
.CodeMirror.cm-s-one-dark .cm-m-lua.cm-variable {
color: #56b6c2;
}

View file

@ -23,9 +23,9 @@ function injectDevelopmentTemplate(event, templates) {
export function openContextMenu(event, templates = [], canEdit = false, selection = '') {
const { type, value } = event.target;
const isSomethingSelected = selection.length > 0 || window.getSelection().toString().length > 0;
const isInput = event.target.matches('input') && (type === 'text' || type === 'number');
const isTextField = canEdit || isInput || event.target.matches('textarea');
const isSomethingSelected = selection.length > 0 || window.getSelection().toString().length > 0;
templates.push({
label: 'Copy',
@ -63,7 +63,7 @@ export function openContextMenu(event, templates = [], canEdit = false, selectio
}
// This function is used for the markdown description on the publish page
export function openEditorMenu(event, codeMirror) {
export function openEditorMenu(codeMirror, event) {
const value = codeMirror.doc.getValue();
const selection = codeMirror.doc.getSelection();
const templates = [
@ -86,6 +86,25 @@ export function openEditorMenu(event, codeMirror) {
openContextMenu(event, templates, true, selection);
}
// This function is used for the CodeViewer component
export function openSnippetMenu(codeMirror, event) {
const value = codeMirror.doc.getValue();
const selection = codeMirror.doc.getSelection();
const templates = [
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
role: 'selectall',
click: () => {
codeMirror.execCommand('selectAll');
},
// Enabled if there is text to select
enabled: value.length > 0,
},
];
openContextMenu(event, templates, false, selection);
}
export function openCopyLinkMenu(text, event) {
const templates = [
{
@ -97,3 +116,9 @@ export function openCopyLinkMenu(text, event) {
];
openContextMenu(event, templates);
}
// Block context menu
export function stopContextMenu(event) {
event.preventDefault();
event.stopPropagation();
}

View file

@ -3,7 +3,9 @@ import mime from 'mime';
const formats = [
[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'],
[/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'],
[/\.(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'],
[/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'],
[/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'],
[/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'],
[/\.(stl|obj|fbx|gcode)$/i, '3D-file'],
];

View file

@ -1,7 +1,6 @@
:root {
/* Colors */
--color-divider: #53637C;;
--color-canvas: transparent;
--color-help: #8696AF;
@ -12,12 +11,11 @@
--color-placeholder: var(--color-bg-alt);
/* Text */
--text-color: #FFF;
--text-color: var(--color-white);
--text-help-color: var(--color-help);
--text-selection-color: #fff;
/* Form */
--form-label-color: #FFF;
--form-label-color: var(--color-white);
/* Input */
--input-bg: transparent;
@ -90,7 +88,7 @@
/* Scrollbar */
--scrollbar-thumb-bg: rgba(255, 255, 255, 0.20);
--scrollbar-thumb-hover-bg: #8696AF;
/* Shadows */
--box-shadow-header: 0px 6px 20px 1px rgba(0, 0, 0, 0.2);
}

347
yarn.lock
View file

@ -309,7 +309,7 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.7:
argparse@^1.0.7, argparse@~1.0.3:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
dependencies:
@ -1282,7 +1282,7 @@ bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
bluebird@~3.4.1:
bluebird@~3.4.0, bluebird@~3.4.1:
version "3.4.7"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3"
@ -1368,6 +1368,43 @@ braces@^2.3.0, braces@^2.3.1:
split-string "^3.0.2"
to-regex "^3.0.1"
breakdance-util@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/breakdance-util/-/breakdance-util-0.1.5.tgz#c76bb92bac25f94d2adb90ead3b3e54140466b98"
dependencies:
diacritics-map "^0.1.0"
get-value "^2.0.6"
is-self-closing "^1.0.0"
kind-of "^3.1.0"
snapdragon-util "^1.0.6"
strip-color "^0.1.0"
typeof-article "^0.1.1"
word-regex "^0.1.1"
breakdance@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/breakdance/-/breakdance-3.0.1.tgz#475a989c8389f522876890ba14f397adfb0e3184"
dependencies:
breakdance-util "^0.1.5"
cheerio "^0.22.0"
condense-newlines "^0.2.1"
define-property "^1.0.0"
detect-indent "^5.0.0"
export-files "^2.1.1"
extend-shallow "^2.0.1"
is-self-closing "^1.0.0"
isobject "^3.0.0"
mixin-deep "^1.2.0"
repeat-string "^1.6.1"
snapdragon "^0.11.0"
snapdragon-cheerio "^1.1.0"
snapdragon-node "^1.0.6"
snapdragon-util "^2.1.1"
strip-attributes "^0.2.0"
trim-leading-lines "^0.1.1"
trim-trailing-lines "^1.1.0"
unescape "^0.2.0"
brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
@ -1775,6 +1812,27 @@ cheerio@^0.19.0:
htmlparser2 "~3.8.1"
lodash "^3.2.0"
cheerio@^0.22.0:
version "0.22.0"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
dependencies:
css-select "~1.2.0"
dom-serializer "~0.1.0"
entities "~1.1.1"
htmlparser2 "^3.9.1"
lodash.assignin "^4.0.9"
lodash.bind "^4.1.4"
lodash.defaults "^4.0.1"
lodash.filter "^4.4.0"
lodash.flatten "^4.2.0"
lodash.foreach "^4.3.0"
lodash.map "^4.4.0"
lodash.merge "^4.4.0"
lodash.pick "^4.2.1"
lodash.reduce "^4.4.0"
lodash.reject "^4.4.0"
lodash.some "^4.4.0"
chokidar@^1.0.0, chokidar@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@ -1949,6 +2007,10 @@ codemirror@*:
version "5.39.0"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.0.tgz#4654f7d2f7e525e04a62e72d9482348ccb37dce5"
codemirror@^5.39.2:
version "5.39.2"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.2.tgz#778aa13b55ebf280745c309cb1b148e3fc06f698"
collapse-white-space@^1.0.0, collapse-white-space@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091"
@ -2099,6 +2161,14 @@ concat-stream@1.6.2, concat-stream@^1.4.6, concat-stream@^1.4.7, concat-stream@^
readable-stream "^2.2.2"
typedarray "^0.0.6"
condense-newlines@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f"
dependencies:
extend-shallow "^2.0.1"
is-whitespace "^0.3.0"
kind-of "^3.0.2"
configstore@^3.0.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f"
@ -2323,7 +2393,7 @@ css-loader@^0.28.9:
postcss-value-parser "^3.3.0"
source-list-map "^2.0.0"
css-select@^1.1.0:
css-select@^1.1.0, css-select@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
dependencies:
@ -2458,7 +2528,7 @@ debug@2.2.0:
dependencies:
ms "0.7.1"
debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.2, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
@ -2650,6 +2720,10 @@ detect-indent@^4.0.0:
dependencies:
repeating "^2.0.0"
detect-indent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
detect-libc@^1.0.2, detect-libc@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
@ -2673,6 +2747,10 @@ devtron@^1.4.0:
highlight.js "^9.3.0"
humanize-plus "^1.8.1"
diacritics-map@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/diacritics-map/-/diacritics-map-0.1.0.tgz#6dfc0ff9d01000a2edf2865371cac316e94977af"
diff@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf"
@ -2757,7 +2835,7 @@ domain-browser@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
domelementtype@1:
domelementtype@1, domelementtype@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
@ -2777,6 +2855,12 @@ domhandler@2.3:
dependencies:
domelementtype "1"
domhandler@^2.3.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
dependencies:
domelementtype "1"
domutils@1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485"
@ -2796,6 +2880,13 @@ domutils@1.5, domutils@1.5.1:
dom-serializer "0"
domelementtype "1"
domutils@^1.5.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
dependencies:
dom-serializer "0"
domelementtype "1"
dot-prop@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
@ -2810,6 +2901,12 @@ dotenv@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935"
duck@~0.1.11:
version "0.1.11"
resolved "https://registry.yarnpkg.com/duck/-/duck-0.1.11.tgz#3adc1a3d2fbdd5879ffd3bda05ce0f69355e9093"
dependencies:
underscore "~1.4.4"
duplexer2@~0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
@ -3145,7 +3242,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"
@ -3612,6 +3709,12 @@ expand-template@^1.0.2:
version "1.1.1"
resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd"
export-files@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/export-files/-/export-files-2.1.1.tgz#bbf64574053a09e4eb98e5f43501d572b2c3ce7f"
dependencies:
lazy-cache "^1.0.3"
express@^4.13.3, express@^4.16.2:
version "4.16.3"
resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
@ -4613,6 +4716,17 @@ html-webpack-plugin@^2.30.1:
pretty-error "^2.0.2"
toposort "^1.0.0"
htmlparser2@^3.9.1:
version "3.9.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
dependencies:
domelementtype "^1.3.0"
domhandler "^2.3.0"
domutils "^1.5.1"
entities "^1.1.1"
inherits "^2.0.1"
readable-stream "^2.0.2"
htmlparser2@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe"
@ -5198,6 +5312,12 @@ is-retry-allowed@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
is-self-closing@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-self-closing/-/is-self-closing-1.0.1.tgz#5f406b527c7b12610176320338af0fa3896416e4"
dependencies:
self-closing-tags "^1.0.1"
is-stream@^1.0.0, 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"
@ -5230,6 +5350,10 @@ is-whitespace-character@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed"
is-whitespace@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f"
is-windows@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
@ -5460,6 +5584,12 @@ jsx-loader@^0.13.2:
jstransform "11"
loader-utils "^0.2.2"
jszip@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-2.5.0.tgz#7444fd8551ddf3e5da7198fea0c91bc8308cc274"
dependencies:
pako "~0.2.5"
kebab-case@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/kebab-case/-/kebab-case-1.0.0.tgz#3f9e4990adcad0c686c0e701f7645868f75f91eb"
@ -5475,7 +5605,7 @@ killable@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b"
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
dependencies:
@ -5511,6 +5641,12 @@ lazy-cache@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
lazy-cache@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264"
dependencies:
set-getter "^0.1.0"
lazy-val@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc"
@ -5706,6 +5842,14 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
lodash.assignin@^4.0.9:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
lodash.bind@^4.1.4:
version "4.2.1"
resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@ -5718,6 +5862,22 @@ lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
lodash.defaults@^4.0.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
lodash.filter@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
lodash.flatten@^4.2.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
lodash.foreach@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
lodash.forin@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.forin/-/lodash.forin-4.4.0.tgz#5d3f20ae564011fbe88381f7d98949c9c9519731"
@ -5734,22 +5894,46 @@ lodash.isequal@4.5.0, lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
lodash.map@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
lodash.merge@^4.4.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
lodash.mergewith@^4.6.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
lodash.pick@^4.2.1:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
lodash.pickby@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff"
lodash.reduce@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
lodash.reject@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
lodash.set@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
lodash.some@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
lodash.tail@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
@ -5766,7 +5950,7 @@ lodash.unset@^4.5.2:
version "4.5.2"
resolved "https://registry.yarnpkg.com/lodash.unset/-/lodash.unset-4.5.2.tgz#370d1d3e85b72a7e1b0cdf2d272121306f23e4ed"
lodash@3.10.1, lodash@^3.10.1, lodash@^3.2.0:
lodash@3.10.1, lodash@^3.10.1, lodash@^3.2.0, lodash@^3.5.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
@ -5811,6 +5995,14 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
lop@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/lop/-/lop-0.4.0.tgz#4f0e4384d5c4f455d0b86d254fd52a9d05593c2c"
dependencies:
duck "~0.1.11"
option "~0.2.1"
underscore "~1.4.4"
loud-rejection@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
@ -5854,6 +6046,19 @@ make-runnable@^1.3.6:
bluebird "^3.5.0"
yargs "^4.7.1"
mammoth@^1.4.6:
version "1.4.6"
resolved "https://registry.yarnpkg.com/mammoth/-/mammoth-1.4.6.tgz#1818934b0b34bb56f23b07e0670af31778543a8e"
dependencies:
argparse "~1.0.3"
bluebird "~3.4.0"
jszip "~2.5.0"
lop "~0.4.0"
path-is-absolute "^1.0.0"
sax "~1.1.1"
underscore "~1.8.3"
xmlbuilder "~2.6.4"
map-cache@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
@ -6625,14 +6830,14 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
object.omit@^2.0.0:
object.omit@^2.0.0, object.omit@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
dependencies:
for-own "^0.1.4"
is-extendable "^0.1.1"
object.pick@^1.3.0:
object.pick@^1.2.0, object.pick@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
dependencies:
@ -6685,6 +6890,10 @@ optimist@~0.6.0, optimist@~0.6.1:
minimist "~0.0.1"
wordwrap "~0.0.2"
option@~0.2.1:
version "0.2.4"
resolved "https://registry.yarnpkg.com/option/-/option-0.2.4.tgz#fd475cdf98dcabb3cb397a3ba5284feb45edbfe4"
optionator@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.6.0.tgz#b63ecbbf0e315fad4bc9827b45dc7ba45284fcb6"
@ -6822,7 +7031,7 @@ package-json@^4.0.0:
registry-url "^3.0.3"
semver "^5.1.0"
pako@~0.2.0:
pako@~0.2.0, pako@~0.2.5:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
@ -8265,6 +8474,10 @@ sax@>=0.6.0, sax@^1.2.4, sax@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
sax@~1.1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240"
schema-utils@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"
@ -8295,6 +8508,10 @@ select-hose@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
self-closing-tags@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/self-closing-tags/-/self-closing-tags-1.0.1.tgz#6c5fa497994bb826b484216916371accee490a5d"
selfsigned@^1.9.1:
version "1.10.3"
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.3.tgz#d628ecf9e3735f84e8bafba936b3cf85bea43823"
@ -8366,6 +8583,12 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
set-getter@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
dependencies:
to-object-path "^0.3.0"
set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
@ -8488,6 +8711,26 @@ slice-ansi@1.0.0:
dependencies:
is-fullwidth-code-point "^2.0.0"
snapdragon-cheerio@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/snapdragon-cheerio/-/snapdragon-cheerio-1.1.0.tgz#16f3bd3fa1615f85c5f826504c5bb406cd340eb7"
dependencies:
cheerio "^0.22.0"
define-property "^0.2.5"
extend-shallow "^2.0.1"
is-self-closing "^1.0.0"
snapdragon-node "^1.0.6"
snapdragon-util "^2.0.0"
snapdragon-node@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-1.0.6.tgz#2448d5ef6fea7f5e8fd5326a0a114854da271356"
dependencies:
define-property "^0.2.5"
isobject "^3.0.0"
lazy-cache "^2.0.2"
snapdragon-util "^1.0.3"
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -8496,12 +8739,44 @@ snapdragon-node@^2.0.1:
isobject "^3.0.0"
snapdragon-util "^3.0.1"
snapdragon-util@^1.0.3, snapdragon-util@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-1.0.6.tgz#8b3d2d6dec8930c90e054ba052e562ca1b3a621e"
dependencies:
define-property "^0.2.5"
kind-of "^3.1.0"
lazy-cache "^2.0.2"
snapdragon-node "^1.0.6"
snapdragon-util@^2.0.0, snapdragon-util@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-2.1.1.tgz#552779df8a1493a0e78c06cc80953a262770957a"
dependencies:
kind-of "^3.1.0"
snapdragon-util@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2"
dependencies:
kind-of "^3.2.0"
snapdragon@^0.11.0:
version "0.11.5"
resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.11.5.tgz#522812d175f24f919629fd37406b02e434e645e6"
dependencies:
component-emitter "^1.2.1"
debug "^2.6.2"
define-property "^0.2.5"
extend-shallow "^2.0.1"
get-value "^2.0.6"
isobject "^3.0.0"
map-cache "^0.2.2"
snapdragon-node "^1.0.6"
snapdragon-util "^2.1.1"
source-map "^0.5.6"
source-map-resolve "^0.5.0"
use "^3.1.0"
snapdragon@^0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d"
@ -8853,6 +9128,16 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
strip-attributes@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/strip-attributes/-/strip-attributes-0.2.0.tgz#30ba227c6abf6356a51b2b68626c795f19280945"
dependencies:
cheerio "^0.22.0"
extend-shallow "^2.0.1"
isobject "^3.0.0"
object.omit "^2.0.1"
object.pick "^1.2.0"
strip-bom@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
@ -8863,6 +9148,10 @@ strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
strip-color@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/strip-color/-/strip-color-0.1.0.tgz#106f65d3d3e6a2d9401cac0eb0ce8b8a702b4f7b"
strip-dirs@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5"
@ -9165,6 +9454,12 @@ tree-kill@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.0.tgz#5846786237b4239014f05db156b643212d4c6f36"
trim-leading-lines@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/trim-leading-lines/-/trim-leading-lines-0.1.1.tgz#0e7cac3e83042dcf95a74ed36966f17744d5c169"
dependencies:
is-whitespace "^0.3.0"
trim-lines@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.1.tgz#da738ff58fa74817588455e30b11b85289f2a396"
@ -9177,7 +9472,7 @@ trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
trim-trailing-lines@^1.0.0:
trim-trailing-lines@^1.0.0, trim-trailing-lines@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz#e0ec0810fd3c3f1730516b45f49083caaf2774d9"
@ -9236,6 +9531,12 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
typeof-article@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/typeof-article/-/typeof-article-0.1.1.tgz#9f07e733c3fbb646ffa9e61c08debacd460e06af"
dependencies:
kind-of "^3.1.0"
typo-js@*:
version "1.0.3"
resolved "https://registry.yarnpkg.com/typo-js/-/typo-js-1.0.3.tgz#54d8ebc7949f1a7810908b6002c6841526c99d5a"
@ -9320,6 +9621,18 @@ underscore@>1.4.4:
version "1.9.1"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
underscore@~1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
underscore@~1.8.3:
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
unescape@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/unescape/-/unescape-0.2.0.tgz#b78b9b60c86f1629df181bf53eee3bc8d6367ddf"
unherit@^1.0.4:
version "1.1.1"
resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.1.tgz#132748da3e88eab767e08fabfbb89c5e9d28628c"
@ -9862,6 +10175,10 @@ window-size@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
word-regex@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/word-regex/-/word-regex-0.1.2.tgz#a3bc7f2d222ce4a93c246c3ef69458f61f511639"
wordwrap@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
@ -9943,6 +10260,12 @@ xmlbuilder@^9.0.7:
version "9.0.7"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
xmlbuilder@~2.6.4:
version "2.6.5"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-2.6.5.tgz#6ff7ad60fb72d22764f007a164b77f2bf1400526"
dependencies:
lodash "^3.5.0"
xmldom@0.1.x:
version "0.1.27"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"