UNPKG

chowdown

Version:

A JavaScript library that allows for the quick transformation of DOM documents into useful formats.

211 lines (171 loc) 7.5 kB
"use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var _require = require('lodash'), capitalize = _require.capitalize, identity = _require.identity, castArray = _require.castArray, assignIn = _require.assignIn; /** * An abstract class representing a document. * Can be queried to retrieve values, links and child documents. * * @class Document * @abstract */ var Document = /*#__PURE__*/ function () { /** * Builds a document instance given the type of document (i.e dom), the * body of the whole doocument and a root allowing queries to be relative. * * @param {string} type The type of the document e.g 'dom' or 'json'. * @param {any} document The raw document object. * @param {any} [root] The root of the document. */ function Document(type, document, root) { _classCallCheck(this, Document); this.options = {}; this.options.type = type; this.options.document = this.loadDocument(document); this.options.root = this.loadRoot(root); } /** * Creates a child document of the same type given a new root. * * @param {any} root The root of the new child document. * @return {Document} The new child document. */ _createClass(Document, [{ key: "create", value: function create(root) { return Document.factory[this.options.type](this.options.document, root); } /** * Given a function, this method attempts to call it * with relevant parameters determined by the concrete type * and returns the result. * * @param {function} fn The raw document function to call. * @return {any} The result of the raw document function. */ }, { key: "raw", value: function raw(fn) { return this.queryRaw(fn); } /** * Given a selector, it attempts to resolve an array of child documents. * * @param {string} selector The selector for to the children. * @return {Document[]} An array of child documents. */ }, { key: "children", value: function children(selector) { var _this = this; var children = this.queryChildren(this.formatSelector(selector)); if (children === undefined) return undefined; return children.map(function (child) { return _this.create(child); }); } /** * Given a selector, this method attempts to find a leaf value in the document. * * @param {string} selector The selector for the value. * @return {any} The value of the resolved selector. */ }, { key: "value", value: function value(selector) { return this.queryValue(this.formatSelector(selector)); } /** * Given a selector, this method attempts to resolve a URI to another document. * * @param {string} selector The selector for the URI. * @return {any} The resolved URI. */ }, { key: "uri", value: function uri(selector) { return this.queryUri(this.formatSelector(selector)); } /** * An abstract method that handles the querying of values within the document. * * @param {string} selector The selector for the value. * @return {any} The value rettrieved. * @abstract */ }, { key: "query", value: function query(selector) { throw new Error('the query method must be implemented by the subclass'); } }]); return Document; }(); module.exports = Document; /** * Set the child load methods to the identity function by default. */ for (var _i = 0, _arr = ['root', 'document']; _i < _arr.length; _i++) { var suffix = _arr[_i]; Document.prototype['load' + capitalize(suffix)] = identity; } /** * Set the child format methods to the identity function by default. */ for (var _i2 = 0, _arr2 = ['selector']; _i2 < _arr2.length; _i2++) { var _suffix = _arr2[_i2]; Document.prototype['format' + capitalize(_suffix)] = identity; } /** * Set the child query methods to call the general query method by default. */ for (var _i3 = 0, _arr3 = ['uri', 'value', 'children']; _i3 < _arr3.length; _i3++) { var _suffix2 = _arr3[_i3]; Document.prototype['query' + capitalize(_suffix2)] = function (selector) { return this.query(selector); }; } /** * Holds a list of factory methods to create different document types. * * @type {object} */ Document.factory = {}; /** * Creates and adds a a factory method for a new subtype of document. * * @param {string} name The name of the subtype. * @param {object} methods The methods the class will have. */ function add(name, methods) { // Create a container class that extends Document for our methods. var ConcreteDocument = /*#__PURE__*/ function (_Document) { _inherits(ConcreteDocument, _Document); function ConcreteDocument(document, root) { _classCallCheck(this, ConcreteDocument); return _possibleConstructorReturn(this, _getPrototypeOf(ConcreteDocument).call(this, name, document, root)); } return ConcreteDocument; }(Document); // Assign the methods to the new classes prototype. assignIn(ConcreteDocument.prototype, methods); // Add a factory method for the new type. Document.factory[name] = function (document, root) { return new ConcreteDocument(document, root); }; } // Add the DOM document type; add('dom', require('./dom'));