Remove semicolons

main
Andrew 7 years ago committed by Jake Dexheimer
parent 7e69ca2897
commit 3cbcb49c27

@ -1,4 +1,5 @@
{ {
singleQuote: true, singleQuote: true,
printWidth: 100 printWidth: 100,
semi: false
} }

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react'
import { COLORS } from '../lib/constants'; import { COLORS } from '../lib/constants'
export default props => ( export default props => (
<button <button
@ -30,4 +30,4 @@ export default props => (
} }
`}</style> `}</style>
</button> </button>
); )

@ -1,14 +1,14 @@
import { EOL } from 'os'; import { EOL } from 'os'
import * as hljs from 'highlight.js'; import * as hljs from 'highlight.js'
import React from 'react'; import React from 'react'
import domtoimage from 'dom-to-image'; import domtoimage from 'dom-to-image'
import CodeMirror from 'react-codemirror'; import CodeMirror from 'react-codemirror'
import Spinner from 'react-spinner'; import Spinner from 'react-spinner'
import toHash from 'tohash'; import toHash from 'tohash'
import WindowControls from '../components/WindowControls'; import WindowControls from '../components/WindowControls'
import { COLORS, DEFAULT_LANGUAGE, LANGUAGES } from '../lib/constants'; import { COLORS, DEFAULT_LANGUAGE, LANGUAGES } from '../lib/constants'
const LANGUAGE_HASH = toHash(LANGUAGES, 'module'); const LANGUAGE_HASH = toHash(LANGUAGES, 'module')
const DEFAULT_SETTINGS = { const DEFAULT_SETTINGS = {
paddingVertical: '50px', paddingVertical: '50px',
@ -18,56 +18,56 @@ const DEFAULT_SETTINGS = {
background: '#fed0ec', background: '#fed0ec',
theme: 'seti', theme: 'seti',
language: DEFAULT_LANGUAGE language: DEFAULT_LANGUAGE
}; }
class Carbon extends React.Component { class Carbon extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props)
this.state = { this.state = {
loading: true, loading: true,
language: props.config.language language: props.config.language
}; }
this.handleLanguageChange = this.handleLanguageChange.bind(this); this.handleLanguageChange = this.handleLanguageChange.bind(this)
this.codeUpdated = this.codeUpdated.bind(this); this.codeUpdated = this.codeUpdated.bind(this)
} }
componentDidMount() { componentDidMount() {
this.setState({ this.setState({
loading: false loading: false
}); })
this.handleLanguageChange(this.props.children); this.handleLanguageChange(this.props.children)
} }
componentWillReceiveProps(newProps) { componentWillReceiveProps(newProps) {
this.handleLanguageChange(newProps.children, { customProps: newProps }); this.handleLanguageChange(newProps.children, { customProps: newProps })
} }
codeUpdated(newCode) { codeUpdated(newCode) {
this.handleLanguageChange(newCode); this.handleLanguageChange(newCode)
this.props.updateCode(newCode); this.props.updateCode(newCode)
} }
handleLanguageChange(newCode, config) { handleLanguageChange(newCode, config) {
const props = (config && config.customProps) || this.props; const props = (config && config.customProps) || this.props
if (props.config.language === 'auto') { if (props.config.language === 'auto') {
// try to set the language // try to set the language
const detectedLanguage = hljs.highlightAuto(newCode).language; const detectedLanguage = hljs.highlightAuto(newCode).language
const languageModule = LANGUAGE_HASH[detectedLanguage]; const languageModule = LANGUAGE_HASH[detectedLanguage]
if (languageModule) { if (languageModule) {
this.setState({ language: languageModule.module }); this.setState({ language: languageModule.module })
} }
} else { } else {
this.setState({ language: props.config.language }); this.setState({ language: props.config.language })
} }
} }
render() { render() {
const config = Object.assign(DEFAULT_SETTINGS, this.props.config); const config = Object.assign(DEFAULT_SETTINGS, this.props.config)
const options = { const options = {
lineNumbers: false, lineNumbers: false,
@ -76,13 +76,13 @@ class Carbon extends React.Component {
scrollBarStyle: null, scrollBarStyle: null,
viewportMargin: Infinity, viewportMargin: Infinity,
lineWrapping: true lineWrapping: true
}; }
// create styles // create styles
const containerStyle = { const containerStyle = {
background: config.background, background: config.background,
padding: `${config.paddingVertical} ${config.paddingHorizontal}` padding: `${config.paddingVertical} ${config.paddingHorizontal}`
}; }
// set content to spinner if loading, else editor // set content to spinner if loading, else editor
let content = ( let content = (
@ -96,7 +96,7 @@ class Carbon extends React.Component {
`} `}
</style> </style>
</div> </div>
); )
if (this.state.loading === false) { if (this.state.loading === false) {
content = ( content = (
<div id="container" style={containerStyle}> <div id="container" style={containerStyle}>
@ -150,7 +150,7 @@ class Carbon extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
return ( return (
@ -165,8 +165,8 @@ class Carbon extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
} }
export default Carbon; export default Carbon

@ -1,27 +1,27 @@
import React from 'react'; import React from 'react'
import enhanceWithClickOutside from 'react-click-outside'; import enhanceWithClickOutside from 'react-click-outside'
import { TwitterPicker } from 'react-color'; import { TwitterPicker } from 'react-color'
import WindowPointer from './WindowPointer'; import WindowPointer from './WindowPointer'
import { COLORS } from '../lib/constants'; import { COLORS } from '../lib/constants'
class ColorPicker extends React.Component { class ColorPicker extends React.Component {
constructor() { constructor() {
super(); super()
this.state = { isVisible: false }; this.state = { isVisible: false }
this.toggle = this.toggle.bind(this); this.toggle = this.toggle.bind(this)
this.handlePickColor = this.handlePickColor.bind(this); this.handlePickColor = this.handlePickColor.bind(this)
} }
toggle() { toggle() {
this.setState({ isVisible: !this.state.isVisible }); this.setState({ isVisible: !this.state.isVisible })
} }
handleClickOutside() { handleClickOutside() {
this.setState({ isVisible: false }); this.setState({ isVisible: false })
} }
handlePickColor(color) { handlePickColor(color) {
this.props.onChange(color.hex); this.props.onChange(color.hex)
} }
render() { render() {
@ -104,8 +104,8 @@ class ColorPicker extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
} }
export default enhanceWithClickOutside(ColorPicker); export default enhanceWithClickOutside(ColorPicker)

@ -1,33 +1,33 @@
import React from 'react'; import React from 'react'
import enhanceWithClickOutside from 'react-click-outside'; import enhanceWithClickOutside from 'react-click-outside'
import ArrowDown from './svg/Arrowdown'; import ArrowDown from './svg/Arrowdown'
import Checkmark from './svg/Checkmark'; import Checkmark from './svg/Checkmark'
import { COLORS } from '../lib/constants'; import { COLORS } from '../lib/constants'
class Dropdown extends React.Component { class Dropdown extends React.Component {
constructor(props) { constructor(props) {
super(); super()
this.state = { this.state = {
isVisible: false, isVisible: false,
selected: props.selected || props.list[0] selected: props.selected || props.list[0]
}; }
this.select = this.select.bind(this); this.select = this.select.bind(this)
this.toggle = this.toggle.bind(this); this.toggle = this.toggle.bind(this)
} }
select(item) { select(item) {
if (this.state.selected !== item) { if (this.state.selected !== item) {
this.props.onChange(item); this.props.onChange(item)
this.setState({ selected: item }); this.setState({ selected: item })
} }
} }
toggle() { toggle() {
this.setState({ isVisible: !this.state.isVisible }); this.setState({ isVisible: !this.state.isVisible })
} }
handleClickOutside() { handleClickOutside() {
this.setState({ isVisible: false }); this.setState({ isVisible: false })
} }
renderListItems() { renderListItems() {
@ -52,7 +52,7 @@ class Dropdown extends React.Component {
} }
`}</style> `}</style>
</div> </div>
)); ))
} }
render() { render() {
@ -60,7 +60,7 @@ class Dropdown extends React.Component {
const MIN_WIDTH = this.props.list.reduce( const MIN_WIDTH = this.props.list.reduce(
(max, { name }) => (name.length > max ? name.length : max), (max, { name }) => (name.length > max ? name.length : max),
0 0
); )
return ( return (
<div <div
@ -121,8 +121,8 @@ class Dropdown extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
} }
export default enhanceWithClickOutside(Dropdown); export default enhanceWithClickOutside(Dropdown)

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react'
import Link from 'next/link'; import Link from 'next/link'
import { COLORS } from '../lib/constants'; import { COLORS } from '../lib/constants'
const Footer = props => ( const Footer = props => (
<div className="mt3"> <div className="mt3">
@ -47,6 +47,6 @@ const Footer = props => (
} }
`}</style> `}</style>
</div> </div>
); )
export default Footer; export default Footer

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react'
import Logo from './svg/Logo'; import Logo from './svg/Logo'
const Header = ({ enableHeroText }) => ( const Header = ({ enableHeroText }) => (
<div className="header mb4"> <div className="header mb4">
@ -34,6 +34,6 @@ const Header = ({ enableHeroText }) => (
} }
`}</style> `}</style>
</div> </div>
); )
export default Header; export default Header

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react'
import { Controls, ControlsBW } from './svg/Controls'; import { Controls, ControlsBW } from './svg/Controls'
export default ({ language }) => ( export default ({ language }) => (
<div className="language"> <div className="language">
@ -19,4 +19,4 @@ export default ({ language }) => (
`} `}
</style> </style>
</div> </div>
); )

@ -1,7 +1,7 @@
import Head from 'next/head'; import Head from 'next/head'
import { THEMES_ARRAY, COLORS } from '../lib/constants'; import { THEMES_ARRAY, COLORS } from '../lib/constants'
import Reset from './style/Reset'; import Reset from './style/Reset'
import Typography from './style/Typography'; import Typography from './style/Typography'
export default () => ( export default () => (
<div className="meta"> <div className="meta">
@ -52,4 +52,4 @@ export default () => (
} }
`}</style> `}</style>
</div> </div>
); )

@ -22,6 +22,6 @@ const Overlay = props => (
} }
`}</style> `}</style>
</div> </div>
); )
export default Overlay; export default Overlay

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react'
import Meta from './Meta'; import Meta from './Meta'
import Header from './Header'; import Header from './Header'
import Footer from './Footer'; import Footer from './Footer'
export default ({ children, enableHeroText }) => ( export default ({ children, enableHeroText }) => (
<div className="main mt4 mb4"> <div className="main mt4 mb4">
@ -20,4 +20,4 @@ export default ({ children, enableHeroText }) => (
} }
`}</style> `}</style>
</div> </div>
); )

@ -1,27 +1,27 @@
import React from 'react'; import React from 'react'
import enhanceWithClickOutside from 'react-click-outside'; import enhanceWithClickOutside from 'react-click-outside'
import SettingsIcon from './svg/Settings'; import SettingsIcon from './svg/Settings'
import ThemeSelect from './ThemeSelect'; import ThemeSelect from './ThemeSelect'
import Slider from './Slider'; import Slider from './Slider'
import Toggle from './Toggle'; import Toggle from './Toggle'
import WindowPointer from './WindowPointer'; import WindowPointer from './WindowPointer'
import { COLORS } from '../lib/constants'; import { COLORS } from '../lib/constants'
class Settings extends React.Component { class Settings extends React.Component {
constructor(props) { constructor(props) {
super(); super()
this.state = { this.state = {
isVisible: false isVisible: false
}; }
this.toggle = this.toggle.bind(this); this.toggle = this.toggle.bind(this)
} }
toggle() { toggle() {
this.setState({ isVisible: !this.state.isVisible }); this.setState({ isVisible: !this.state.isVisible })
} }
handleClickOutside() { handleClickOutside() {
this.setState({ isVisible: false }); this.setState({ isVisible: false })
} }
render() { render() {
@ -108,8 +108,8 @@ class Settings extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
} }
export default enhanceWithClickOutside(Settings); export default enhanceWithClickOutside(Settings)

@ -1,21 +1,21 @@
import React from 'react'; import React from 'react'
export default class extends React.Component { export default class extends React.Component {
constructor(props) { constructor(props) {
super(); super()
this.state = { value: props.initialValue || 0 }; this.state = { value: props.initialValue || 0 }
this.handleChange = this.handleChange.bind(this); this.handleChange = this.handleChange.bind(this)
} }
handleChange(e) { handleChange(e) {
this.setState({ value: e.target.value }, () => { this.setState({ value: e.target.value }, () => {
this.props.onChange(`${this.state.value}px`); this.props.onChange(`${this.state.value}px`)
}); })
} }
render() { render() {
const minValue = this.props.minValue || 0; const minValue = this.props.minValue || 0
const maxValue = this.props.maxValue || 100; const maxValue = this.props.maxValue || 100
return ( return (
<div className="slider"> <div className="slider">
@ -70,6 +70,6 @@ export default class extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
} }

@ -1,27 +1,27 @@
import React from 'react'; import React from 'react'
import { None, BW, Sharp } from './svg/WindowThemes'; import { None, BW, Sharp } from './svg/WindowThemes'
import { COLORS } from '../lib/constants'; import { COLORS } from '../lib/constants'
const WINDOW_THEMES_MAP = { none: None, sharp: Sharp, bw: BW }; const WINDOW_THEMES_MAP = { none: None, sharp: Sharp, bw: BW }
export const WINDOW_THEMES = Object.keys(WINDOW_THEMES_MAP); export const WINDOW_THEMES = Object.keys(WINDOW_THEMES_MAP)
export default class extends React.Component { export default class extends React.Component {
constructor(props) { constructor(props) {
super(); super()
this.state = { selected: props.selected || WINDOW_THEMES[0] }; this.state = { selected: props.selected || WINDOW_THEMES[0] }
this.select = this.select.bind(this); this.select = this.select.bind(this)
} }
select(theme) { select(theme) {
if (this.state.selected !== theme) { if (this.state.selected !== theme) {
this.props.onChange(theme); this.props.onChange(theme)
this.setState({ selected: theme }); this.setState({ selected: theme })
} }
} }
renderThemes() { renderThemes() {
return WINDOW_THEMES.map((theme, i) => { return WINDOW_THEMES.map((theme, i) => {
const Img = WINDOW_THEMES_MAP[theme]; const Img = WINDOW_THEMES_MAP[theme]
return ( return (
<div <div
className={`theme ${this.state.selected === theme ? 'selected' : ''}`} className={`theme ${this.state.selected === theme ? 'selected' : ''}`}
@ -45,8 +45,8 @@ export default class extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
}); })
} }
render() { render() {
@ -71,6 +71,6 @@ export default class extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
} }

@ -1,17 +1,17 @@
import React from 'react'; import React from 'react'
import Checkmark from './svg/Checkmark'; import Checkmark from './svg/Checkmark'
export default class extends React.Component { export default class extends React.Component {
constructor(props) { constructor(props) {
super(); super()
this.state = { isEnabled: props.enabled || false }; this.state = { isEnabled: props.enabled || false }
this.toggle = this.toggle.bind(this); this.toggle = this.toggle.bind(this)
} }
toggle() { toggle() {
this.setState({ isEnabled: !this.state.isEnabled }, () => { this.setState({ isEnabled: !this.state.isEnabled }, () => {
this.props.onChange(this.state.isEnabled); this.props.onChange(this.state.isEnabled)
}); })
} }
render() { render() {
@ -30,6 +30,6 @@ export default class extends React.Component {
} }
`}</style> `}</style>
</div> </div>
); )
} }
} }

@ -1,4 +1,4 @@
import React from 'react'; import React from 'react'
const Toolbar = props => ( const Toolbar = props => (
<div id="toolbar"> <div id="toolbar">
{props.children} {props.children}
@ -23,6 +23,6 @@ const Toolbar = props => (
} }
`}</style> `}</style>
</div> </div>
); )
export default Toolbar; export default Toolbar

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react'
import { Controls, ControlsBW } from './svg/Controls'; import { Controls, ControlsBW } from './svg/Controls'
export default ({ theme }) => ( export default ({ theme }) => (
<div className="window-controls"> <div className="window-controls">
@ -16,4 +16,4 @@ export default ({ theme }) => (
`} `}
</style> </style>
</div> </div>
); )

@ -1,4 +1,4 @@
import React from 'react'; import React from 'react'
export default ({ fromLeft }) => ( export default ({ fromLeft }) => (
<div style={{ left: fromLeft }}> <div style={{ left: fromLeft }}>
@ -16,4 +16,4 @@ export default ({ fromLeft }) => (
} }
`}</style> `}</style>
</div> </div>
); )

@ -1,4 +1,4 @@
import { COLORS } from '../../lib/constants'; import { COLORS } from '../../lib/constants'
export default () => ( export default () => (
<style jsx global>{` <style jsx global>{`
@ -192,4 +192,4 @@ export default () => (
background: none; background: none;
} }
`}</style> `}</style>
); )

@ -175,4 +175,4 @@ export default () => (
font-weight: bold; font-weight: bold;
} }
`}</style> `}</style>
); )

@ -1,4 +1,4 @@
import React from 'react'; import React from 'react'
export default () => ( export default () => (
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6"> <svg xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6">
@ -9,4 +9,4 @@ export default () => (
transform="translate(-89 -14)" transform="translate(-89 -14)"
/> />
</svg> </svg>
); )

@ -1,4 +1,4 @@
import React from 'react'; import React from 'react'
export default () => ( export default () => (
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="8" viewBox="0 0 9 7"> <svg xmlns="http://www.w3.org/2000/svg" width="9" height="8" viewBox="0 0 9 7">
@ -8,4 +8,4 @@ export default () => (
points="2.852 5.016 8.275 0 9 .67 2.852 6.344 0 3.711 .713 3.042" points="2.852 5.016 8.275 0 9 .67 2.852 6.344 0 3.711 .713 3.042"
/> />
</svg> </svg>
); )

@ -1,4 +1,4 @@
import React from 'react'; import React from 'react'
export const Controls = () => ( export const Controls = () => (
<svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"> <svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14">
@ -8,7 +8,7 @@ export const Controls = () => (
<circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" strokeWidth=".5" /> <circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" strokeWidth=".5" />
</g> </g>
</svg> </svg>
); )
export const ControlsBW = () => ( export const ControlsBW = () => (
<svg xmlns="http://www.w3.org/2000/svg" width="54" height="16" viewBox="0 0 54 14"> <svg xmlns="http://www.w3.org/2000/svg" width="54" height="16" viewBox="0 0 54 14">
@ -18,4 +18,4 @@ export const ControlsBW = () => (
<circle cx="46" cy="6" r="6" /> <circle cx="46" cy="6" r="6" />
</g> </g>
</svg> </svg>
); )

File diff suppressed because one or more lines are too long

@ -1,4 +1,4 @@
import React from 'react'; import React from 'react'
export default () => ( export default () => (
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 18 18"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 18 18">
@ -9,4 +9,4 @@ export default () => (
transform="translate(-191 -357)" transform="translate(-191 -357)"
/> />
</svg> </svg>
); )

@ -1,4 +1,4 @@
import React from 'react'; import React from 'react'
export const Sharp = () => ( export const Sharp = () => (
<svg <svg
@ -47,7 +47,7 @@ export const Sharp = () => (
</g> </g>
</g> </g>
</svg> </svg>
); )
export const BW = () => ( export const BW = () => (
<svg <svg
@ -79,7 +79,7 @@ export const BW = () => (
</g> </g>
</g> </g>
</svg> </svg>
); )
export const None = () => ( export const None = () => (
<svg <svg
@ -110,4 +110,4 @@ export const None = () => (
</g> </g>
</g> </g>
</svg> </svg>
); )

@ -1,46 +1,46 @@
const Twitter = require('twitter'); const Twitter = require('twitter')
const morph = require('morphmorph'); const morph = require('morphmorph')
const RATE_LIMIT_CODE = 420; const RATE_LIMIT_CODE = 420
const client = new Twitter({ const client = new Twitter({
consumer_key: process.env.TWITTER_CONSUMER_KEY, consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET, consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY, access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
}); })
const uploadImage = data => client.post('media/upload', { media_data: data }); const uploadImage = data => client.post('media/upload', { media_data: data })
const uploadTweet = (media = {}) => const uploadTweet = (media = {}) =>
client.post('statuses/update', { client.post('statuses/update', {
status: `Carbon Copy #${media.media_id_string.slice(0, 8)}`, status: `Carbon Copy #${media.media_id_string.slice(0, 8)}`,
media_ids: media.media_id_string media_ids: media.media_id_string
}); })
const extractImageUrl = morph.get('entities.media.0.display_url'); const extractImageUrl = morph.get('entities.media.0.display_url')
const extractErrorCode = morph.get('0.code'); const extractErrorCode = morph.get('0.code')
const respondSuccess = (res, url) => res.json({ url }); const respondSuccess = (res, url) => res.json({ url })
const respondFail = (res, err) => { const respondFail = (res, err) => {
const errorCode = extractErrorCode(err); const errorCode = extractErrorCode(err)
// check for rate limit // check for rate limit
if (errorCode === RATE_LIMIT_CODE) { if (errorCode === RATE_LIMIT_CODE) {
return res.status(420).send(); return res.status(420).send()
} }
console.error(`Error: ${err.message || JSON.stringify(err, null, 2)}`); console.error(`Error: ${err.message || JSON.stringify(err, null, 2)}`)
res.status(500).send(); res.status(500).send()
}; }
module.exports = (req, res) => { module.exports = (req, res) => {
if (!req.body.data) { if (!req.body.data) {
return res.status(400).send(); return res.status(400).send()
} }
uploadImage(req.body.data) uploadImage(req.body.data)
.then(uploadTweet) .then(uploadTweet)
.then(extractImageUrl) .then(extractImageUrl)
.then(respondSuccess.bind(null, res)) .then(respondSuccess.bind(null, res))
.catch(respondFail.bind(null, res)); .catch(respondFail.bind(null, res))
}; }

@ -1,9 +1,9 @@
import axios from 'axios'; import axios from 'axios'
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce'
import ms from 'ms'; import ms from 'ms'
const DOMAIN = process.browser ? document.location.origin : ''; const DOMAIN = process.browser ? document.location.origin : ''
const RATE_LIMIT_CODE = 420; const RATE_LIMIT_CODE = 420
const gistClient = axios.create({ const gistClient = axios.create({
baseURL: 'https://api.github.com', baseURL: 'https://api.github.com',
@ -12,10 +12,10 @@ const gistClient = axios.create({
Accept: 'application/vnd.github.v3+json', Accept: 'application/vnd.github.v3+json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
}); })
async function tweet(encodedImage) { async function tweet(encodedImage) {
const processedData = encodedImage.split(',')[1]; const processedData = encodedImage.split(',')[1]
return axios return axios
.post(`${DOMAIN}/twitter`, { data: processedData }) .post(`${DOMAIN}/twitter`, { data: processedData })
@ -23,42 +23,42 @@ async function tweet(encodedImage) {
.then(url => encodeURIComponent(`Built with #Carbon, by @dawn_labs ${url}`)) .then(url => encodeURIComponent(`Built with #Carbon, by @dawn_labs ${url}`))
.then(uri => `https://twitter.com/intent/tweet?text=${uri}`) .then(uri => `https://twitter.com/intent/tweet?text=${uri}`)
.then(openTwitterUrl) .then(openTwitterUrl)
.catch(checkIfRateLimited); .catch(checkIfRateLimited)
} }
const getGist = id => { const getGist = id => {
const uid = id.split('/').pop(); const uid = id.split('/').pop()
return gistClient return gistClient
.get(`/gists/${uid}`) .get(`/gists/${uid}`)
.then(res => res.data) .then(res => res.data)
.then(gist => gist.files) .then(gist => gist.files)
.then(files => files[Object.keys(files)[0]]) .then(files => files[Object.keys(files)[0]])
.then(file => file.content); .then(file => file.content)
}; }
// private // private
function openTwitterUrl(twitterUrl) { function openTwitterUrl(twitterUrl) {
const width = 575, const width = 575,
height = 400; height = 400
const left = (window.outerWidth - width) / 2; const left = (window.outerWidth - width) / 2
const right = (window.outerHeight - height) / 2; const right = (window.outerHeight - height) / 2
const opts = `status=1,width=${width},height=${height},top=${top},left=${left}`; const opts = `status=1,width=${width},height=${height},top=${top},left=${left}`
window.open(twitterUrl, 'twitter', opts); window.open(twitterUrl, 'twitter', opts)
} }
function checkIfRateLimited(err) { function checkIfRateLimited(err) {
if (err.response.status === RATE_LIMIT_CODE) { if (err.response.status === RATE_LIMIT_CODE) {
alert( alert(
"Oh no! Looks like to many people are trying to tweet right now and we've been rate limited. Try again soon or save and upload manually!" "Oh no! Looks like to many people are trying to tweet right now and we've been rate limited. Try again soon or save and upload manually!"
); )
return; return
} }
throw err; throw err
} }
export default { export default {
getGist, getGist,
tweet: debounce(tweet, ms('5s'), { leading: true, trailing: true }) tweet: debounce(tweet, ms('5s'), { leading: true, trailing: true })
}; }

@ -1,4 +1,4 @@
import toHash from 'tohash'; import toHash from 'tohash'
export const THEMES_ARRAY = [ export const THEMES_ARRAY = [
{ {
@ -67,9 +67,9 @@ export const THEMES_ARRAY = [
id: 'zenburn', id: 'zenburn',
name: 'Zenburn' name: 'Zenburn'
} }
]; ]
export const THEMES = toHash(THEMES_ARRAY); export const THEMES = toHash(THEMES_ARRAY)
export const LANGUAGES = [ export const LANGUAGES = [
{ {
@ -277,16 +277,16 @@ export const LANGUAGES = [
name: 'YAML', name: 'YAML',
module: 'yaml' module: 'yaml'
} }
]; ]
export const DEFAULT_LANGUAGE = 'auto'; export const DEFAULT_LANGUAGE = 'auto'
export const COLORS = { export const COLORS = {
BLACK: '#121212', BLACK: '#121212',
PRIMARY: '#F8E81C', PRIMARY: '#F8E81C',
SECONDARY: '#fff', SECONDARY: '#fff',
GRAY: '#858585' GRAY: '#858585'
}; }
export const DEFAULT_CODE = `const pluckDeep = key => obj => key.split('.').reduce((accum, key) => accum[key], obj) export const DEFAULT_CODE = `const pluckDeep = key => obj => key.split('.').reduce((accum, key) => accum[key], obj)
@ -298,14 +298,14 @@ const unfold = (f, seed) => {
return res ? go(f, res[1], acc.concat([res[0]])) : acc return res ? go(f, res[1], acc.concat([res[0]])) : acc
} }
return go(f, seed, []) return go(f, seed, [])
}`; }`
if (typeof window !== 'undefined' && typeof window.navigator !== 'undefined') { if (typeof window !== 'undefined' && typeof window.navigator !== 'undefined') {
LANGUAGES.filter(language => language.module !== 'auto').forEach(language => { LANGUAGES.filter(language => language.module !== 'auto').forEach(language => {
if (language.module) { if (language.module) {
!language.custom !language.custom
? require(`codemirror/mode/${language.module}/${language.module}`) ? require(`codemirror/mode/${language.module}/${language.module}`)
: require(`./customModes/${language.module}`); : require(`./customModes/${language.module}`)
} }
}); })
} }

@ -1,203 +1,203 @@
const CodeMirror = require('codemirror'); const CodeMirror = require('codemirror')
CodeMirror.defineMode('kotlin', function(config, parserConfig) { CodeMirror.defineMode('kotlin', function(config, parserConfig) {
function words(str) { function words(str) {
var obj = {}, var obj = {},
words = str.split(' '); words = str.split(' ')
for (var i = 0; i < words.length; ++i) obj[words[i]] = true; for (var i = 0; i < words.length; ++i) obj[words[i]] = true
return obj; return obj
} }
var multiLineStrings = parserConfig.multiLineStrings; var multiLineStrings = parserConfig.multiLineStrings
var keywords = words( var keywords = words(
'package continue return object while break class data trait throw super ' + 'package continue return object while break class data trait throw super ' +
'when type this else This try val var fun for is in if do as true false null get set ' + 'when type this else This try val var fun for is in if do as true false null get set ' +
'import where by get set abstract enum open annotation override private public internal ' + 'import where by get set abstract enum open annotation override private public internal ' +
'protected catch out vararg inline finally final ref const' 'protected catch out vararg inline finally final ref const'
); )
var blockKeywords = words('catch class do else finally for if where try while enum'); var blockKeywords = words('catch class do else finally for if where try while enum')
var atoms = words('null true false this'); var atoms = words('null true false this')
var builtins = words( var builtins = words(
'Int Double Float Long Short Byte IntArray ShortArray ByteArray String Boolean List Set ' + 'Int Double Float Long Short Byte IntArray ShortArray ByteArray String Boolean List Set ' +
'Map MutableList MutableSet print println shl shr ushr and or xor inv ' 'Map MutableList MutableSet print println shl shr ushr and or xor inv '
); )
var curPunc; var curPunc
function tokenBase(stream, state) { function tokenBase(stream, state) {
var ch = stream.next(); var ch = stream.next()
if (ch == '"' || ch == "'") { if (ch == '"' || ch == "'") {
return startString(ch, stream, state); return startString(ch, stream, state)
} }
// Wildcard import w/o trailing semicolon (import smth.*) // Wildcard import w/o trailing semicolon (import smth.*)
if (ch == '.' && stream.eat('*')) { if (ch == '.' && stream.eat('*')) {
return 'word'; return 'word'
} }
if (/[\[\]{}\(\),;\:\.]/.test(ch)) { if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch; curPunc = ch
return null; return null
} }
if (/\d/.test(ch)) { if (/\d/.test(ch)) {
if (stream.eat(/eE/)) { if (stream.eat(/eE/)) {
stream.eat(/\+\-/); stream.eat(/\+\-/)
stream.eatWhile(/\d/); stream.eatWhile(/\d/)
} }
return 'number'; return 'number'
} }
if (ch == '/') { if (ch == '/') {
if (stream.eat('*')) { if (stream.eat('*')) {
state.tokenize.push(tokenComment); state.tokenize.push(tokenComment)
return tokenComment(stream, state); return tokenComment(stream, state)
} }
if (stream.eat('/')) { if (stream.eat('/')) {
stream.skipToEnd(); stream.skipToEnd()
return 'comment'; return 'comment'
} }
if (expectExpression(state.lastToken)) { if (expectExpression(state.lastToken)) {
return startString(ch, stream, state); return startString(ch, stream, state)
} }
} }
// Commented // Commented
if (ch == '-' && stream.eat('>')) { if (ch == '-' && stream.eat('>')) {
curPunc = '->'; curPunc = '->'
return null; return null
} }
if (/[\-+*&%=<>!?|\/~]/.test(ch)) { if (/[\-+*&%=<>!?|\/~]/.test(ch)) {
stream.eatWhile(/[\-+*&%=<>|~]/); stream.eatWhile(/[\-+*&%=<>|~]/)
return 'operator'; return 'operator'
} }
stream.eatWhile(/[\w\$_]/); stream.eatWhile(/[\w\$_]/)
var cur = stream.current(); var cur = stream.current()
if (atoms.propertyIsEnumerable(cur)) { if (atoms.propertyIsEnumerable(cur)) {
return 'atom'; return 'atom'
} }
if (keywords.propertyIsEnumerable(cur)) { if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = 'newstatement'; if (blockKeywords.propertyIsEnumerable(cur)) curPunc = 'newstatement'
return 'keyword'; return 'keyword'
} }
if (builtins.propertyIsEnumerable(cur)) { if (builtins.propertyIsEnumerable(cur)) {
return 'builtin'; return 'builtin'
} }
return 'word'; return 'word'
} }
tokenBase.isBase = true; tokenBase.isBase = true
function startString(quote, stream, state) { function startString(quote, stream, state) {
var tripleQuoted = false; var tripleQuoted = false
if (quote != '/' && stream.eat(quote)) { if (quote != '/' && stream.eat(quote)) {
if (stream.eat(quote)) tripleQuoted = true; if (stream.eat(quote)) tripleQuoted = true
else return 'string'; else return 'string'
} }
function t(stream, state) { function t(stream, state) {
var escaped = false, var escaped = false,
next, next,
end = !tripleQuoted; end = !tripleQuoted
while ((next = stream.next()) != null) { while ((next = stream.next()) != null) {
if (next == quote && !escaped) { if (next == quote && !escaped) {
if (!tripleQuoted) { if (!tripleQuoted) {
break; break
} }
if (stream.match(quote + quote)) { if (stream.match(quote + quote)) {
end = true; end = true
break; break
} }
} }
if (quote == '"' && next == '$' && !escaped && stream.eat('{')) { if (quote == '"' && next == '$' && !escaped && stream.eat('{')) {
state.tokenize.push(tokenBaseUntilBrace()); state.tokenize.push(tokenBaseUntilBrace())
return 'string'; return 'string'
} }
if (next == '$' && !escaped && !stream.eat(' ')) { if (next == '$' && !escaped && !stream.eat(' ')) {
state.tokenize.push(tokenBaseUntilSpace()); state.tokenize.push(tokenBaseUntilSpace())
return 'string'; return 'string'
} }
escaped = !escaped && next == '\\'; escaped = !escaped && next == '\\'
} }
if (multiLineStrings) state.tokenize.push(t); if (multiLineStrings) state.tokenize.push(t)
if (end) state.tokenize.pop(); if (end) state.tokenize.pop()
return 'string'; return 'string'
} }
state.tokenize.push(t); state.tokenize.push(t)
return t(stream, state); return t(stream, state)
} }
function tokenBaseUntilBrace() { function tokenBaseUntilBrace() {
var depth = 1; var depth = 1
function t(stream, state) { function t(stream, state) {
if (stream.peek() == '}') { if (stream.peek() == '}') {
depth--; depth--
if (depth == 0) { if (depth == 0) {
state.tokenize.pop(); state.tokenize.pop()
return state.tokenize[state.tokenize.length - 1](stream, state); return state.tokenize[state.tokenize.length - 1](stream, state)
} }
} else if (stream.peek() == '{') { } else if (stream.peek() == '{') {
depth++; depth++
} }
return tokenBase(stream, state); return tokenBase(stream, state)
} }
t.isBase = true; t.isBase = true
return t; return t
} }
function tokenBaseUntilSpace() { function tokenBaseUntilSpace() {
function t(stream, state) { function t(stream, state) {
if (stream.eat(/[\w]/)) { if (stream.eat(/[\w]/)) {
var isWord = stream.eatWhile(/[\w]/); var isWord = stream.eatWhile(/[\w]/)
if (isWord) { if (isWord) {
state.tokenize.pop(); state.tokenize.pop()
return 'word'; return 'word'
} }
} }
state.tokenize.pop(); state.tokenize.pop()
return 'string'; return 'string'
} }
t.isBase = true; t.isBase = true
return t; return t
} }
function tokenComment(stream, state) { function tokenComment(stream, state) {
var maybeEnd = false, var maybeEnd = false,
ch; ch
while ((ch = stream.next())) { while ((ch = stream.next())) {
if (ch == '/' && maybeEnd) { if (ch == '/' && maybeEnd) {
state.tokenize.pop(); state.tokenize.pop()
break; break
} }
maybeEnd = ch == '*'; maybeEnd = ch == '*'
} }
return 'comment'; return 'comment'
} }
function expectExpression(last) { function expectExpression(last) {
@ -209,25 +209,25 @@ CodeMirror.defineMode('kotlin', function(config, parserConfig) {
last == 'newstatement' || last == 'newstatement' ||
last == 'keyword' || last == 'keyword' ||
last == 'proplabel' last == 'proplabel'
); )
} }
function Context(indented, column, type, align, prev) { function Context(indented, column, type, align, prev) {
this.indented = indented; this.indented = indented
this.column = column; this.column = column
this.type = type; this.type = type
this.align = align; this.align = align
this.prev = prev; this.prev = prev
} }
function pushContext(state, col, type) { function pushContext(state, col, type) {
return (state.context = new Context(state.indented, col, type, null, state.context)); return (state.context = new Context(state.indented, col, type, null, state.context))
} }
function popContext(state) { function popContext(state) {
var t = state.context.type; var t = state.context.type
if (t == ')' || t == ']' || t == '}') state.indented = state.context.indented; if (t == ')' || t == ']' || t == '}') state.indented = state.context.indented
return (state.context = state.context.prev); return (state.context = state.context.prev)
} }
// Interface // Interface
@ -240,67 +240,67 @@ CodeMirror.defineMode('kotlin', function(config, parserConfig) {
indented: 0, indented: 0,
startOfLine: true, startOfLine: true,
lastToken: null lastToken: null
}; }
}, },
token: function(stream, state) { token: function(stream, state) {
var ctx = state.context; var ctx = state.context
if (stream.sol()) { if (stream.sol()) {
if (ctx.align == null) ctx.align = false; if (ctx.align == null) ctx.align = false
state.indented = stream.indentation(); state.indented = stream.indentation()
state.startOfLine = true; state.startOfLine = true
// Automatic semicolon insertion // Automatic semicolon insertion
if (ctx.type == 'statement' && !expectExpression(state.lastToken)) { if (ctx.type == 'statement' && !expectExpression(state.lastToken)) {
popContext(state); popContext(state)
ctx = state.context; ctx = state.context
} }
} }
if (stream.eatSpace()) return null; if (stream.eatSpace()) return null
curPunc = null; curPunc = null
var style = state.tokenize[state.tokenize.length - 1](stream, state); var style = state.tokenize[state.tokenize.length - 1](stream, state)
if (style == 'comment') return style; if (style == 'comment') return style
if (ctx.align == null) ctx.align = true; if (ctx.align == null) ctx.align = true
if ((curPunc == ';' || curPunc == ':') && ctx.type == 'statement') popContext(state); if ((curPunc == ';' || curPunc == ':') && ctx.type == 'statement') popContext(state)
else if (curPunc == '->' && ctx.type == 'statement' && ctx.prev.type == '}') { else if (curPunc == '->' && ctx.type == 'statement' && ctx.prev.type == '}') {
// Handle indentation for {x -> \n ... } // Handle indentation for {x -> \n ... }
popContext(state); popContext(state)
state.context.align = false; state.context.align = false
} else if (curPunc == '{') pushContext(state, stream.column(), '}'); } else if (curPunc == '{') pushContext(state, stream.column(), '}')
else if (curPunc == '[') pushContext(state, stream.column(), ']'); else if (curPunc == '[') pushContext(state, stream.column(), ']')
else if (curPunc == '(') pushContext(state, stream.column(), ')'); else if (curPunc == '(') pushContext(state, stream.column(), ')')
else if (curPunc == '}') { else if (curPunc == '}') {
while (ctx.type == 'statement') ctx = popContext(state); while (ctx.type == 'statement') ctx = popContext(state)
if (ctx.type == '}') ctx = popContext(state); if (ctx.type == '}') ctx = popContext(state)
while (ctx.type == 'statement') ctx = popContext(state); while (ctx.type == 'statement') ctx = popContext(state)
} else if (curPunc == ctx.type) popContext(state); } else if (curPunc == ctx.type) popContext(state)
else if ( else if (
ctx.type == '}' || ctx.type == '}' ||
ctx.type == 'top' || ctx.type == 'top' ||
(ctx.type == 'statement' && curPunc == 'newstatement') (ctx.type == 'statement' && curPunc == 'newstatement')
) )
pushContext(state, stream.column(), 'statement'); pushContext(state, stream.column(), 'statement')
state.startOfLine = false; state.startOfLine = false
state.lastToken = curPunc || style; state.lastToken = curPunc || style
return style; return style
}, },
indent: function(state, textAfter) { indent: function(state, textAfter) {
if (!state.tokenize[state.tokenize.length - 1].isBase) return 0; if (!state.tokenize[state.tokenize.length - 1].isBase) return 0
var firstChar = textAfter && textAfter.charAt(0), var firstChar = textAfter && textAfter.charAt(0),
ctx = state.context; ctx = state.context
if (ctx.type == 'statement' && !expectExpression(state.lastToken)) ctx = ctx.prev; if (ctx.type == 'statement' && !expectExpression(state.lastToken)) ctx = ctx.prev
var closing = firstChar == ctx.type; var closing = firstChar == ctx.type
if (ctx.type == 'statement') { if (ctx.type == 'statement') {
return ctx.indented + (firstChar == '{' ? 0 : config.indentUnit); return ctx.indented + (firstChar == '{' ? 0 : config.indentUnit)
} else if (ctx.align) return ctx.column + (closing ? 0 : 1); } else if (ctx.align) return ctx.column + (closing ? 0 : 1)
else return ctx.indented + (closing ? 0 : config.indentUnit); else return ctx.indented + (closing ? 0 : config.indentUnit)
}, },
closeBrackets: { closeBrackets: {
triples: '\'"' triples: '\'"'
}, },
electricChars: '{}' electricChars: '{}'
}; }
}); })
CodeMirror.defineMIME('text/x-kotlin', 'kotlin'); CodeMirror.defineMIME('text/x-kotlin', 'kotlin')

@ -1,14 +1,14 @@
const CodeMirror = require('codemirror'); const CodeMirror = require('codemirror')
CodeMirror.defineMode('nimrod', function(conf, parserConf) { CodeMirror.defineMode('nimrod', function(conf, parserConf) {
var ERRORCLASS = 'error'; var ERRORCLASS = 'error'
function wordRegexp(words) { function wordRegexp(words) {
return new RegExp('^((' + words.join(')|(') + '))\\b'); return new RegExp('^((' + words.join(')|(') + '))\\b')
} }
var operators = new RegExp('\\=\\+\\-\\*\\/\\<\\>\\@\\$\\~\\&\\%\\|\\!\\?\\^\\:\\\\'); var operators = new RegExp('\\=\\+\\-\\*\\/\\<\\>\\@\\$\\~\\&\\%\\|\\!\\?\\^\\:\\\\')
var identifiers = new RegExp('^[_A-Za-z][_A-Za-z0-9]*'); var identifiers = new RegExp('^[_A-Za-z][_A-Za-z0-9]*')
var commonkeywords = [ var commonkeywords = [
'addr', 'addr',
@ -81,7 +81,7 @@ CodeMirror.defineMode('nimrod', function(conf, parserConf) {
'in', 'in',
'as', 'as',
'of' 'of'
]; ]
var commonBuiltins = [ var commonBuiltins = [
'int', 'int',
@ -294,272 +294,272 @@ CodeMirror.defineMode('nimrod', function(conf, parserConf) {
'EFloatOverflow', 'EFloatOverflow',
'EFloatInexact', 'EFloatInexact',
'EDeadThrea' 'EDeadThrea'
]; ]
if (parserConf.extra_keywords != undefined) if (parserConf.extra_keywords != undefined)
commonkeywords = commonkeywords.concat(parserConf.extra_keywords); commonkeywords = commonkeywords.concat(parserConf.extra_keywords)
if (parserConf.extra_builtins != undefined) if (parserConf.extra_builtins != undefined)
commonBuiltins = commonBuiltins.concat(parserConf.extra_builtins); commonBuiltins = commonBuiltins.concat(parserConf.extra_builtins)
var keywords = wordRegexp(commonkeywords); var keywords = wordRegexp(commonkeywords)
var builtins = wordRegexp(commonBuiltins); var builtins = wordRegexp(commonBuiltins)
var indentInfo = null; var indentInfo = null
var stringPrefixes = new RegExp('^((\'{3}|"{3}|[\'"]))', 'i'); var stringPrefixes = new RegExp('^((\'{3}|"{3}|[\'"]))', 'i')
// tokenizers // tokenizers
function tokenBase(stream, state) { function tokenBase(stream, state) {
// Handle scope changes // Handle scope changes
if (stream.sol()) { if (stream.sol()) {
var scopeOffset = state.scopes[0].offset; var scopeOffset = state.scopes[0].offset
if (stream.eatSpace()) { if (stream.eatSpace()) {
var lineOffset = stream.indentation(); var lineOffset = stream.indentation()
if (lineOffset > scopeOffset) { if (lineOffset > scopeOffset) {
indentInfo = 'indent'; indentInfo = 'indent'
} else if (lineOffset < scopeOffset) { } else if (lineOffset < scopeOffset) {
indentInfo = 'dedent'; indentInfo = 'dedent'
} }
return null; return null
} else { } else {
if (scopeOffset > 0) { if (scopeOffset > 0) {
dedent(stream, state); dedent(stream, state)
} }
} }
} }
if (stream.eatSpace()) return null; if (stream.eatSpace()) return null
var ch = stream.peek(); var ch = stream.peek()
// Handle Comments // Handle Comments
if (ch === '#') { if (ch === '#') {
stream.skipToEnd(); stream.skipToEnd()
return 'comment'; return 'comment'
} }
// Handle Number Literals // Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) { if (stream.match(/^[0-9\.]/, false)) {
var floatLiteral = false; var floatLiteral = false
// Floats // Floats
if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) {
floatLiteral = true; floatLiteral = true
} }
if (stream.match(/^\d+\.\d*/)) { if (stream.match(/^\d+\.\d*/)) {
floatLiteral = true; floatLiteral = true
} }
if (stream.match(/^\.\d+/)) { if (stream.match(/^\.\d+/)) {
floatLiteral = true; floatLiteral = true
} }
if (floatLiteral) { if (floatLiteral) {
// Float literals may be "imaginary" // Float literals may be "imaginary"
stream.eat(/J/i); stream.eat(/J/i)
return 'number'; return 'number'
} }
// Integers // Integers
var intLiteral = false; var intLiteral = false
// Hex // Hex
if (stream.match(/^0x[0-9a-f]+/i)) { if (stream.match(/^0x[0-9a-f]+/i)) {
intLiteral = true; intLiteral = true
} }
// Binary // Binary
if (stream.match(/^0b[01]+/i)) { if (stream.match(/^0b[01]+/i)) {
intLiteral = true; intLiteral = true
} }
// Octal // Octal
if (stream.match(/^0o[0-7]+/i)) { if (stream.match(/^0o[0-7]+/i)) {
intLiteral = true; intLiteral = true
} }
// Decimal // Decimal
if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
// Decimal literals may be "imaginary" // Decimal literals may be "imaginary"
stream.eat(/J/i); stream.eat(/J/i)
// TODO - Can you have imaginary longs? // TODO - Can you have imaginary longs?
intLiteral = true; intLiteral = true
} }
// Zero by itself with no other piece of number. // Zero by itself with no other piece of number.
if (stream.match(/^0(?![\dx])/i)) { if (stream.match(/^0(?![\dx])/i)) {
intLiteral = true; intLiteral = true
} }
if (intLiteral) { if (intLiteral) {
// Integer literals may be "long" // Integer literals may be "long"
stream.eat(/L/i); stream.eat(/L/i)
return 'number'; return 'number'
} }
} }
// Handle Strings // Handle Strings
if (stream.match(stringPrefixes)) { if (stream.match(stringPrefixes)) {
state.tokenize = tokenStringFactory(stream.current()); state.tokenize = tokenStringFactory(stream.current())
return state.tokenize(stream, state); return state.tokenize(stream, state)
} }
if (stream.match(operators)) return 'operator'; if (stream.match(operators)) return 'operator'
if (stream.match(keywords)) return 'keyword'; if (stream.match(keywords)) return 'keyword'
if (stream.match(builtins)) return 'builtin'; if (stream.match(builtins)) return 'builtin'
if (stream.match(identifiers)) { if (stream.match(identifiers)) {
if ( if (
state.lastToken != null && state.lastToken != null &&
state.lastToken.match(/proc|iterator|macro|template|class|converter/) state.lastToken.match(/proc|iterator|macro|template|class|converter/)
) { ) {
return 'def'; return 'def'
} }
return 'variable'; return 'variable'
} }
// Handle non-detected items // Handle non-detected items
stream.next(); stream.next()
return ERRORCLASS; return ERRORCLASS
} }
function tokenStringFactory(delimiter) { function tokenStringFactory(delimiter) {
var singleline = delimiter.length == 1; var singleline = delimiter.length == 1
var OUTCLASS = 'string'; var OUTCLASS = 'string'
function tokenString(stream, state) { function tokenString(stream, state) {
while (!stream.eol()) { while (!stream.eol()) {
stream.eatWhile(/[^'"\\]/); stream.eatWhile(/[^'"\\]/)
if (stream.eat('\\')) { if (stream.eat('\\')) {
stream.next(); stream.next()
if (singleline && stream.eol()) { if (singleline && stream.eol()) {
return OUTCLASS; return OUTCLASS
} }
} else if (stream.match(delimiter)) { } else if (stream.match(delimiter)) {
state.tokenize = tokenBase; state.tokenize = tokenBase
return OUTCLASS; return OUTCLASS
} else { } else {
stream.eat(/['"]/); stream.eat(/['"]/)
} }
} }
if (singleline) { if (singleline) {
if (parserConf.singleLineStringErrors) { if (parserConf.singleLineStringErrors) {
return ERRORCLASS; return ERRORCLASS
} else { } else {
state.tokenize = tokenBase; state.tokenize = tokenBase
} }
} }
return OUTCLASS; return OUTCLASS
} }
tokenString.isString = true; tokenString.isString = true
return tokenString; return tokenString
} }
function indent(stream, state, type) { function indent(stream, state, type) {
type = type || 'nim'; type = type || 'nim'
var indentUnit = 0; var indentUnit = 0
if (type === 'nim') { if (type === 'nim') {
if (state.scopes[0].type !== 'nim') { if (state.scopes[0].type !== 'nim') {
state.scopes[0].offset = stream.indentation(); state.scopes[0].offset = stream.indentation()
return; return
} }
for (var i = 0; i < state.scopes.length; ++i) { for (var i = 0; i < state.scopes.length; ++i) {
if (state.scopes[i].type === 'nim') { if (state.scopes[i].type === 'nim') {
indentUnit = state.scopes[i].offset + conf.indentUnit; indentUnit = state.scopes[i].offset + conf.indentUnit
break; break
} }
} }
} else { } else {
indentUnit = stream.column() + stream.current().length; indentUnit = stream.column() + stream.current().length
} }
state.scopes.unshift({ state.scopes.unshift({
offset: indentUnit, offset: indentUnit,
type: type type: type
}); })
} }
function dedent(stream, state, type) { function dedent(stream, state, type) {
type = type || 'nim'; type = type || 'nim'
if (state.scopes.length == 1) return; if (state.scopes.length == 1) return
if (state.scopes[0].type === 'nim') { if (state.scopes[0].type === 'nim') {
var _indent = stream.indentation(); var _indent = stream.indentation()
var _indent_index = -1; var _indent_index = -1
for (var i = 0; i < state.scopes.length; ++i) { for (var i = 0; i < state.scopes.length; ++i) {
if (_indent === state.scopes[i].offset) { if (_indent === state.scopes[i].offset) {
_indent_index = i; _indent_index = i
break; break
} }
} }
if (_indent_index === -1) { if (_indent_index === -1) {
return true; return true
} }
while (state.scopes[0].offset !== _indent) { while (state.scopes[0].offset !== _indent) {
state.scopes.shift(); state.scopes.shift()
} }
return false; return false
} else { } else {
if (type === 'nim') { if (type === 'nim') {
state.scopes[0].offset = stream.indentation(); state.scopes[0].offset = stream.indentation()
return false; return false
} else { } else {
if (state.scopes[0].type != type) { if (state.scopes[0].type != type) {
return true; return true
} }
state.scopes.shift(); state.scopes.shift()
return false; return false
} }
} }
} }
function tokenLexer(stream, state) { function tokenLexer(stream, state) {
indentInfo = null; indentInfo = null
var style = state.tokenize(stream, state); var style = state.tokenize(stream, state)
var current = stream.current(); var current = stream.current()
// Handle '.' connected identifiers // Handle '.' connected identifiers
if (current === '.') { if (current === '.') {
style = stream.match(identifiers, false) ? null : ERRORCLASS; style = stream.match(identifiers, false) ? null : ERRORCLASS
if (style === null && state.lastStyle === 'meta') { if (style === null && state.lastStyle === 'meta') {
// Apply 'meta' style to '.' connected identifiers when // Apply 'meta' style to '.' connected identifiers when
// appropriate. // appropriate.
style = 'meta'; style = 'meta'
} }
return style; return style
} }
if ((style === 'variable' || style === 'builtin') && state.lastStyle === 'meta') { if ((style === 'variable' || style === 'builtin') && state.lastStyle === 'meta') {
style = 'meta'; style = 'meta'
} }
// Handle scope changes. // Handle scope changes.
if (current.match(/return|break|continue|raise/) || (current === 'discard' && stream.eol())) if (current.match(/return|break|continue|raise/) || (current === 'discard' && stream.eol()))
state.dedent += 1; state.dedent += 1
if (current === 'lambda' || current === 'proc') state.lambda = true; if (current === 'lambda' || current === 'proc') state.lambda = true
var delimiter_index = '[({'.indexOf(current); var delimiter_index = '[({'.indexOf(current)
if (delimiter_index !== -1) { if (delimiter_index !== -1) {
indent(stream, state, '])}'.slice(delimiter_index, delimiter_index + 1)); indent(stream, state, '])}'.slice(delimiter_index, delimiter_index + 1))
} else if (stream.eol() && current.match(/\=|\:|import|include|type|const|var|let/)) { } else if (stream.eol() && current.match(/\=|\:|import|include|type|const|var|let/)) {
indent(stream, state); indent(stream, state)
} }
if (indentInfo === 'dedent') { if (indentInfo === 'dedent') {
if (dedent(stream, state)) { if (dedent(stream, state)) {
return ERRORCLASS; return ERRORCLASS
} }
} }
delimiter_index = '])}'.indexOf(current); delimiter_index = '])}'.indexOf(current)
if (delimiter_index !== -1) { if (delimiter_index !== -1) {
if (dedent(stream, state, current)) { if (dedent(stream, state, current)) {
return ERRORCLASS; return ERRORCLASS
} }
} }
if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'nim') { if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'nim') {
if (state.scopes.length > 1) state.scopes.shift(); if (state.scopes.length > 1) state.scopes.shift()
state.dedent -= 1; state.dedent -= 1
} }
return style; return style
} }
var external = { var external = {
@ -571,33 +571,33 @@ CodeMirror.defineMode('nimrod', function(conf, parserConf) {
lastToken: null, lastToken: null,
lambda: false, lambda: false,
dedent: 0 dedent: 0
}; }
}, },
token: function(stream, state) { token: function(stream, state) {
var style = tokenLexer(stream, state); var style = tokenLexer(stream, state)
state.lastStyle = style; state.lastStyle = style
var current = stream.current(); var current = stream.current()
if (current && style) state.lastToken = current; if (current && style) state.lastToken = current
if (stream.eol() && state.lambda) state.lambda = false; if (stream.eol() && state.lambda) state.lambda = false
return style; return style
}, },
indent: function(state) { indent: function(state) {
if (state.tokenize != tokenBase) return state.tokenize.isString ? CodeMirror.Pass : 0; if (state.tokenize != tokenBase) return state.tokenize.isString ? CodeMirror.Pass : 0
return state.scopes[0].offset; return state.scopes[0].offset
}, },
lineComment: '#', lineComment: '#',
fold: 'indent' fold: 'indent'
}; }
return external; return external
}); })
CodeMirror.defineMIME('text/x-nimrod', 'nimrod'); CodeMirror.defineMIME('text/x-nimrod', 'nimrod')

@ -1,8 +1,8 @@
import Page from '../components/Page'; import Page from '../components/Page'
import Meta from '../components/Meta'; import Meta from '../components/Meta'
import Header from '../components/Header'; import Header from '../components/Header'
import Footer from '../components/Footer'; import Footer from '../components/Footer'
import { COLORS } from '../lib/constants'; import { COLORS } from '../lib/constants'
export default () => ( export default () => (
<Page> <Page>
@ -71,4 +71,4 @@ export default () => (
} }
`}</style> `}</style>
</Page> </Page>
); )

@ -1,20 +1,20 @@
// Theirs // Theirs
import React from 'react'; import React from 'react'
import HTML5Backend from 'react-dnd-html5-backend'; import HTML5Backend from 'react-dnd-html5-backend'
import { DragDropContext } from 'react-dnd'; import { DragDropContext } from 'react-dnd'
import domtoimage from 'dom-to-image'; import domtoimage from 'dom-to-image'
import ReadFileDropContainer from 'dropperx'; import ReadFileDropContainer from 'dropperx'
// Ours // Ours
import Page from '../components/Page'; import Page from '../components/Page'
import Button from '../components/Button'; import Button from '../components/Button'
import Dropdown from '../components/Dropdown'; import Dropdown from '../components/Dropdown'
import ColorPicker from '../components/ColorPicker'; import ColorPicker from '../components/ColorPicker'
import Settings from '../components/Settings'; import Settings from '../components/Settings'
import Toolbar from '../components/Toolbar'; import Toolbar from '../components/Toolbar'
import Overlay from '../components/Overlay'; import Overlay from '../components/Overlay'
import Carbon from '../components/Carbon'; import Carbon from '../components/Carbon'
import api from '../lib/api'; import api from '../lib/api'
import { import {
THEMES_ARRAY, THEMES_ARRAY,
THEMES, THEMES,
@ -22,7 +22,7 @@ import {
DEFAULT_LANGUAGE, DEFAULT_LANGUAGE,
COLORS, COLORS,
DEFAULT_CODE DEFAULT_CODE
} from '../lib/constants'; } from '../lib/constants'
class Editor extends React.Component { class Editor extends React.Component {
/* pathname, asPath, err, req, res */ /* pathname, asPath, err, req, res */
@ -30,17 +30,17 @@ class Editor extends React.Component {
try { try {
// TODO fix this hack // TODO fix this hack
if (asPath.length > 30) { if (asPath.length > 30) {
const content = await api.getGist(asPath); const content = await api.getGist(asPath)
return { content }; return { content }
} }
} catch (e) { } catch (e) {
console.log(e); console.log(e)
} }
return {}; return {}
} }
constructor(props) { constructor(props) {
super(props); super(props)
this.state = { this.state = {
background: '#ABB8C3', background: '#ABB8C3',
theme: THEMES.seti.id, theme: THEMES.seti.id,
@ -51,15 +51,15 @@ class Editor extends React.Component {
paddingHorizontal: '32px', paddingHorizontal: '32px',
uploading: false, uploading: false,
code: props.content || DEFAULT_CODE code: props.content || DEFAULT_CODE
}; }
this.save = this.save.bind(this); this.save = this.save.bind(this)
this.upload = this.upload.bind(this); this.upload = this.upload.bind(this)
this.updateCode = this.updateCode.bind(this); this.updateCode = this.updateCode.bind(this)
} }
getCarbonImage() { getCarbonImage() {
const node = document.getElementById('section'); const node = document.getElementById('section')
const config = { const config = {
style: { style: {
@ -68,35 +68,35 @@ class Editor extends React.Component {
}, },
width: node.offsetWidth * 2, width: node.offsetWidth * 2,
height: node.offsetHeight * 2 height: node.offsetHeight * 2
}; }
return domtoimage.toPng(node, config); return domtoimage.toPng(node, config)
} }
updateCode(code) { updateCode(code) {
this.setState({ code }); this.setState({ code })
} }
save() { save() {
this.getCarbonImage().then(dataUrl => { this.getCarbonImage().then(dataUrl => {
const link = document.createElement('a'); const link = document.createElement('a')
link.download = 'carbon.png'; link.download = 'carbon.png'
link.href = dataUrl; link.href = dataUrl
document.body.appendChild(link); document.body.appendChild(link)
link.click(); link.click()
link.remove(); link.remove()
}); })
} }
upload() { upload() {
this.setState({ uploading: true }); this.setState({ uploading: true })
this.getCarbonImage() this.getCarbonImage()
.then(api.tweet) .then(api.tweet)
.then(() => this.setState({ uploading: false })) .then(() => this.setState({ uploading: false }))
.catch(err => { .catch(err => {
console.error(err); console.error(err)
this.setState({ uploading: false }); this.setState({ uploading: false })
}); })
} }
render() { render() {
@ -162,8 +162,8 @@ class Editor extends React.Component {
`} `}
</style> </style>
</Page> </Page>
); )
} }
} }
export default DragDropContext(HTML5Backend)(Editor); export default DragDropContext(HTML5Backend)(Editor)

@ -1,2 +1,2 @@
import Editor from './editor'; import Editor from './editor'
export default Editor; export default Editor

@ -1,38 +1,38 @@
const express = require('express'); const express = require('express')
const morgan = require('morgan'); const morgan = require('morgan')
const bodyParser = require('body-parser'); const bodyParser = require('body-parser')
const next = require('next'); const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000; const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production' && !process.env.NOW; const dev = process.env.NODE_ENV !== 'production' && !process.env.NOW
const app = next({ dev }); const app = next({ dev })
const handle = app.getRequestHandler(); const handle = app.getRequestHandler()
function wrap(handler) { function wrap(handler) {
return (req, res) => return (req, res) =>
handler(req, res).catch(err => { handler(req, res).catch(err => {
console.log('ERR:', err); console.log('ERR:', err)
}); })
} }
app.prepare().then(() => { app.prepare().then(() => {
const server = express(); const server = express()
server.use(morgan('tiny')); server.use(morgan('tiny'))
server.get('/about', (req, res) => app.render(req, res, '/about')); server.get('/about', (req, res) => app.render(req, res, '/about'))
// if root, render webpage from next // if root, render webpage from next
server.get('/*', (req, res) => app.render(req, res, '/', req.query)); server.get('/*', (req, res) => app.render(req, res, '/', req.query))
// otherwise, try and get gist // otherwise, try and get gist
server.get('*', handle); server.get('*', handle)
// api endpoints // api endpoints
server.post('/twitter', bodyParser.json({ limit: '5mb' }), require('./handlers/twitter')); server.post('/twitter', bodyParser.json({ limit: '5mb' }), require('./handlers/twitter'))
server.listen(port, err => { server.listen(port, err => {
if (err) throw err; if (err) throw err
console.log(`> Ready on http://localhost:${port}`); console.log(`> Ready on http://localhost:${port}`)
}); })
}); })

Loading…
Cancel
Save