import React from 'react' import dynamic from 'next/dynamic' import * as hljs from 'highlight.js' import debounce from 'lodash.debounce' import ms from 'ms' import { Controlled as CodeMirror } from 'react-codemirror2' import WindowControls from '../components/WindowControls' import { COLORS, LANGUAGE_MODE_HASH, LANGUAGE_NAME_HASH, THEMES_HASH, DEFAULT_SETTINGS } from '../lib/constants' const Watermark = dynamic(() => import('../components/svg/Watermark'), { loading: () => null }) class Carbon extends React.PureComponent { static defaultProps = { onAspectRatioChange: () => {}, onChange: () => {} } componentDidMount() { const node = this.props.innerRef.current this.mo = new MutationObserver(() => { const ratio = node.clientWidth / node.clientHeight this.props.onAspectRatioChange(ratio) }) this.mo.observe(node, { attributes: true, childList: true, subtree: true }) } componentWillUnmount() { this.mo.disconnect() } handleLanguageChange = debounce( (newCode, language) => { if (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 languageMode.mime || languageMode.mode } } return language }, ms('300ms'), { leading: true, trailing: true } ) onBeforeChange = (editor, meta, code) => { if (!this.props.readOnly) { this.props.onChange(code) } } render() { const config = { ...DEFAULT_SETTINGS, ...this.props.config } const languageMode = this.handleLanguageChange(this.props.children, config.language) const options = { lineNumbers: config.lineNumbers, mode: languageMode || 'plaintext', theme: config.theme, scrollBarStyle: null, viewportMargin: Infinity, lineWrapping: true, extraKeys: { 'Shift-Tab': 'indentLess' }, // negative values removes the cursor, undefined means default (530) cursorBlinkRate: this.props.readOnly ? -1 : undefined, // needs to be able to refresh every 16ms to hit 60 frames / second pollInterval: 16 } const backgroundImage = (this.props.config.backgroundImage && this.props.config.backgroundImageSelection) || this.props.config.backgroundImage const content = (