import React, { PureComponent } from 'react' import * as hljs from 'highlight.js' import ResizeObserver from 'resize-observer-polyfill' import debounce from 'lodash.debounce' import ms from 'ms' import { Controlled as CodeMirror } from 'react-codemirror2' import Spinner from 'react-spinner' import WindowControls from '../components/WindowControls' import Watermark from '../components/svg/Watermark' import { COLORS, LANGUAGE_MODE_HASH, LANGUAGE_NAME_HASH, DEFAULT_SETTINGS } from '../lib/constants' const handleLanguageChange = (newCode, props) => { if (props.config.language === 'auto') { // try to set the language const detectedLanguage = hljs.highlightAuto(newCode).language const languageMode = LANGUAGE_MODE_HASH[detectedLanguage] || LANGUAGE_NAME_HASH[detectedLanguage] if (languageMode) { return { language: languageMode.mime || languageMode.mode } } } return { language: props.config.language } } class Carbon extends PureComponent { constructor(props) { super(props) this.state = { loading: true, language: props.config.language } this.handleTitleBarChange = this.handleTitleBarChange.bind(this) this.codeUpdated = this.codeUpdated.bind(this) this.onBeforeChange = this.onBeforeChange.bind(this) this.handleLanguageChange = this.handleLanguageChange.bind(this) } componentDidMount() { this.setState({ loading: false }) this.setState(handleLanguageChange(this.props.children, this.props)) const ro = new ResizeObserver(entries => { const cr = entries[0].contentRect this.props.onAspectRatioChange(cr.width / cr.height) }) ro.observe(this.exportContainerNode) } static getDerivedStateFromProps(newProps) { return handleLanguageChange(newProps.children, newProps) || null } codeUpdated(newCode) { this.handleLanguageChange(newCode, this.props) this.props.updateCode(newCode) } handleTitleBarChange(newTitle) { this.props.updateTitleBar(newTitle) } handleLanguageChange = debounce( (...args) => this.setState(handleLanguageChange(...args)), ms('300ms'), { trailing: true } ) onBeforeChange(editor, meta, code) { return this.codeUpdated(code) } render() { const config = { ...DEFAULT_SETTINGS, ...this.props.config } const options = { lineNumbers: config.lineNumbers, mode: this.state.language || 'plaintext', theme: config.theme, scrollBarStyle: null, viewportMargin: Infinity, lineWrapping: true, extraKeys: { 'Shift-Tab': 'indentLess' } } const backgroundImage = (this.props.config.backgroundImage && this.props.config.backgroundImageSelection) || this.props.config.backgroundImage let content = (
) if (this.state.loading === false) { content = (
{config.windowControls ? ( ) : null} {config.watermark && }
) } return (
(this.exportContainerNode = ele)}> {content}
) } } export default Carbon