UNPKG

libre

Version:
724 lines (555 loc) 23.8 kB
(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 5); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = require("lodash"); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); exports.goto = goto; var _reactRouter = __webpack_require__(11); var _lodash = __webpack_require__(0); var _lodash2 = _interopRequireDefault(_lodash); var _reactGa = __webpack_require__(10); var _reactGa2 = _interopRequireDefault(_reactGa); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function goto(path) { _reactRouter.browserHistory.push(path); }; var Packet = function () { function Packet(_ref) { var category = _ref.category, action = _ref.action, label = _ref.label, data = _ref.data; _classCallCheck(this, Packet); _lodash2.default.assign(this, { category: category, action: action, label: label, data: data }); } _createClass(Packet, [{ key: 'ga', get: function get() { return { category: this.category, action: this.action, label: this.label, value: this.data }; } }]); return Packet; }(); var Dealer = function () { function Dealer() { _classCallCheck(this, Dealer); } _createClass(Dealer, [{ key: 'init', value: function init(gaID) { _reactGa2.default.initialize(gaID); } }, { key: 'call', value: function call(packetData) { var packet = new Packet(packetData); _reactGa2.default.event(packet.ga); // console.log('[DEALER] EVENT:', packet.ga); } }, { key: 'page', value: function page() { _reactGa2.default.set({ page: window.location.pathname }); _reactGa2.default.pageview(window.location.pathname); console.log('[LIBRE] PAGE: [' + window.location.pathname + ']'); } }]); return Dealer; }(); var D = new Dealer(); exports.default = D; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _axios = __webpack_require__(6); var _axios2 = _interopRequireDefault(_axios); var _lodash = __webpack_require__(0); var _lodash2 = _interopRequireDefault(_lodash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Libre = function () { function Libre() { _classCallCheck(this, Libre); this.path = '/libre'; this.raw = {}; this.typed = {}; this.grouped = {}; this.typeMap = {}; this.plugins = {}; } _createClass(Libre, [{ key: 'setup', value: function setup(_ref) { var typeMap = _ref.typeMap, plugins = _ref.plugins; if (typeMap) this.typeMap = typeMap; if (plugins) this.plugins = plugins; } //retrieve a simple piece of content based on unique id }, { key: 'get', value: function get(key, applyPlugins) { var _this = this; var c = this.raw[key]; if (c == null) return []; if (!applyPlugins || !c.content) return c.content || []; //if applyPlugins, also call process to run string interpolation plugins //content is a special field and is an automatic array of lines (split on \n) from the source Sheet //so we also use spread operator to flatten the output into a single array of pieces var processed = []; c.content.map(function (line) { return processed.push.apply(processed, _toConsumableArray(_this.process(line))); }); return processed; } //retrieve a model for structured content based on a path }, { key: 'getTyped', value: function getTyped(path, type) { var items = _lodash2.default.filter(this.typed, function (t) { return t.path == path && t.constructor.name == type.name; }); return items.length > 0 ? items[0] : {}; } //create array of typed objects corresponding to a tab in the spreadsheet and given model class }, { key: 'model', value: function model(sheet, type) { var _this2 = this; var raw = _lodash2.default.filter(this.raw, { sheet: sheet }); var items = []; raw.map(function (json) { var typed = new type(json, _this2); _this2.typed[typed.id] = typed; items.push(typed); }); this.grouped[sheet] = items; return items; } }, { key: 'load', value: function load(success) { var _this3 = this; _axios2.default.get(this.path).then(function (_ref2) { var data = _ref2.data; _this3.init(data); if (typeof success == 'function') success(_this3); }); } }, { key: 'push', value: function push(tab, row, success) { _axios2.default.post(this.path + '/push', { tab: tab, row: row }).then(function (result) { if (typeof success == 'function') success(result); }); } }, { key: 'init', value: function init(data) { var _this4 = this; var loaded = []; //add the sheet name to the source data _lodash2.default.forOwn(data, function (tab, sheet) { _lodash2.default.forOwn(tab, function (item) { return item.sheet = sheet; }); loaded.push(sheet); //merge results into overall content store _lodash2.default.assign(_this4.raw, tab); }); console.log('[LIBRE] Content loaded for [' + loaded.join(', ') + ']'); //after all raw content is loaded //create typed model classes of all content based on map in config.js //TODO: add properties to routes because this is overly rigid (route key needs to match sheet name) //typeMap config object tells us what model types to create for each sheet _lodash2.default.forOwn(this.typeMap, function (type, sheet) { return _this4.model(sheet, type); }); } //force sever to re-ingest static content from google doc }, { key: 'refresh', value: function refresh(success) { var _this5 = this; //collect all sheets from what is currently loaded var tabs = []; _lodash2.default.forOwn(this.raw, function (c) { if (tabs.indexOf(c.sheet) < 0) tabs.push(c.sheet); }); console.log('[LIBRE] Refreshing cached content on server...'); _axios2.default.post('/libre/refresh', { tabs: tabs }).then(function (_ref3) { var data = _ref3.data; console.log('[LIBRE] Content refresh complete on server.'); _this5.init(data); success(_this5); }); } //for given text, apply interpolation plugins and return array of pieces for rendering }, { key: 'process', value: function process(text) { var plugins = this.plugins; if (!text || !plugins) return []; var pieces = [], ranges = []; //1. run through all plugins to find matches to be replaced _lodash2.default.forOwn(plugins, function (plugin, type) { var pattern = plugin.pattern; var match = void 0, start = void 0, end = void 0; //each plugin can have multiple matches -- keep going to find them all while ((match = pattern.exec(text)) !== null) { start = match.index; end = start + match[0].length; ranges.push({ type: type, start: start, end: end, match: match }); } }); //if we find nothing, just convert the whole thing to 1 plain piece if (ranges.length == 0) return [{ type: 'plain', text: text }]; //2. sort by starting position ranges = _lodash2.default.sortBy(ranges, 'start'); //3. fill in the gaps with plain text for (var i = 0; i < ranges.length; i++) { //if we're looking at a plain (added) piece or the last piece, skip if (ranges[i].type == 'plain' || i + 1 == ranges.length) continue; var plain = { type: 'plain', start: ranges[i].end, end: ranges[i + 1].start }; if (plain.end > plain.start) ranges.push(plain); } //4. sort again -- now we have everything from the first matched range to the last ranges = _lodash2.default.sortBy(ranges, 'start'); //add plain piece at beginning and end if necessary (the above loop ignores these edge cases) if (ranges[0].start > 0) ranges.splice(0, 0, { type: 'plain', start: 0, end: ranges[0].start }); if (ranges[ranges.length - 1].end < text.length) ranges.push({ type: 'plain', start: ranges[ranges.length - 1].end, end: text.length }); //5. now populate with the actual text content ranges.map(function (r) { return pieces.push({ type: r.type, text: text.substring(r.start, r.end), match: r.match }); }); return pieces; } }]); return Libre; }(); var libre = new Libre(); if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) == 'object') window.Libre = libre; exports.default = libre; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = __webpack_require__(8); var _react2 = _interopRequireDefault(_react); var _reactRouterDom = __webpack_require__(12); var _history = __webpack_require__(7); var _reactDom = __webpack_require__(9); var _reactDom2 = _interopRequireDefault(_reactDom); var _Libre = __webpack_require__(2); var _Libre2 = _interopRequireDefault(_Libre); var _Dealer = __webpack_require__(1); var _Dealer2 = _interopRequireDefault(_Dealer); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Client = function (_Component) { _inherits(Client, _Component); function Client(props) { _classCallCheck(this, Client); var _this = _possibleConstructorReturn(this, (Client.__proto__ || Object.getPrototypeOf(Client)).call(this, props)); _this.state = { refreshing: false, libre: null }; _this.globals = { refresh: function refresh() { return _this.refresh(); }, og: function og(tags) { return _this.og(tags); } // push: (tab, row, success) => this.push(tab, row, success) }; return _this; } _createClass(Client, [{ key: 'componentWillMount', value: function componentWillMount() { var _this2 = this; _Libre2.default.load(function (libre) { return _this2.setState({ libre: libre }); }); } //to make content production easier, the client app can expose a refresh button //pushing content to app state on load also causes components to re-render live //(whether they use it or not) //because App state is passed to all child components as props }, { key: 'refresh', value: function refresh() { var _this3 = this; this.setState({ refreshing: true }); _Libre2.default.refresh(function (libre) { return _this3.setState({ refreshing: false, libre: libre }); }); } }, { key: 'og', value: function og(tags) { if ((typeof document === 'undefined' ? 'undefined' : _typeof(document)) === 'object') { if (tags.title) document.title = tags.title; if (tags.description) { var meta = document.querySelector('meta[name="description"]'); if (meta != null) meta.setAttribute('content', tags.description); } } } }, { key: 'render', value: function render() { var _this4 = this; var _props = this.props, App = _props.App, routes = _props.routes; if (!this.state.libre) return null; return _react2.default.createElement(_reactRouterDom.Route, { render: function render(r) { return _react2.default.createElement( App, _extends({}, r, _this4.state, _this4.globals), _react2.default.createElement( _reactRouterDom.Switch, null, Object.keys(routes).map(function (key) { return _this4.renderRoute(key, routes[key]); }) ) ); } }); } }, { key: 'renderRoute', value: function renderRoute(key, route) { var _this5 = this; var routeProps = { exact: key === '/', key: key, path: key }; var Component = route.component; return _react2.default.createElement(_reactRouterDom.Route, _extends({}, routeProps, { render: function render(r) { return _react2.default.createElement(Component, _extends({}, r, _this5.state, _this5.globals)); } })); } }], [{ key: 'run', value: function run(App, routes, config, typeMap, plugins) { if (config.GA_ID) _Dealer2.default.init(config.GA_ID); _Libre2.default.setup({ typeMap: typeMap, plugins: plugins }); //pass other config data into app instance via route props var renderProps = { config: config, typeMap: typeMap, App: App, routes: routes }; var history = (0, _history.createBrowserHistory)(); //track current (first) page, and listen for subsequent updates _Dealer2.default.page(); history.listen(function (location) { _Dealer2.default.page(); }); _reactDom2.default.render(_react2.default.createElement( _reactRouterDom.Router, { history: history }, _react2.default.createElement(Client, renderProps) ), document.querySelector('#app')); } }]); return Client; }(_react.Component); exports.default = Client; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _lodash = __webpack_require__(0); var _lodash2 = _interopRequireDefault(_lodash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Item = function () { function Item(_ref, libre) { var _this = this; var id = _ref.id, title = _ref.title, links = _ref.links, path = _ref.path; _classCallCheck(this, Item); this.libre = libre; _lodash2.default.assign(this, { id: id, title: title, path: path }); this.links = []; if (links && links != '') { var lines = links.split('\n'); lines.map(function (link) { var pieces = link.split('|'); if (pieces.length >= 2) _this.links.push({ title: pieces[0], url: pieces[1] }); }); } } //for a given field, split into sections based on line breaks (\n) //ignoring empty (double) breaks //auto run Libre.process() on sections, so this will return a section array of piece arrays (nested array) _createClass(Item, [{ key: 'sections', value: function sections(field) { var _this2 = this; var text = this[field]; if (!text) return []; var sections = []; text.split('\n').map(function (raw) { if (raw.trim() != '') sections.push(_this2.libre.process(raw.trim())); }); return sections; } }]); return Item; }(); exports.default = Item; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _Client = __webpack_require__(3); var _Client2 = _interopRequireDefault(_Client); var _Item = __webpack_require__(4); var _Item2 = _interopRequireDefault(_Item); var _Dealer = __webpack_require__(1); var _Dealer2 = _interopRequireDefault(_Dealer); var _Libre = __webpack_require__(2); var _Libre2 = _interopRequireDefault(_Libre); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } module.exports = { Libre: _Libre2.default, Item: _Item2.default, Client: _Client2.default, Dealer: _Dealer2.default }; //probably remove this /***/ }), /* 6 */ /***/ (function(module, exports) { module.exports = require("axios"); /***/ }), /* 7 */ /***/ (function(module, exports) { module.exports = require("history"); /***/ }), /* 8 */ /***/ (function(module, exports) { module.exports = require("react"); /***/ }), /* 9 */ /***/ (function(module, exports) { module.exports = require("react-dom"); /***/ }), /* 10 */ /***/ (function(module, exports) { module.exports = require("react-ga"); /***/ }), /* 11 */ /***/ (function(module, exports) { module.exports = require("react-router"); /***/ }), /* 12 */ /***/ (function(module, exports) { module.exports = require("react-router-dom"); /***/ }) /******/ ])));