Skip to content

Commit

Permalink
JSXElement's hasAttributes filter method supports attributes with omi…
Browse files Browse the repository at this point in the history
…tted boolean values.
  • Loading branch information
artemruts committed Oct 10, 2018
1 parent 595b15c commit 1fc7a7a
Show file tree
Hide file tree
Showing 17 changed files with 766 additions and 172 deletions.
430 changes: 415 additions & 15 deletions docs/Collection.html

Large diffs are not rendered by default.

70 changes: 47 additions & 23 deletions docs/Collection.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ <h1 class="page-title">Source: Collection.js</h1>

'use strict';

var assert = require('assert');
var recast = require('recast');
var _ = require('lodash');
const assert = require('assert');
const recast = require('recast');
const _ = require('lodash');

var astTypes = recast.types;
const astTypes = recast.types;
var types = astTypes.namedTypes;
var NodePath = astTypes.NodePath;
var Node = types.Node;
const NodePath = astTypes.NodePath;
const Node = types.Node;

/**
* This represents a generic collection of node paths. It only has a generic
Expand Down Expand Up @@ -106,6 +106,30 @@ <h1 class="page-title">Source: Collection.js</h1>
return this;
}

/**
* Tests whether at-least one path passes the test implemented by the provided callback.
*
* @param {function} callback
* @return {boolean}
*/
some(callback) {
return this.__paths.some(
(path, i, paths) => callback.call(path, path, i, paths)
);
}

/**
* Tests whether all paths pass the test implemented by the provided callback.
*
* @param {function} callback
* @return {boolean}
*/
every(callback) {
return this.__paths.every(
(path, i, paths) => callback.call(path, path, i, paths)
);
}

/**
* Executes the callback for every path in the collection and returns a new
* collection from the return values (which must be paths).
Expand All @@ -120,15 +144,15 @@ <h1 class="page-title">Source: Collection.js</h1>
* @param {Type} type Force the new collection to be of a specific type
*/
map(callback, type) {
var paths = [];
const paths = [];
this.forEach(function(path) {
/*jshint eqnull:true*/
var result = callback.apply(path, arguments);
let result = callback.apply(path, arguments);
if (result == null) return;
if (!Array.isArray(result)) {
result = [result];
}
for (var i = 0; i &lt; result.length; i++) {
for (let i = 0; i &lt; result.length; i++) {
if (paths.indexOf(result[i]) === -1) {
paths.push(result[i]);
}
Expand Down Expand Up @@ -213,7 +237,7 @@ <h1 class="page-title">Source: Collection.js</h1>
* @param {string|number} ...fields
*/
get() {
var path = this.__paths[0];
const path = this.__paths[0];
if (!path) {
throw Error(
'You cannot call "get" on a collection with no paths. ' +
Expand Down Expand Up @@ -251,11 +275,11 @@ <h1 class="page-title">Source: Collection.js</h1>
* @return {Type} type An AST type
*/
function _inferTypes(paths) {
var _types = [];
let _types = [];

if (paths.length > 0 &amp;&amp; Node.check(paths[0].node)) {
var nodeType = types[paths[0].node.type];
var sameType = paths.length === 1 ||
const nodeType = types[paths[0].node.type];
const sameType = paths.length === 1 ||
paths.every(path => nodeType.check(path.node));

if (sameType) {
Expand Down Expand Up @@ -336,7 +360,7 @@ <h1 class="page-title">Source: Collection.js</h1>
);
}

var CPt = Collection.prototype;
const CPt = Collection.prototype;

/**
* This function adds the provided methods to the prototype of the corresponding
Expand All @@ -347,12 +371,12 @@ <h1 class="page-title">Source: Collection.js</h1>
* @param {Type=} type Optional type to add the methods to
*/
function registerMethods(methods, type) {
for (var methodName in methods) {
for (const methodName in methods) {
if (!methods.hasOwnProperty(methodName)) {
return;
}
if (hasConflictingRegistration(methodName, type)) {
var msg = `There is a conflicting registration for method with name "${methodName}".\nYou tried to register an additional method with `;
let msg = `There is a conflicting registration for method with name "${methodName}".\nYou tried to register an additional method with `;

if (type) {
msg += `type "${type.toString()}".`
Expand All @@ -362,7 +386,7 @@ <h1 class="page-title">Source: Collection.js</h1>

msg += '\nThere are existing registrations for that method with ';

var conflictingRegistrations = CPt[methodName].typedRegistrations;
const conflictingRegistrations = CPt[methodName].typedRegistrations;

if (conflictingRegistrations) {
msg += `type ${Object.keys(conflictingRegistrations).join(', ')}.`;
Expand Down Expand Up @@ -393,13 +417,13 @@ <h1 class="page-title">Source: Collection.js</h1>
throw new Error(`Internal Error: "${methodName}" method is already installed`);
}

var registrations = {};
const registrations = {};

function typedMethod() {
var types = Object.keys(registrations);
const types = Object.keys(registrations);

for (var i = 0; i &lt; types.length; i++) {
var currentType = types[i];
for (let i = 0; i &lt; types.length; i++) {
const currentType = types[i];
if (registrations[currentType] &amp;&amp; this.isOfType(currentType)) {
return registrations[currentType].apply(this, arguments);
}
Expand All @@ -425,7 +449,7 @@ <h1 class="page-title">Source: Collection.js</h1>
return false;
}

var registrations = CPt[methodName] &amp;&amp; CPt[methodName].typedRegistrations;
const registrations = CPt[methodName] &amp;&amp; CPt[methodName].typedRegistrations;

if (!registrations) {
return true;
Expand Down Expand Up @@ -477,7 +501,7 @@ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-js
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.1</a> on Wed Sep 21 2016 16:53:09 GMT-0400 (EDT)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Oct 09 2018 21:58:15 GMT-0400 (EDT)
</footer>

<script> prettyPrint(); </script>
Expand Down
76 changes: 42 additions & 34 deletions docs/collections_JSXElement.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,32 +38,32 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>

'use strict';

var _ = require('lodash');
var Collection = require('../Collection');
var NodeCollection = require('./Node');
const _ = require('lodash');
const Collection = require('../Collection');
const NodeCollection = require('./Node');

var assert = require('assert');
var recast = require('recast');
var requiresModule = require('./VariableDeclarator').filters.requiresModule;
const assert = require('assert');
const recast = require('recast');
const requiresModule = require('./VariableDeclarator').filters.requiresModule;

var types = recast.types.namedTypes;
var JSXElement = types.JSXElement;
var JSXAttribute = types.JSXAttribute;
var Literal = types.Literal;
const types = recast.types.namedTypes;
const JSXElement = types.JSXElement;
const JSXAttribute = types.JSXAttribute;
const Literal = types.Literal;

/**
* Contains filter methods and mutation methods for processing JSXElements.
* @mixin
*/
var globalMethods = {
const globalMethods = {
/**
* Finds all JSXElements optionally filtered by name
*
* @param {string} name
* @return {Collection}
*/
findJSXElements: function(name) {
var nameFilter = name &amp;&amp; {openingElement: {name: {name: name}}};
const nameFilter = name &amp;&amp; {openingElement: {name: {name: name}}};
return this.find(JSXElement, nameFilter);
},

Expand All @@ -85,7 +85,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
return this.find(types.VariableDeclarator)
.filter(requiresModule(moduleName))
.map(function(path) {
var id = path.value.id.name;
const id = path.value.id.name;
if (id) {
return Collection.fromPaths([path])
.closestScope()
Expand All @@ -96,7 +96,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
}
};

var filterMethods = {
const filterMethods = {

/**
* Filter method for attributes.
Expand All @@ -105,12 +105,12 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
* @return {function}
*/
hasAttributes: function(attributeFilter) {
var attributeNames = Object.keys(attributeFilter);
const attributeNames = Object.keys(attributeFilter);
return function filter(path) {
if (!JSXElement.check(path.value)) {
return false;
}
var elementAttributes = Object.create(null);
const elementAttributes = Object.create(null);
path.value.openingElement.attributes.forEach(function(attr) {
if (!JSXAttribute.check(attr) ||
!(attr.name.name in attributeFilter)) {
Expand All @@ -123,15 +123,23 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
if (!(name in elementAttributes) ){
return false;
}
var value = elementAttributes[name].value;
var expected = attributeFilter[name];
var actual = Literal.check(value) ? value.value : value.expression;

const value = elementAttributes[name].value;
const expected = attributeFilter[name];

// Only when value is truthy access it's properties
const actual = !value
? value
: Literal.check(value)
? value.value
: value.expression;

if (typeof expected === 'function') {
return expected(actual);
} else {
// Literal attribute values are always strings
return String(expected) === actual;
}

// Literal attribute values are always strings
return String(expected) === actual;
});
};
},
Expand All @@ -156,19 +164,19 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
/**
* @mixin
*/
var traversalMethods = {
const traversalMethods = {

/**
* Returns all child nodes, including literals and expressions.
*
* @return {Collection}
*/
childNodes: function() {
var paths = [];
const paths = [];
this.forEach(function(path) {
var children = path.get('children');
var l = children.value.length;
for (var i = 0; i &lt; l; i++) {
const children = path.get('children');
const l = children.value.length;
for (let i = 0; i &lt; l; i++) {
paths.push(children.get(i));
}
});
Expand All @@ -181,11 +189,11 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
* @return {JSXElementCollection}
*/
childElements: function() {
var paths = [];
const paths = [];
this.forEach(function(path) {
var children = path.get('children');
var l = children.value.length;
for (var i = 0; i &lt; l; i++) {
const children = path.get('children');
const l = children.value.length;
for (let i = 0; i &lt; l; i++) {
if (types.JSXElement.check(children.value[i])) {
paths.push(children.get(i));
}
Expand All @@ -195,7 +203,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
},
};

var mappingMethods = {
const mappingMethods = {
/**
* Given a JSXElement, returns its "root" name. E.g. it would return "Foo" for
* both &lt;Foo /> and &lt;Foo.Bar />.
Expand All @@ -204,7 +212,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
* @return {string}
*/
getRootName: function(path) {
var name = path.value.openingElement.name;
let name = path.value.openingElement.name;
while (types.JSXMemberExpression.check(name)) {
name = name.object;
}
Expand Down Expand Up @@ -238,7 +246,7 @@ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-js
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.1</a> on Wed Sep 21 2016 16:53:09 GMT-0400 (EDT)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Oct 09 2018 21:58:15 GMT-0400 (EDT)
</footer>

<script> prettyPrint(); </script>
Expand Down
Loading

0 comments on commit 1fc7a7a

Please sign in to comment.