source: node_modules/react-syntax-highlighter/src/create-element.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 6.3 KB
Line 
1import React from 'react';
2
3// Get all possible permutations of all power sets
4//
5// Super simple, non-algorithmic solution since the
6// number of class names will not be greater than 4
7function powerSetPermutations(arr) {
8 const arrLength = arr.length;
9 if (arrLength === 0 || arrLength === 1) return arr;
10 if (arrLength === 2) {
11 // prettier-ignore
12 return [
13 arr[0],
14 arr[1],
15 `${arr[0]}.${arr[1]}`,
16 `${arr[1]}.${arr[0]}`
17 ];
18 }
19 if (arrLength === 3) {
20 return [
21 arr[0],
22 arr[1],
23 arr[2],
24 `${arr[0]}.${arr[1]}`,
25 `${arr[0]}.${arr[2]}`,
26 `${arr[1]}.${arr[0]}`,
27 `${arr[1]}.${arr[2]}`,
28 `${arr[2]}.${arr[0]}`,
29 `${arr[2]}.${arr[1]}`,
30 `${arr[0]}.${arr[1]}.${arr[2]}`,
31 `${arr[0]}.${arr[2]}.${arr[1]}`,
32 `${arr[1]}.${arr[0]}.${arr[2]}`,
33 `${arr[1]}.${arr[2]}.${arr[0]}`,
34 `${arr[2]}.${arr[0]}.${arr[1]}`,
35 `${arr[2]}.${arr[1]}.${arr[0]}`
36 ];
37 }
38 if (arrLength >= 4) {
39 // Currently does not support more than 4 extra
40 // class names (after `.token` has been removed)
41 return [
42 arr[0],
43 arr[1],
44 arr[2],
45 arr[3],
46 `${arr[0]}.${arr[1]}`,
47 `${arr[0]}.${arr[2]}`,
48 `${arr[0]}.${arr[3]}`,
49 `${arr[1]}.${arr[0]}`,
50 `${arr[1]}.${arr[2]}`,
51 `${arr[1]}.${arr[3]}`,
52 `${arr[2]}.${arr[0]}`,
53 `${arr[2]}.${arr[1]}`,
54 `${arr[2]}.${arr[3]}`,
55 `${arr[3]}.${arr[0]}`,
56 `${arr[3]}.${arr[1]}`,
57 `${arr[3]}.${arr[2]}`,
58 `${arr[0]}.${arr[1]}.${arr[2]}`,
59 `${arr[0]}.${arr[1]}.${arr[3]}`,
60 `${arr[0]}.${arr[2]}.${arr[1]}`,
61 `${arr[0]}.${arr[2]}.${arr[3]}`,
62 `${arr[0]}.${arr[3]}.${arr[1]}`,
63 `${arr[0]}.${arr[3]}.${arr[2]}`,
64 `${arr[1]}.${arr[0]}.${arr[2]}`,
65 `${arr[1]}.${arr[0]}.${arr[3]}`,
66 `${arr[1]}.${arr[2]}.${arr[0]}`,
67 `${arr[1]}.${arr[2]}.${arr[3]}`,
68 `${arr[1]}.${arr[3]}.${arr[0]}`,
69 `${arr[1]}.${arr[3]}.${arr[2]}`,
70 `${arr[2]}.${arr[0]}.${arr[1]}`,
71 `${arr[2]}.${arr[0]}.${arr[3]}`,
72 `${arr[2]}.${arr[1]}.${arr[0]}`,
73 `${arr[2]}.${arr[1]}.${arr[3]}`,
74 `${arr[2]}.${arr[3]}.${arr[0]}`,
75 `${arr[2]}.${arr[3]}.${arr[1]}`,
76 `${arr[3]}.${arr[0]}.${arr[1]}`,
77 `${arr[3]}.${arr[0]}.${arr[2]}`,
78 `${arr[3]}.${arr[1]}.${arr[0]}`,
79 `${arr[3]}.${arr[1]}.${arr[2]}`,
80 `${arr[3]}.${arr[2]}.${arr[0]}`,
81 `${arr[3]}.${arr[2]}.${arr[1]}`,
82 `${arr[0]}.${arr[1]}.${arr[2]}.${arr[3]}`,
83 `${arr[0]}.${arr[1]}.${arr[3]}.${arr[2]}`,
84 `${arr[0]}.${arr[2]}.${arr[1]}.${arr[3]}`,
85 `${arr[0]}.${arr[2]}.${arr[3]}.${arr[1]}`,
86 `${arr[0]}.${arr[3]}.${arr[1]}.${arr[2]}`,
87 `${arr[0]}.${arr[3]}.${arr[2]}.${arr[1]}`,
88 `${arr[1]}.${arr[0]}.${arr[2]}.${arr[3]}`,
89 `${arr[1]}.${arr[0]}.${arr[3]}.${arr[2]}`,
90 `${arr[1]}.${arr[2]}.${arr[0]}.${arr[3]}`,
91 `${arr[1]}.${arr[2]}.${arr[3]}.${arr[0]}`,
92 `${arr[1]}.${arr[3]}.${arr[0]}.${arr[2]}`,
93 `${arr[1]}.${arr[3]}.${arr[2]}.${arr[0]}`,
94 `${arr[2]}.${arr[0]}.${arr[1]}.${arr[3]}`,
95 `${arr[2]}.${arr[0]}.${arr[3]}.${arr[1]}`,
96 `${arr[2]}.${arr[1]}.${arr[0]}.${arr[3]}`,
97 `${arr[2]}.${arr[1]}.${arr[3]}.${arr[0]}`,
98 `${arr[2]}.${arr[3]}.${arr[0]}.${arr[1]}`,
99 `${arr[2]}.${arr[3]}.${arr[1]}.${arr[0]}`,
100 `${arr[3]}.${arr[0]}.${arr[1]}.${arr[2]}`,
101 `${arr[3]}.${arr[0]}.${arr[2]}.${arr[1]}`,
102 `${arr[3]}.${arr[1]}.${arr[0]}.${arr[2]}`,
103 `${arr[3]}.${arr[1]}.${arr[2]}.${arr[0]}`,
104 `${arr[3]}.${arr[2]}.${arr[0]}.${arr[1]}`,
105 `${arr[3]}.${arr[2]}.${arr[1]}.${arr[0]}`
106 ];
107 }
108}
109
110const classNameCombinations = {};
111function getClassNameCombinations(classNames) {
112 if (classNames.length === 0 || classNames.length === 1) return classNames;
113 const key = classNames.join('.');
114 if (!classNameCombinations[key]) {
115 classNameCombinations[key] = powerSetPermutations(classNames);
116 }
117 return classNameCombinations[key];
118}
119
120export function createStyleObject(classNames, elementStyle = {}, stylesheet) {
121 const nonTokenClassNames = classNames.filter(
122 className => className !== 'token'
123 );
124 const classNamesCombinations = getClassNameCombinations(nonTokenClassNames);
125 return classNamesCombinations.reduce((styleObject, className) => {
126 return { ...styleObject, ...stylesheet[className] };
127 }, elementStyle);
128}
129
130export function createClassNameString(classNames) {
131 return classNames.join(' ');
132}
133
134export function createChildren(stylesheet, useInlineStyles) {
135 let childrenCount = 0;
136 return children => {
137 childrenCount += 1;
138 return children.map((child, i) =>
139 createElement({
140 node: child,
141 stylesheet,
142 useInlineStyles,
143 key: `code-segment-${childrenCount}-${i}`
144 })
145 );
146 };
147}
148
149export default function createElement({
150 node,
151 stylesheet,
152 style = {},
153 useInlineStyles,
154 key
155}) {
156 const { properties, type, tagName: TagName, value } = node;
157 if (type === 'text') {
158 return value;
159 } else if (TagName) {
160 const childrenCreator = createChildren(stylesheet, useInlineStyles);
161
162 let props;
163
164 if (!useInlineStyles) {
165 props = {
166 ...properties,
167 className: createClassNameString(properties.className)
168 };
169 } else {
170 const allStylesheetSelectors = Object.keys(stylesheet).reduce(
171 (classes, selector) => {
172 selector.split('.').forEach(className => {
173 if (!classes.includes(className)) classes.push(className);
174 });
175 return classes;
176 },
177 []
178 );
179
180 // For compatibility with older versions of react-syntax-highlighter
181 const startingClassName =
182 properties.className && properties.className.includes('token')
183 ? ['token']
184 : [];
185
186 const className =
187 properties.className &&
188 startingClassName.concat(
189 properties.className.filter(
190 className => !allStylesheetSelectors.includes(className)
191 )
192 );
193
194 props = {
195 ...properties,
196 className: createClassNameString(className) || undefined,
197 style: createStyleObject(
198 properties.className,
199 Object.assign({}, properties.style, style),
200 stylesheet
201 )
202 };
203 }
204
205 const children = childrenCreator(node.children);
206 return (
207 <TagName key={key} {...props}>
208 {children}
209 </TagName>
210 );
211 }
212}
Note: See TracBrowser for help on using the repository browser.