diff --git a/frontend/src/visualizations/XKCDChart.css b/frontend/src/visualizations/XKCDChart.css new file mode 100644 index 0000000000000000000000000000000000000000..7d12a325ef668e25df4b1d55262c498f13d8d48f --- /dev/null +++ b/frontend/src/visualizations/XKCDChart.css @@ -0,0 +1,27 @@ + +:local(.XKCDChart) { + font-family: "Humor Sans", sans-serif; + font-size: 16px; + color: #333; + text-align: center; +} + +:local(.XKCDChart) text.title { + font-size: 20px; +} + +:local(.XKCDChart) path { + fill: none; + stroke-width: 2.5px; + stroke-linecap: round; + stroke-linejoin: round; +} + +:local(.XKCDChart) path.axis { + stroke: black; +} + +:local(.XKCDChart) path.bgline { + stroke: white; + stroke-width: 6px; +} diff --git a/frontend/src/visualizations/XKCDChart.jsx b/frontend/src/visualizations/XKCDChart.jsx new file mode 100644 index 0000000000000000000000000000000000000000..a8a61456dc9380662155493385fc9623dd242942 --- /dev/null +++ b/frontend/src/visualizations/XKCDChart.jsx @@ -0,0 +1,89 @@ +import React, { Component, PropTypes } from "react"; +import ReactDOM from "react-dom"; + +import styles from "./XKCDChart.css"; + +import { MinColumnsError, MinRowsError } from "metabase/visualizations/lib/errors"; + +import { + getFriendlyName, + getAvailableCanvasWidth, + getAvailableCanvasHeight +} from "metabase/visualizations/lib/utils"; + +import { dimensionIsTimeseries } from "./lib/timeseries"; + +import xkcdplot from "xkcdplot"; +import "xkcdplot/humor-sans"; + +import cx from "classnames"; + +export default class XKCDChart extends Component { + static displayName = "XKCD" + static identifier = "xkcd"; + static iconName = "pinmap"; + + static noHeader = true; + + static isSensible(cols, rows) { + return rows.length > 1 && cols.length > 1; + } + + static checkRenderable(cols, rows) { + if (cols.length < 2) { throw new MinColumnsError(2, cols.length); } + if (rows.length < 1) { throw new MinRowsError(1, rows.length); } + } + + componentDidMount() { + this.componentDidUpdate(); + } + + componentDidUpdate() { + let { series } = this.props; + + let parent = ReactDOM.findDOMNode(this); + while (parent.firstChild) { + parent.removeChild(parent.firstChild); + } + + let margin = 50; + + // Build the plot. + var plot = xkcdplot() + .width(Math.min(800, getAvailableCanvasWidth(parent) - margin * 2)) + .height(Math.min(600, getAvailableCanvasHeight(parent) - margin * 2)) + .margin(margin) + .xlabel(getFriendlyName(series[0].data.cols[0])) + .ylabel(getFriendlyName(series[0].data.cols[1])); + + if (series[0].card.name) { + plot.title(series[0].card.name); + } + + plot(parent); + + let colors = [undefined, "red", "grey", "green", "yellow"]; + let isTimeseries = dimensionIsTimeseries(series[0].data); + series.map((s, index) => { + let data = s.data.rows.map(row => ({ + x: isTimeseries ? new Date(row[0]).getTime() : row[0], + y: row[1] + })); + plot.plot(data, { stroke: colors[index % colors.length] }); + }) + + plot.draw(); + + if (series[0].card.id) { + let title = parent.querySelector(".title"); + title.style = "cursor: pointer;"; + title.addEventListener("click", () => window.location = "/card/" + series[0].card.id); + } + } + + render() { + return ( + <div className={cx(this.props.className, styles.XKCDChart)} /> + ); + } +} diff --git a/frontend/src/visualizations/index.js b/frontend/src/visualizations/index.js index 003a3313c87e1ad956332634ec23099b9723b8c6..bccc333af0fe42898dd3741b04fe3b8985dab5a2 100644 --- a/frontend/src/visualizations/index.js +++ b/frontend/src/visualizations/index.js @@ -35,4 +35,10 @@ registerVisualization(USStateMap); registerVisualization(WorldMap); registerVisualization(PinMap); + +import { enableVisualizationEasterEgg } from "./lib/utils"; +import XKCDChart from "./XKCDChart.jsx"; +import LineAreaBarChart from "./components/LineAreaBarChart.jsx"; +enableVisualizationEasterEgg("XKCD", LineAreaBarChart, XKCDChart); + export default visualizations; diff --git a/frontend/src/visualizations/lib/utils.js b/frontend/src/visualizations/lib/utils.js index 75ed51a3f65ec8307f63d971806f123d2eeb9721..d2d1e333862f91e27eac0534643506489d6ebd95 100644 --- a/frontend/src/visualizations/lib/utils.js +++ b/frontend/src/visualizations/lib/utils.js @@ -1,4 +1,5 @@ +import React from "react"; import _ from "underscore"; import d3 from "d3"; @@ -127,3 +128,41 @@ export function colorShade(hex, shade = 0) { Math.round(min + (max - min) * shade * (c / 255)).toString(16) ).join(""); } + +export function enableVisualizationEasterEgg(code, OriginalVisualization, EasterEggVisualization) { + if (!code) { + code = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]; + } else if (typeof code === "string") { + code = code.split("").map(c => c.charCodeAt(0)); + } + wrapMethod(OriginalVisualization.prototype, "componentWillMount", function easterEgg() { + let keypresses = []; + let enabled = false; + let render_original = this.render; + let render_egg = function() { + return <EasterEggVisualization {...this.props} />; + }; + this._keyListener = (e) => { + keypresses = keypresses.concat(e.keyCode).slice(-code.length); + if (code.reduce((ok, value, index) => ok && value === keypresses[index], true)) { + enabled = !enabled; + this.render = enabled ? render_egg : render_original; + this.forceUpdate(); + } + } + window.addEventListener("keyup", this._keyListener, false); + }); + wrapMethod(OriginalVisualization.prototype, "componentWillUnmount", function cleanupEasterEgg() { + window.removeEventListener("keyup", this._keyListener, false); + }); +} + +function wrapMethod(object, name, method) { + let method_original = object[name]; + object[name] = function() { + method.apply(this, arguments); + if (typeof method_original === "function") { + return method_original.apply(this, arguments); + } + } +} diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index e1dfafcf56936412341f2fd8bc31886a6d9ad19b..0dc7e8e77cce60576fe5e559187fd24ef46fb894 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -5381,6 +5381,9 @@ } } }, + "file-loader": { + "version": "0.8.5" + }, "fixed-data-table": { "version": "0.6.0" }, @@ -7228,7 +7231,7 @@ } }, "which": { - "version": "1.2.0", + "version": "1.2.4", "dependencies": { "is-absolute": { "version": "0.1.7", @@ -7237,6 +7240,9 @@ "version": "0.1.3" } } + }, + "isexe": { + "version": "1.1.2" } } } @@ -7743,7 +7749,7 @@ "version": "0.1.1" }, "es5-ext": { - "version": "0.10.10", + "version": "0.10.11", "dependencies": { "es6-iterator": { "version": "2.0.0" @@ -7808,7 +7814,7 @@ } }, "webpack": { - "version": "1.12.11", + "version": "1.12.14", "dependencies": { "async": { "version": "1.5.2" @@ -7820,7 +7826,7 @@ "version": "0.9.1", "dependencies": { "graceful-fs": { - "version": "4.1.2" + "version": "4.1.3" }, "memory-fs": { "version": "0.2.0" @@ -7828,7 +7834,7 @@ } }, "esprima": { - "version": "2.7.1" + "version": "2.7.2" }, "interpret": { "version": "0.6.6" @@ -7900,7 +7906,7 @@ "version": "0.1.10" }, "uglify-js": { - "version": "2.6.1", + "version": "2.6.2", "dependencies": { "async": { "version": "0.2.10" @@ -7921,16 +7927,16 @@ "version": "2.1.0", "dependencies": { "center-align": { - "version": "0.1.2", + "version": "0.1.3", "dependencies": { "align-text": { - "version": "0.1.3", + "version": "0.1.4", "dependencies": { "kind-of": { - "version": "2.0.1", + "version": "3.0.2", "dependencies": { "is-buffer": { - "version": "1.1.1" + "version": "1.1.2" } } }, @@ -7938,12 +7944,12 @@ "version": "1.0.1" }, "repeat-string": { - "version": "1.5.2" + "version": "1.5.4" } } }, "lazy-cache": { - "version": "0.2.7" + "version": "1.0.3" } } }, @@ -7951,13 +7957,13 @@ "version": "0.1.3", "dependencies": { "align-text": { - "version": "0.1.3", + "version": "0.1.4", "dependencies": { "kind-of": { - "version": "2.0.1", + "version": "3.0.2", "dependencies": { "is-buffer": { - "version": "1.1.1" + "version": "1.1.2" } } }, @@ -7965,7 +7971,7 @@ "version": "1.0.1" }, "repeat-string": { - "version": "1.5.2" + "version": "1.5.4" } } } @@ -7980,7 +7986,7 @@ "version": "1.1.2", "dependencies": { "escape-string-regexp": { - "version": "1.0.4" + "version": "1.0.5" } } }, @@ -7998,7 +8004,7 @@ "version": "0.9.2" }, "chokidar": { - "version": "1.4.2", + "version": "1.4.3", "dependencies": { "anymatch": { "version": "1.3.0", @@ -8044,7 +8050,7 @@ "version": "1.1.5" }, "repeat-string": { - "version": "1.5.2" + "version": "1.5.4" } } } @@ -8062,20 +8068,7 @@ "version": "0.1.4" }, "extglob": { - "version": "0.3.1", - "dependencies": { - "ansi-green": { - "version": "0.1.1", - "dependencies": { - "ansi-wrap": { - "version": "0.1.0" - } - } - }, - "success-symbol": { - "version": "0.1.0" - } - } + "version": "0.3.2" }, "filename-regex": { "version": "2.0.0" @@ -8087,7 +8080,7 @@ "version": "3.0.2", "dependencies": { "is-buffer": { - "version": "1.1.1" + "version": "1.1.2" } } }, @@ -8137,13 +8130,13 @@ } }, "async-each": { - "version": "0.1.6" + "version": "1.0.0" }, "fsevents": { - "version": "1.0.6", + "version": "1.0.8", "dependencies": { "ansi": { - "version": "0.3.0" + "version": "0.3.1" }, "ansi-regex": { "version": "2.0.0" @@ -8152,48 +8145,31 @@ "version": "2.1.0" }, "are-we-there-yet": { - "version": "1.0.4" + "version": "1.0.6" }, "asn1": { "version": "0.2.3" }, "assert-plus": { - "version": "0.1.5" + "version": "0.2.0" }, "async": { - "version": "1.5.0" + "version": "1.5.2" }, "aws-sign2": { "version": "0.6.0" }, - "bl": { - "version": "1.0.0", + "aws4": { + "version": "1.2.1", "dependencies": { - "readable-stream": { - "version": "2.0.4", - "dependencies": { - "core-util-is": { - "version": "1.0.2" - }, - "inherits": { - "version": "2.0.1" - }, - "isarray": { - "version": "0.0.1" - }, - "process-nextick-args": { - "version": "1.0.3" - }, - "string_decoder": { - "version": "0.10.31" - }, - "util-deprecate": { - "version": "1.0.2" - } - } + "lru-cache": { + "version": "2.7.3" } } }, + "bl": { + "version": "1.0.2" + }, "block-stream": { "version": "0.0.8" }, @@ -8219,25 +8195,25 @@ "version": "2.0.5" }, "dashdash": { - "version": "1.10.1" + "version": "1.12.2" }, "debug": { - "version": "0.7.4" + "version": "2.2.0" }, "deep-extend": { - "version": "0.4.0" + "version": "0.4.1" }, "delayed-stream": { "version": "1.0.0" }, "delegates": { - "version": "0.1.0" + "version": "1.0.0" }, "ecc-jsbn": { "version": "0.1.1" }, "escape-string-regexp": { - "version": "1.0.3" + "version": "1.0.4" }, "extend": { "version": "3.0.0" @@ -8261,10 +8237,10 @@ "version": "3.0.0", "dependencies": { "brace-expansion": { - "version": "1.1.1", + "version": "1.1.2", "dependencies": { "balanced-match": { - "version": "0.2.1" + "version": "0.3.0" }, "concat-map": { "version": "0.0.1" @@ -8276,7 +8252,7 @@ } }, "gauge": { - "version": "1.2.2" + "version": "1.2.5" }, "generate-function": { "version": "2.0.0" @@ -8285,28 +8261,28 @@ "version": "1.2.0" }, "graceful-fs": { - "version": "4.1.2" + "version": "4.1.3" }, "graceful-readlink": { "version": "1.0.1" }, "har-validator": { - "version": "2.0.3" + "version": "2.0.6" }, "has-ansi": { "version": "2.0.0" }, "has-unicode": { - "version": "1.0.1" + "version": "2.0.0" }, "hawk": { - "version": "3.1.2" + "version": "3.1.3" }, "hoek": { "version": "2.16.3" }, "http-signature": { - "version": "1.1.0" + "version": "1.1.1" }, "inherits": { "version": "2.0.1" @@ -8315,7 +8291,7 @@ "version": "1.3.4" }, "is-my-json-valid": { - "version": "2.12.3" + "version": "2.12.4" }, "is-property": { "version": "1.0.2" @@ -8353,8 +8329,11 @@ "lodash._createpadding": { "version": "3.6.1" }, + "lodash._root": { + "version": "3.0.0" + }, "lodash.pad": { - "version": "3.1.1" + "version": "3.3.0" }, "lodash.padleft": { "version": "3.1.1" @@ -8363,13 +8342,13 @@ "version": "3.1.1" }, "lodash.repeat": { - "version": "3.0.1" + "version": "3.2.0" }, "mime-db": { - "version": "1.19.0" + "version": "1.21.0" }, "mime-types": { - "version": "2.1.7" + "version": "2.1.9" }, "minimist": { "version": "0.0.8" @@ -8377,11 +8356,14 @@ "mkdirp": { "version": "0.5.1" }, + "ms": { + "version": "0.7.1" + }, "nan": { "version": "2.2.0" }, "node-pre-gyp": { - "version": "0.6.17", + "version": "0.6.21", "dependencies": { "nopt": { "version": "3.0.6", @@ -8397,25 +8379,28 @@ "version": "1.4.7" }, "npmlog": { - "version": "2.0.0" + "version": "2.0.2" }, "oauth-sign": { - "version": "0.8.0" + "version": "0.8.1" }, "once": { - "version": "1.1.1" + "version": "1.3.3" }, "pinkie": { - "version": "2.0.1" + "version": "2.0.4" }, "pinkie-promise": { "version": "2.0.0" }, + "process-nextick-args": { + "version": "1.0.6" + }, "qs": { - "version": "5.2.0" + "version": "6.0.2" }, "rc": { - "version": "1.1.5", + "version": "1.1.6", "dependencies": { "minimist": { "version": "1.2.0" @@ -8423,16 +8408,16 @@ } }, "readable-stream": { - "version": "1.1.13" + "version": "2.0.5" }, "request": { - "version": "2.67.0" + "version": "2.69.0" }, "rimraf": { - "version": "2.4.4", + "version": "2.5.1", "dependencies": { "glob": { - "version": "5.0.15", + "version": "6.0.4", "dependencies": { "inflight": { "version": "1.0.4", @@ -8449,10 +8434,10 @@ "version": "3.0.0", "dependencies": { "brace-expansion": { - "version": "1.1.1", + "version": "1.1.2", "dependencies": { "balanced-match": { - "version": "0.2.1" + "version": "0.3.0" }, "concat-map": { "version": "0.0.1" @@ -8483,12 +8468,7 @@ "version": "1.0.9" }, "sshpk": { - "version": "1.7.0", - "dependencies": { - "assert-plus": { - "version": "0.2.0" - } - } + "version": "1.7.3" }, "string_decoder": { "version": "0.10.31" @@ -8509,45 +8489,29 @@ "version": "2.2.1" }, "tar-pack": { - "version": "3.1.0", - "dependencies": { - "readable-stream": { - "version": "1.0.33", - "dependencies": { - "core-util-is": { - "version": "1.0.2" - }, - "inherits": { - "version": "2.0.1" - }, - "isarray": { - "version": "0.0.1" - }, - "string_decoder": { - "version": "0.10.31" - } - } - }, - "rimraf": { - "version": "2.2.8" - } - } + "version": "3.1.3" }, "tough-cookie": { "version": "2.2.1" }, "tunnel-agent": { - "version": "0.4.1" + "version": "0.4.2" }, "tweetnacl": { - "version": "0.13.2" + "version": "0.13.3" }, "uid-number": { - "version": "0.0.3" + "version": "0.0.6" + }, + "util-deprecate": { + "version": "1.0.2" }, "verror": { "version": "1.3.6" }, + "wrappy": { + "version": "1.0.1" + }, "xtend": { "version": "4.0.1" } @@ -8585,7 +8549,7 @@ "version": "2.0.10", "dependencies": { "brace-expansion": { - "version": "1.1.2", + "version": "1.1.3", "dependencies": { "balanced-match": { "version": "0.3.0" @@ -8622,7 +8586,7 @@ } }, "graceful-fs": { - "version": "4.1.2" + "version": "4.1.3" } } }, @@ -8645,7 +8609,7 @@ } }, "webpack-dev-middleware": { - "version": "1.4.0", + "version": "1.5.1", "dependencies": { "memory-fs": { "version": "0.3.0", @@ -8659,7 +8623,7 @@ } }, "readable-stream": { - "version": "2.0.4", + "version": "2.0.5", "dependencies": { "core-util-is": { "version": "1.0.2" @@ -9639,7 +9603,7 @@ "version": "0.5.0" }, "bl": { - "version": "0.9.4", + "version": "0.9.5", "dependencies": { "readable-stream": { "version": "1.0.33", @@ -9703,7 +9667,7 @@ "version": "2.1.0" }, "escape-string-regexp": { - "version": "1.0.3" + "version": "1.0.4" }, "has-ansi": { "version": "2.0.0", @@ -9735,7 +9699,7 @@ } }, "is-my-json-valid": { - "version": "2.12.3", + "version": "2.12.4", "dependencies": { "generate-function": { "version": "2.0.0" @@ -9807,7 +9771,7 @@ "version": "1.4.7" }, "oauth-sign": { - "version": "0.8.0" + "version": "0.8.1" }, "qs": { "version": "3.1.0" @@ -9856,10 +9820,10 @@ "version": "2.47.0", "dependencies": { "rimraf": { - "version": "2.4.4", + "version": "2.5.2", "dependencies": { "glob": { - "version": "5.0.15", + "version": "7.0.0", "dependencies": { "inflight": { "version": "1.0.4", @@ -9876,7 +9840,7 @@ "version": "3.0.0", "dependencies": { "brace-expansion": { - "version": "1.1.2", + "version": "1.1.3", "dependencies": { "balanced-match": { "version": "0.3.0" @@ -9916,7 +9880,7 @@ "version": "1.2.1" }, "nan": { - "version": "2.1.0" + "version": "2.2.0" } } }, @@ -9933,7 +9897,7 @@ "version": "1.2.1" }, "nan": { - "version": "2.1.0" + "version": "2.2.0" } } } @@ -9946,10 +9910,10 @@ "version": "0.6.1" }, "xmlbuilder": { - "version": "4.1.0", + "version": "4.2.1", "dependencies": { "lodash": { - "version": "3.10.1" + "version": "4.3.0" } } } @@ -11421,9 +11385,32 @@ } } }, - "webpack-dev-middleware": { - "version": "1.5.1", + "webpack": { + "version": "1.12.14", "dependencies": { + "async": { + "version": "1.5.2" + }, + "clone": { + "version": "1.0.2" + }, + "enhanced-resolve": { + "version": "0.9.1", + "dependencies": { + "graceful-fs": { + "version": "4.1.3" + }, + "memory-fs": { + "version": "0.2.0" + } + } + }, + "esprima": { + "version": "2.7.2" + }, + "interpret": { + "version": "0.6.6" + }, "memory-fs": { "version": "0.3.0", "dependencies": { @@ -11460,42 +11447,798 @@ } } }, - "mime": { - "version": "1.3.4" - } - } - } - } - }, - "webpack-postcss-tools": { - "version": "1.1.1", - "dependencies": { - "lodash": { - "version": "3.10.1" - }, - "postcss": { - "version": "4.1.16", - "dependencies": { - "es6-promise": { - "version": "2.3.0" - }, - "js-base64": { - "version": "2.1.9" - }, - "source-map": { - "version": "0.4.4", + "mkdirp": { + "version": "0.5.1", "dependencies": { - "amdefine": { - "version": "1.0.0" + "minimist": { + "version": "0.0.8" } } - } - } - }, - "resolve": { - "version": "1.1.7" - } - } + }, + "tapable": { + "version": "0.1.10" + }, + "uglify-js": { + "version": "2.6.2", + "dependencies": { + "async": { + "version": "0.2.10" + }, + "source-map": { + "version": "0.5.3" + }, + "uglify-to-browserify": { + "version": "1.0.2" + }, + "yargs": { + "version": "3.10.0", + "dependencies": { + "camelcase": { + "version": "1.2.1" + }, + "cliui": { + "version": "2.1.0", + "dependencies": { + "center-align": { + "version": "0.1.3", + "dependencies": { + "align-text": { + "version": "0.1.4", + "dependencies": { + "kind-of": { + "version": "3.0.2", + "dependencies": { + "is-buffer": { + "version": "1.1.2" + } + } + }, + "longest": { + "version": "1.0.1" + }, + "repeat-string": { + "version": "1.5.4" + } + } + }, + "lazy-cache": { + "version": "1.0.3" + } + } + }, + "right-align": { + "version": "0.1.3", + "dependencies": { + "align-text": { + "version": "0.1.4", + "dependencies": { + "kind-of": { + "version": "3.0.2", + "dependencies": { + "is-buffer": { + "version": "1.1.2" + } + } + }, + "longest": { + "version": "1.0.1" + }, + "repeat-string": { + "version": "1.5.4" + } + } + } + } + }, + "wordwrap": { + "version": "0.0.2" + } + } + }, + "decamelize": { + "version": "1.1.2", + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5" + } + } + }, + "window-size": { + "version": "0.1.0" + } + } + } + } + }, + "watchpack": { + "version": "0.2.9", + "dependencies": { + "async": { + "version": "0.9.2" + }, + "chokidar": { + "version": "1.4.3", + "dependencies": { + "anymatch": { + "version": "1.3.0", + "dependencies": { + "arrify": { + "version": "1.0.1" + }, + "micromatch": { + "version": "2.3.7", + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "dependencies": { + "arr-flatten": { + "version": "1.0.1" + } + } + }, + "array-unique": { + "version": "0.2.1" + }, + "braces": { + "version": "1.8.3", + "dependencies": { + "expand-range": { + "version": "1.8.1", + "dependencies": { + "fill-range": { + "version": "2.2.3", + "dependencies": { + "is-number": { + "version": "2.1.0" + }, + "isobject": { + "version": "2.0.0", + "dependencies": { + "isarray": { + "version": "0.0.1" + } + } + }, + "randomatic": { + "version": "1.1.5" + }, + "repeat-string": { + "version": "1.5.4" + } + } + } + } + }, + "preserve": { + "version": "0.2.0" + }, + "repeat-element": { + "version": "1.1.2" + } + } + }, + "expand-brackets": { + "version": "0.1.4" + }, + "extglob": { + "version": "0.3.2" + }, + "filename-regex": { + "version": "2.0.0" + }, + "is-extglob": { + "version": "1.0.0" + }, + "kind-of": { + "version": "3.0.2", + "dependencies": { + "is-buffer": { + "version": "1.1.2" + } + } + }, + "normalize-path": { + "version": "2.0.1" + }, + "object.omit": { + "version": "2.0.0", + "dependencies": { + "for-own": { + "version": "0.1.3", + "dependencies": { + "for-in": { + "version": "0.1.4" + } + } + }, + "is-extendable": { + "version": "0.1.1" + } + } + }, + "parse-glob": { + "version": "3.0.4", + "dependencies": { + "glob-base": { + "version": "0.3.0" + }, + "is-dotfile": { + "version": "1.0.2" + } + } + }, + "regex-cache": { + "version": "0.4.2", + "dependencies": { + "is-equal-shallow": { + "version": "0.1.3" + }, + "is-primitive": { + "version": "2.0.0" + } + } + } + } + } + } + }, + "async-each": { + "version": "1.0.0" + }, + "fsevents": { + "version": "1.0.8", + "dependencies": { + "ansi": { + "version": "0.3.1" + }, + "ansi-regex": { + "version": "2.0.0" + }, + "ansi-styles": { + "version": "2.1.0" + }, + "are-we-there-yet": { + "version": "1.0.6" + }, + "asn1": { + "version": "0.2.3" + }, + "assert-plus": { + "version": "0.2.0" + }, + "async": { + "version": "1.5.2" + }, + "aws-sign2": { + "version": "0.6.0" + }, + "aws4": { + "version": "1.2.1", + "dependencies": { + "lru-cache": { + "version": "2.7.3" + } + } + }, + "bl": { + "version": "1.0.2" + }, + "block-stream": { + "version": "0.0.8" + }, + "boom": { + "version": "2.10.1" + }, + "caseless": { + "version": "0.11.0" + }, + "chalk": { + "version": "1.1.1" + }, + "combined-stream": { + "version": "1.0.5" + }, + "commander": { + "version": "2.9.0" + }, + "core-util-is": { + "version": "1.0.2" + }, + "cryptiles": { + "version": "2.0.5" + }, + "dashdash": { + "version": "1.12.2" + }, + "debug": { + "version": "2.2.0" + }, + "deep-extend": { + "version": "0.4.1" + }, + "delayed-stream": { + "version": "1.0.0" + }, + "delegates": { + "version": "1.0.0" + }, + "ecc-jsbn": { + "version": "0.1.1" + }, + "escape-string-regexp": { + "version": "1.0.4" + }, + "extend": { + "version": "3.0.0" + }, + "extsprintf": { + "version": "1.0.2" + }, + "forever-agent": { + "version": "0.6.1" + }, + "form-data": { + "version": "1.0.0-rc3" + }, + "fstream": { + "version": "1.0.8" + }, + "fstream-ignore": { + "version": "1.0.3", + "dependencies": { + "minimatch": { + "version": "3.0.0", + "dependencies": { + "brace-expansion": { + "version": "1.1.2", + "dependencies": { + "balanced-match": { + "version": "0.3.0" + }, + "concat-map": { + "version": "0.0.1" + } + } + } + } + } + } + }, + "gauge": { + "version": "1.2.5" + }, + "generate-function": { + "version": "2.0.0" + }, + "generate-object-property": { + "version": "1.2.0" + }, + "graceful-fs": { + "version": "4.1.3" + }, + "graceful-readlink": { + "version": "1.0.1" + }, + "har-validator": { + "version": "2.0.6" + }, + "has-ansi": { + "version": "2.0.0" + }, + "has-unicode": { + "version": "2.0.0" + }, + "hawk": { + "version": "3.1.3" + }, + "hoek": { + "version": "2.16.3" + }, + "http-signature": { + "version": "1.1.1" + }, + "inherits": { + "version": "2.0.1" + }, + "ini": { + "version": "1.3.4" + }, + "is-my-json-valid": { + "version": "2.12.4" + }, + "is-property": { + "version": "1.0.2" + }, + "is-typedarray": { + "version": "1.0.0" + }, + "isarray": { + "version": "0.0.1" + }, + "isstream": { + "version": "0.1.2" + }, + "jodid25519": { + "version": "1.0.2" + }, + "jsbn": { + "version": "0.1.0" + }, + "json-schema": { + "version": "0.2.2" + }, + "json-stringify-safe": { + "version": "5.0.1" + }, + "jsonpointer": { + "version": "2.0.0" + }, + "jsprim": { + "version": "1.2.2" + }, + "lodash._basetostring": { + "version": "3.0.1" + }, + "lodash._createpadding": { + "version": "3.6.1" + }, + "lodash._root": { + "version": "3.0.0" + }, + "lodash.pad": { + "version": "3.3.0" + }, + "lodash.padleft": { + "version": "3.1.1" + }, + "lodash.padright": { + "version": "3.1.1" + }, + "lodash.repeat": { + "version": "3.2.0" + }, + "mime-db": { + "version": "1.21.0" + }, + "mime-types": { + "version": "2.1.9" + }, + "minimist": { + "version": "0.0.8" + }, + "mkdirp": { + "version": "0.5.1" + }, + "ms": { + "version": "0.7.1" + }, + "nan": { + "version": "2.2.0" + }, + "node-pre-gyp": { + "version": "0.6.21", + "dependencies": { + "nopt": { + "version": "3.0.6", + "dependencies": { + "abbrev": { + "version": "1.0.7" + } + } + } + } + }, + "node-uuid": { + "version": "1.4.7" + }, + "npmlog": { + "version": "2.0.2" + }, + "oauth-sign": { + "version": "0.8.1" + }, + "once": { + "version": "1.3.3" + }, + "pinkie": { + "version": "2.0.4" + }, + "pinkie-promise": { + "version": "2.0.0" + }, + "process-nextick-args": { + "version": "1.0.6" + }, + "qs": { + "version": "6.0.2" + }, + "rc": { + "version": "1.1.6", + "dependencies": { + "minimist": { + "version": "1.2.0" + } + } + }, + "readable-stream": { + "version": "2.0.5" + }, + "request": { + "version": "2.69.0" + }, + "rimraf": { + "version": "2.5.1", + "dependencies": { + "glob": { + "version": "6.0.4", + "dependencies": { + "inflight": { + "version": "1.0.4", + "dependencies": { + "wrappy": { + "version": "1.0.1" + } + } + }, + "inherits": { + "version": "2.0.1" + }, + "minimatch": { + "version": "3.0.0", + "dependencies": { + "brace-expansion": { + "version": "1.1.2", + "dependencies": { + "balanced-match": { + "version": "0.3.0" + }, + "concat-map": { + "version": "0.0.1" + } + } + } + } + }, + "once": { + "version": "1.3.3", + "dependencies": { + "wrappy": { + "version": "1.0.1" + } + } + }, + "path-is-absolute": { + "version": "1.0.0" + } + } + } + } + }, + "semver": { + "version": "5.1.0" + }, + "sntp": { + "version": "1.0.9" + }, + "sshpk": { + "version": "1.7.3" + }, + "string_decoder": { + "version": "0.10.31" + }, + "stringstream": { + "version": "0.0.5" + }, + "strip-ansi": { + "version": "3.0.0" + }, + "strip-json-comments": { + "version": "1.0.4" + }, + "supports-color": { + "version": "2.0.0" + }, + "tar": { + "version": "2.2.1" + }, + "tar-pack": { + "version": "3.1.3" + }, + "tough-cookie": { + "version": "2.2.1" + }, + "tunnel-agent": { + "version": "0.4.2" + }, + "tweetnacl": { + "version": "0.13.3" + }, + "uid-number": { + "version": "0.0.6" + }, + "util-deprecate": { + "version": "1.0.2" + }, + "verror": { + "version": "1.3.6" + }, + "wrappy": { + "version": "1.0.1" + }, + "xtend": { + "version": "4.0.1" + } + } + }, + "glob-parent": { + "version": "2.0.0" + }, + "inherits": { + "version": "2.0.1" + }, + "is-binary-path": { + "version": "1.0.1", + "dependencies": { + "binary-extensions": { + "version": "1.4.0" + } + } + }, + "is-glob": { + "version": "2.0.1", + "dependencies": { + "is-extglob": { + "version": "1.0.0" + } + } + }, + "path-is-absolute": { + "version": "1.0.0" + }, + "readdirp": { + "version": "2.0.0", + "dependencies": { + "minimatch": { + "version": "2.0.10", + "dependencies": { + "brace-expansion": { + "version": "1.1.3", + "dependencies": { + "balanced-match": { + "version": "0.3.0" + }, + "concat-map": { + "version": "0.0.1" + } + } + } + } + }, + "readable-stream": { + "version": "2.0.5", + "dependencies": { + "core-util-is": { + "version": "1.0.2" + }, + "isarray": { + "version": "0.0.1" + }, + "process-nextick-args": { + "version": "1.0.6" + }, + "string_decoder": { + "version": "0.10.31" + }, + "util-deprecate": { + "version": "1.0.2" + } + } + } + } + } + } + }, + "graceful-fs": { + "version": "4.1.3" + } + } + }, + "webpack-core": { + "version": "0.6.8", + "dependencies": { + "source-list-map": { + "version": "0.1.5" + }, + "source-map": { + "version": "0.4.4", + "dependencies": { + "amdefine": { + "version": "1.0.0" + } + } + } + } + } + } + }, + "webpack-dev-middleware": { + "version": "1.5.1", + "dependencies": { + "memory-fs": { + "version": "0.3.0", + "dependencies": { + "errno": { + "version": "0.1.4", + "dependencies": { + "prr": { + "version": "0.0.0" + } + } + }, + "readable-stream": { + "version": "2.0.5", + "dependencies": { + "core-util-is": { + "version": "1.0.2" + }, + "inherits": { + "version": "2.0.1" + }, + "isarray": { + "version": "0.0.1" + }, + "process-nextick-args": { + "version": "1.0.6" + }, + "string_decoder": { + "version": "0.10.31" + }, + "util-deprecate": { + "version": "1.0.2" + } + } + } + } + }, + "mime": { + "version": "1.3.4" + } + } + } + } + }, + "webpack-postcss-tools": { + "version": "1.1.1", + "dependencies": { + "lodash": { + "version": "3.10.1" + }, + "postcss": { + "version": "4.1.16", + "dependencies": { + "es6-promise": { + "version": "2.3.0" + }, + "js-base64": { + "version": "2.1.9" + }, + "source-map": { + "version": "0.4.4", + "dependencies": { + "amdefine": { + "version": "1.0.0" + } + } + } + } + }, + "resolve": { + "version": "1.1.7" + } + } + }, + "xkcdplot": { + "version": "1.1.0" }, "z-index": { "version": "0.0.1" diff --git a/package.json b/package.json index d7c6fef70bf1afa8bf1305ddb8b7b35163b93555..0ffe1b1891d32521a1b1bd9b2da2210c6e6cd237 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "screenfull": "^3.0.0", "tether": "^1.2.0", "underscore": "^1.8.3", + "xkcdplot": "^1.1.0", "z-index": "0.0.1" }, "devDependencies": { @@ -66,6 +67,7 @@ "eslint-loader": "^1.3.0", "eslint-plugin-react": "^4.1.0", "extract-text-webpack-plugin": "^1.0.1", + "file-loader": "^0.8.5", "glob": "^5.0.15", "html-webpack-plugin": "^2.9.0", "istanbul-instrumenter-loader": "^0.2.0", diff --git a/src/metabase/middleware.clj b/src/metabase/middleware.clj index 87c5f4af01aae3fda515606873587deba0d04ff0..04369f1688d16bab6c40ab08f870415c0029a88d 100644 --- a/src/metabase/middleware.clj +++ b/src/metabase/middleware.clj @@ -151,8 +151,11 @@ :style-src ["'unsafe-inline'" "'self'" "fonts.googleapis.com"] - :font-src ["fonts.gstatic.com" - "themes.googleusercontent.com"] + :font-src ["'self'" + "fonts.gstatic.com" + "themes.googleusercontent.com" + (when config/is-dev? + "localhost:8080")] :img-src ["*" "self data:"] :connect-src ["'self'" diff --git a/webpack.config.js b/webpack.config.js index d97699cc4befbf9514f7600567fb2c331a6fdecf..50c21f2c815ff2797dcb29168e38d8ff81eb1007 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -82,7 +82,7 @@ var config = module.exports = { path: BUILD_PATH + '/app/dist', // NOTE: the filename on disk won't include "?[chunkhash]" but the URL in index.html generated by HtmlWebpackPlugin will: filename: '[name].bundle.js?[hash]', - publicPath: '/app/dist' + publicPath: '/app/dist/' }, module: { @@ -98,6 +98,10 @@ var config = module.exports = { exclude: /node_modules|\.spec\.js/, loader: 'eslint' }, + { + test: /\.(eot|woff2?|ttf|svg)$/, + loader: "file-loader" + }, { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader?" + JSON.stringify(CSS_CONFIG) + "!postcss-loader")