Skip to content
This repository has been archived by the owner on Sep 3, 2022. It is now read-only.

Commit

Permalink
JSDoc type updates.
Browse files Browse the repository at this point in the history
1. Used /** @type {Object.<string, any>}*/(node).newProperty, casting Node to generic object, allowing addition of new properties.
2. Added other minor type improvements across files.
3. Removed @description tag since the first block of text in a JSDoc comment is treated as the description automatically.
4. Updated test files to use favicons to avoid unnecessary warnings in browser console.
5. Moved build functionality from gulpfile to NPM command line script. Running Rollup from command line.
6. Added rollup.config.js file to project.
  • Loading branch information
Wobbabits committed Jul 3, 2018
1 parent 58511e1 commit e0824f9
Show file tree
Hide file tree
Showing 40 changed files with 147 additions and 5,940 deletions.
2 changes: 1 addition & 1 deletion dist/composi.js.map

Large diffs are not rendered by default.

46 changes: 6 additions & 40 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,13 @@
// @ts-nocheck
const gulp = require('gulp')
const browserSync = require('browser-sync')
const rollup = require('rollup')
const babel = require('rollup-plugin-babel')
const uglify = require('rollup-plugin-uglify')
const resolve = require('rollup-plugin-node-resolve')
const commonjs = require('rollup-plugin-commonjs')
const gzip = require('gulp-gzip')

gulp.task('build', () => {
return rollup.rollup({
input: './index.js',
plugins: [
babel({
exclude: 'node_modules/**'
}),
resolve({
jsnext: true,
main: true,
browser: true
}),
commonjs(),
uglify({
compress: {
collapse_vars: true
}
})
]
})
.then((bundle) => {
return bundle.write({
format: 'umd',
name: 'composi',
file: './dist/composi.js',
sourcemap: true
})
})
.then((bundle) => {
gulp.src('./dist/composi.js')
.pipe(gzip({ extension: 'gzip' }))
.pipe(gulp.dest('./dist'))
})
// Gzip files:
gulp.task('gzip', function() {
gulp.src('./dist/composi.js')
.pipe(gzip({ extension: 'gzip' }))
.pipe(gulp.dest('./dist'))
})

// Setup tests:
Expand All @@ -54,5 +22,3 @@ gulp.task('test', function() {
}
}).reload
})

gulp.task('default', ['build'])
37 changes: 18 additions & 19 deletions lib/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { updateComponent } from './utils/componentHelpers/updateComponent'
import { unmountComponent } from './utils/componentHelpers/unmountComponent'

/**
* @description This is a numeric value derived from the Date object used as a key to create a pseudo-private property in the Component class for holding state.
* This is a numeric value derived from the Date object used as a key to create a pseudo-private property in the Component class for holding state.
* @type {number} dataStore A numeric value to use as pseudo-private key to store the component's state.
*/
const dataStore = new Date().getTime()

/**
* @description Component can be instantiated with the new keyword, or extended to create a custom version of the class.
* Component can be instantiated with the new keyword, or extended to create a custom version of the class.
* @class Class to create a component.
* @example New instance of Component class:
* const title = new Component({
Expand Down Expand Up @@ -38,8 +38,7 @@ const dataStore = new Date().getTime()
*/
export class Component {
/**
* @constructor
* @description Constructor for Component class.
* Constructor for Component class.
* @property {state} [props.state] The state object of the component. This can be of type boolean, string, number, object or array.
* @property {string} selector A CSS selector describing the DOM container in which to render the component.
* @property {HTMLElement} container The DOM node in which the component is rendered.
Expand Down Expand Up @@ -107,43 +106,43 @@ export class Component {
if (props.componentWillMount)
/**
* @property {() => void} componentWillMount A method to execute before the component mounts. The callback gets a reference to the component instance as its argument.
* @returns {void} undefined
* @return {void} undefined
*/
this.componentWillMount = props.componentWillMount

if (props.componentDidMount)
/**
* @property {() => void} componentDidMount A method to execute after the component mounts. The callback gets a reference to the component instance as its argument.
* @returns {void} undefined
* @return {void} undefined
*/
this.componentDidMount = props.componentDidMount

if (props.componentWillUpdate)
/**
* @property {() => void} componentWillUpdate A method to execute before the component updates. The callback gets a reference to the component instance as its argument.
* @returns {void} undefined
* @return {void} undefined
*/
this.componentWillUpdate = props.componentWillUpdate

if (props.componentDidUpdate)
/**
* @property {() => void} componentDidUpdate -A method to execute after the component updates. The callback gets a reference to the component instance as its argument.
* @returns {void} undefined
* @return {void} undefined
*/
this.componentDidUpdate = props.componentDidUpdate

if (props.componentWillUnmount)
/**
* @property {() => void} componentWillUnmount A method to execute before the component unmounts. The callback gets a reference to the component instance as its argument.
* @returns {void} undefined
* @return {void} undefined
*/
this.componentWillUnmount = props.componentWillUnmount
}

/**
* @method A method to execute before the component mounts.
* @param {() => void} [cb] A callback to execute.
* @returns {void} undefined
* @return {void} undefined
*/
componentWillMount(cb) {
if (cb && typeof cb === 'function') {
Expand All @@ -154,7 +153,7 @@ export class Component {
/**
* @method A method to execute after the component mounts.
* @param {() => void} [cb] A callback to execute.
* @returns {void} undefined
* @return {void} undefined
*/
componentDidMount(cb) {
if (cb && typeof cb === 'function') {
Expand All @@ -165,7 +164,7 @@ export class Component {
/**
* @method A method to execute before the component updates.
* @param {() => void} [cb] A callback to execute.
* @returns {void} undefined
* @return {void} undefined
*/
componentWillUpdate(cb) {
if (cb && typeof cb === 'function') {
Expand All @@ -176,7 +175,7 @@ export class Component {
/**
* @method A method to execute after the component updates.
* @param {() => void} [cb] A callback to execute.
* @returns {void} undefined
* @return {void} undefined
*/
componentDidUpdate(cb) {
if (cb && typeof cb === 'function') {
Expand All @@ -187,7 +186,7 @@ export class Component {
/**
* @method A method to execute after the component updates.
* @param {() => void} [cb] A callback to execute.
* @returns {void} undefined
* @return {void} undefined
*/
componentWillUnmount(cb) {
if (cb && typeof cb === 'function') {
Expand All @@ -206,7 +205,7 @@ export class Component {

/**
* @method This is getter to access the component's state using the pseudo-private key dataStore.
* @returns {boolean | number | string | Object | any[]} The component's state
* @return {boolean | number | string | Object | any[]} The component's state
*/
get state() {
return this[dataStore]
Expand All @@ -215,7 +214,7 @@ export class Component {
/**
* @method This is a setter to define the component's state. It uses the dataStore object as a pseudo-private key. It uses requestAnimationFrame to throttle component updates to avoid layout thrashing.
* @param {string | number | boolean | Object | any[]} data Data to set as component state.
* @returns {void} undefined
* @return {void} undefined
*/
set state(data) {
this[dataStore] = data
Expand All @@ -231,7 +230,7 @@ export class Component {
* this.setState([1,2,3])
* this.setState(prevState => prevState + 1)
* @param {string | number | boolean | Object | any[] | Function} data The data to set. If a callback is passed as the argument to execute, it gets passed the previous state as its argument. You need to make sure the callback returns the final state or the component will not update.
* @returns {void} undefined
* @return {void} undefined
*/
setState(data) {
handleSetState(data, this)
Expand All @@ -242,7 +241,7 @@ export class Component {
* If data is passed as argument, it will be used.
* Otherwise state will be used.
* @param {boolean | number | string | Object | any[]} [data] By default, data will be the component's current state, otherwise, if data is provided as an argument, that will be used, overriding the state.
* @returns {void} undefined
* @return {void} undefined
*/
update(data) {
updateComponent(data, this)
Expand All @@ -253,7 +252,7 @@ export class Component {
* First unbind events.
* Then remove component element from DOM.
* Also null out component properties.
* @returns {void} undefined
* @return {void} undefined
*/
unmount() {
unmountComponent(this)
Expand Down
4 changes: 2 additions & 2 deletions lib/fragment.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @description A tag to enable returning sibling elements. This is useful for returning list items to render in a list or table cells to render in a table row.
* A tag to enable returning sibling elements. This is useful for returning list items to render in a list or table cells to render in a table row.
* @example
* <Fragment>
* <li>A</li>
Expand All @@ -14,6 +14,6 @@
* ])
* @param {Object} [props] When using Fragment as a function, props is the first argument. Provide either null or {} as the value for props.
* @param {import('./h').VNode[]} [children] The siblings to return with the Fragment. This will be an array of sibling elements.
* @returns {import('./h').VNode[]} An array of virtual nodes.
* @return {import('./h').VNode[]} An array of virtual nodes.
*/
export const Fragment = (props, children) => children
10 changes: 6 additions & 4 deletions lib/h.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
// import {vnode} from './utils/vnode'
/**
* @typedef {Object.<string, any>} Props
*/
/**
* @typedef {Object} VNode;
* @property {string | Function} VNode.type;
* @property {Props} VNode.props;
* @property {any[]} VNode.children;
* @property {string | number | null} VNode.key;
* @property {Object.<string, any> } VNode.props;
*/
/**
* @description Hyperscript function. Enables definition of HTML/SVG using functions.
* Hyperscript function. Enables definition of HTML/SVG using functions.
* @param {string | Function} type A tag name or function.
* @param {Object} [props] An Object literal of key-value pairs.
* @param {any[]} children An array of strings or other arrays.
* @returns {VNode} VNode An object literal of type, props and children.
* @return {VNode} VNode An object literal of type, props and children.
*
* @example Virtual node with string as content:
* const title = h('h1', {class: 'main-title'}, 'This is the Titel!')
Expand Down
8 changes: 4 additions & 4 deletions lib/mount.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { patch } from './patch'
import { FragmentError } from './utils/fragmentError'

/**
* @description A function to create and inject a virtual node into the document. The node will be appended to the container. The first argument can be either a JSX tag or an h function. After mounting, use the render function and the element returned by mount to udate the DOM.
* A function to create and inject a virtual node into the document. The node will be appended to the container. The first argument can be either a JSX tag or an h function. After mounting, use the render function and the element returned by mount to udate the DOM.
* @example Insert Title tag into section:
* const title = mount(<Title message='Hello World!'/>, 'section').
* // Update the node with new prop value and reference to DOM from mount:
* render(<Title message='New stuff'/>, title)
* @param {Object | Function} tag A JSX tag or hyperscript function to render.
* @param {Node | string} [container] The element into which the tag will be rendered.
* @param {HTMLElement} [elementToHydrate] A server-rendered element to hydrate during initial load.
* @returns {Node} The base element of the rendered tag.
* @return {Node} The base element of the rendered tag.
*/
export const mount = (tag, container, elementToHydrate) => {
container = typeof container === 'string' && document.querySelector(container)
Expand All @@ -20,8 +20,8 @@ export const mount = (tag, container, elementToHydrate) => {
if (tag.props && tag.props.onComponentDidMount) {
tag.props.onComponentDidMount.call(tag.props.onComponentDidMount, element)
}
// @ts-ignore
element.mounted = true

element['mounted'] = true
if (elementToHydrate) {
if (typeof elementToHydrate === 'string') {
elementToHydrate = document.querySelector(elementToHydrate)
Expand Down
11 changes: 5 additions & 6 deletions lib/patch.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { patchElement } from './utils/patchElement'

/**
* @description A function to patch a virtual node against a DOM element, updating it in the most efficient manner possible.
* A function to patch a virtual node against a DOM element, updating it in the most efficient manner possible.
* @param {() => import('./h').VNode} node A function that returns a virtual node. This may be a JSX tag, which gets converted into a function, or a hyperscript function.
* @param {Node} [element] The element to patch.
* @returns {Node} The updated element.
* @return {Node} The updated element.
*/
export function patch(node, element) {
if (element) {
// @ts-ignore
patchElement(element.parentNode, element, element && element.vnode, node)
patchElement(element.parentNode, element, element && element['vnode'], node)
} else {
element = patchElement(null, null, null, node)
}
// @ts-ignore
element.vnode = node

element['vnode'] = node

return element
}
4 changes: 2 additions & 2 deletions lib/render.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { patch } from './patch'

/**
* @description A function to update a functional component already mounted in the DOM. The first argument can be either a JSX tag or an h function.
* A function to update a functional component already mounted in the DOM. The first argument can be either a JSX tag or an h function.
* @example Update Title tag into section:
* const element = mount(<Title message='Hello World!'/>, 'section')
* // Pass the captured element to the render function:
* render(<Title message='Hello Everyone!'/>, 'header')
* @param {() => import('./h').VNode} tag A JSX tag or hyperscript function to render.
* @param {Node} [element] The element in the DOM which will be updated.
* @returns {Node} The base element of the rendered tag.
* @return {Node} The base element of the rendered tag.
*/
export function render(tag, element) {
return patch(tag, element)
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/componentHelpers/eventWhitelist.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @description Array of events to remove when a component is unmounted.
* Array of events to remove when a component is unmounted.
* @type {string[]} eventWhitelist
*/
export const eventWhitelist = [
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/componentHelpers/handleSetState.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { mixin } from '../mixin'
import { isObject } from '../componentHelpers/isObject'

/**
* @function A helper function for the Component class. This sets state on the class component provided.
* A helper function for the Component class. This sets state on the class component provided.
* @param {*} data Data to use as state.
* @param {import('../../component').Component} component A reference to the component to use.
* @return {void} undefined
*/
export function handleSetState(data, component) {
if (typeof data === 'function') {
Expand Down
4 changes: 2 additions & 2 deletions lib/utils/componentHelpers/isObject.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @description A function to test where something is an object literal or not. Used by Component setState.
* A function to test where something is an object literal or not. Used by Component setState.
* @param {Object.<string, any>} obj An object literal to test.
* @returns boolean
* @return {boolean} boolean
*/
export function isObject(obj) {
if (Array.isArray(obj)) return false
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/componentHelpers/isSameNode.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/**
* @description A function to test whether the data provided for updating a component creates a new virtual node or not.
* A function to test whether the data provided for updating a component creates a new virtual node or not.
* @param {import('../../h').VNode} oldNode The previous virtual node of a component.
* @param {*} data Data to be used when rendering a new virtual node for a component.
* @param {import('../../component').Component} component A reference to the component being used.
* @return {boolean} boolean
*/
export function isSameNode(oldNode, data, component) {
if (
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/componentHelpers/unmountComponent.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { eventWhitelist } from './eventWhitelist'

/**
* @description This function will unmount the provided component. Doing so it unregisters a whitelist of events, deletes the base element of the component from the DOM, and sets the component instance properties to null.
* This function will unmount the provided component. Doing so it unregisters a whitelist of events, deletes the base element of the component from the DOM, and sets the component instance properties to null.
* @param {import('../../component').Component} component
* @return {void} undefined
*/
export function unmountComponent(component) {
if (!component.element) return
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/componentHelpers/updateComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { isSameNode } from './isSameNode'
import { patch } from '../../patch'

/**
* @description This function updates an already rendered component. In doing so it checks to see if user provided data as an argument to this function. If data was provided, it uses that to render the component. Otherwise it checks if the component has state. If true, the function uses that to render the component. If no data was provided and the component is stateless, nothing will happen.
* This function updates an already rendered component. In doing so it checks to see if user provided data as an argument to this function. If data was provided, it uses that to render the component. Otherwise it checks if the component has state. If true, the function uses that to render the component. If no data was provided and the component is stateless, nothing will happen.
* @param {boolean | number | string | Object.<string, any> | any[]} data
* @param {import('../../component').Component} component
* @return {void} undefined
*/
export function updateComponent(data, component) {
if (!component.render) return
Expand Down
1 change: 1 addition & 0 deletions lib/utils/fragmentError.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Class to throw error message when attempting to insert Fragement tag directly into DOM.
* @return {string} message
*/
export class FragmentError {
constructor() {
Expand Down
Loading

0 comments on commit e0824f9

Please sign in to comment.