collections_JSXElement.js.html 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSDoc: Source: collections/JSXElement.js</title>
  6. <script src="scripts/prettify/prettify.js"> </script>
  7. <script src="scripts/prettify/lang-css.js"> </script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
  13. </head>
  14. <body>
  15. <div id="main">
  16. <h1 class="page-title">Source: collections/JSXElement.js</h1>
  17. <section>
  18. <article>
  19. <pre class="prettyprint source linenums"><code>/*
  20. * Copyright (c) 2015-present, Facebook, Inc.
  21. * All rights reserved.
  22. *
  23. * This source code is licensed under the BSD-style license found in the
  24. * LICENSE file in the root directory of this source tree. An additional grant
  25. * of patent rights can be found in the PATENTS file in the same directory.
  26. *
  27. */
  28. 'use strict';
  29. var _ = require('lodash');
  30. var Collection = require('../Collection');
  31. var NodeCollection = require('./Node');
  32. var assert = require('assert');
  33. var recast = require('recast');
  34. var requiresModule = require('./VariableDeclarator').filters.requiresModule;
  35. var types = recast.types.namedTypes;
  36. var JSXElement = types.JSXElement;
  37. var JSXAttribute = types.JSXAttribute;
  38. var Literal = types.Literal;
  39. /**
  40. * Contains filter methods and mutation methods for processing JSXElements.
  41. * @mixin
  42. */
  43. var globalMethods = {
  44. /**
  45. * Finds all JSXElements optionally filtered by name
  46. *
  47. * @param {string} name
  48. * @return {Collection}
  49. */
  50. findJSXElements: function(name) {
  51. var nameFilter = name &amp;&amp; {openingElement: {name: {name: name}}};
  52. return this.find(JSXElement, nameFilter);
  53. },
  54. /**
  55. * Finds all JSXElements by module name. Given
  56. *
  57. * var Bar = require('Foo');
  58. * &lt;Bar />
  59. *
  60. * findJSXElementsByModuleName('Foo') will find &lt;Bar />, without having to
  61. * know the variable name.
  62. */
  63. findJSXElementsByModuleName: function(moduleName) {
  64. assert.ok(
  65. moduleName &amp;&amp; typeof moduleName === 'string',
  66. 'findJSXElementsByModuleName(...) needs a name to look for'
  67. );
  68. return this.find(types.VariableDeclarator)
  69. .filter(requiresModule(moduleName))
  70. .map(function(path) {
  71. var id = path.value.id.name;
  72. if (id) {
  73. return Collection.fromPaths([path])
  74. .closestScope()
  75. .findJSXElements(id)
  76. .paths();
  77. }
  78. });
  79. }
  80. };
  81. var filterMethods = {
  82. /**
  83. * Filter method for attributes.
  84. *
  85. * @param {Object} attributeFilter
  86. * @return {function}
  87. */
  88. hasAttributes: function(attributeFilter) {
  89. var attributeNames = Object.keys(attributeFilter);
  90. return function filter(path) {
  91. if (!JSXElement.check(path.value)) {
  92. return false;
  93. }
  94. var elementAttributes = Object.create(null);
  95. path.value.openingElement.attributes.forEach(function(attr) {
  96. if (!JSXAttribute.check(attr) ||
  97. !(attr.name.name in attributeFilter)) {
  98. return;
  99. }
  100. elementAttributes[attr.name.name] = attr;
  101. });
  102. return attributeNames.every(function(name) {
  103. if (!(name in elementAttributes) ){
  104. return false;
  105. }
  106. var value = elementAttributes[name].value;
  107. var expected = attributeFilter[name];
  108. var actual = Literal.check(value) ? value.value : value.expression;
  109. if (typeof expected === 'function') {
  110. return expected(actual);
  111. } else {
  112. // Literal attribute values are always strings
  113. return String(expected) === actual;
  114. }
  115. });
  116. };
  117. },
  118. /**
  119. * Filter elements which contain a specific child type
  120. *
  121. * @param {string} name
  122. * @return {function}
  123. */
  124. hasChildren: function(name) {
  125. return function filter(path) {
  126. return JSXElement.check(path.value) &amp;&amp;
  127. path.value.children.some(
  128. child => JSXElement.check(child) &amp;&amp;
  129. child.openingElement.name.name === name
  130. );
  131. };
  132. }
  133. };
  134. /**
  135. * @mixin
  136. */
  137. var traversalMethods = {
  138. /**
  139. * Returns all child nodes, including literals and expressions.
  140. *
  141. * @return {Collection}
  142. */
  143. childNodes: function() {
  144. var paths = [];
  145. this.forEach(function(path) {
  146. var children = path.get('children');
  147. var l = children.value.length;
  148. for (var i = 0; i &lt; l; i++) {
  149. paths.push(children.get(i));
  150. }
  151. });
  152. return Collection.fromPaths(paths, this);
  153. },
  154. /**
  155. * Returns all children that are JSXElements.
  156. *
  157. * @return {JSXElementCollection}
  158. */
  159. childElements: function() {
  160. var paths = [];
  161. this.forEach(function(path) {
  162. var children = path.get('children');
  163. var l = children.value.length;
  164. for (var i = 0; i &lt; l; i++) {
  165. if (types.JSXElement.check(children.value[i])) {
  166. paths.push(children.get(i));
  167. }
  168. }
  169. });
  170. return Collection.fromPaths(paths, this, JSXElement);
  171. },
  172. };
  173. var mappingMethods = {
  174. /**
  175. * Given a JSXElement, returns its "root" name. E.g. it would return "Foo" for
  176. * both &lt;Foo /> and &lt;Foo.Bar />.
  177. *
  178. * @param {NodePath} path
  179. * @return {string}
  180. */
  181. getRootName: function(path) {
  182. var name = path.value.openingElement.name;
  183. while (types.JSXMemberExpression.check(name)) {
  184. name = name.object;
  185. }
  186. return name &amp;&amp; name.name || null;
  187. }
  188. };
  189. function register() {
  190. NodeCollection.register();
  191. Collection.registerMethods(globalMethods, types.Node);
  192. Collection.registerMethods(traversalMethods, JSXElement);
  193. }
  194. exports.register = _.once(register);
  195. exports.filters = filterMethods;
  196. exports.mappings = mappingMethods;
  197. </code></pre>
  198. </article>
  199. </section>
  200. </div>
  201. <nav>
  202. <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-jscodeshift.html">jscodeshift</a></li></ul><h3>Externals</h3><ul><li><a href="external-astTypes.html">astTypes</a></li></ul><h3>Classes</h3><ul><li><a href="Collection.html">Collection</a></li></ul><h3>Mixins</h3><ul><li><a href="globalMethods.html">globalMethods</a></li><li><a href="mutationMethods.html">mutationMethods</a></li><li><a href="transformMethods.html">transformMethods</a></li><li><a href="traversalMethods.html">traversalMethods</a></li></ul><h3>Global</h3><ul><li><a href="global.html#registerMethods">registerMethods</a></li></ul>
  203. </nav>
  204. <br class="clear">
  205. <footer>
  206. 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)
  207. </footer>
  208. <script> prettyPrint(); </script>
  209. <script src="scripts/linenumber.js"> </script>
  210. </body>
  211. </html>