Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8a11738

Browse files
committed
modularize
1 parent 433ed82 commit 8a11738

10 files changed

+3644
-0
lines changed

‎src/ComponentCache.js‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const lru = require('lru-cache');
2+
3+
export default class ComponentCache {
4+
constructor(config = {}) {
5+
if (Number.isInteger(config)) {
6+
config = {
7+
max: config
8+
};
9+
}
10+
11+
this.storage = lru({
12+
max: config.max || 1000000000,
13+
length: (n, key) => {
14+
return n.length + key.length;
15+
}
16+
});
17+
}
18+
19+
get(cacheKey, cb) {
20+
let reply = this.storage.get(cacheKey);
21+
cb(null, reply);
22+
}
23+
24+
set(cacheKey, html) {
25+
this.storage.set(cacheKey, html);
26+
}
27+
}

‎src/DOMMarkupOperations.js‎

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
/**
2+
* Copyright (c) 2013-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import invariant from 'fbjs/lib/invariant';
9+
10+
11+
// These attributes should be all lowercase to allow for
12+
// case insensitive checks
13+
var RESERVED_PROPS = {
14+
children: true,
15+
dangerouslySetInnerHTML: true,
16+
defaultValue: true,
17+
defaultChecked: true,
18+
innerHTML: true,
19+
suppressContentEditableWarning: true,
20+
suppressHydrationWarning: true,
21+
style: true
22+
};
23+
24+
function checkMask(value, bitmask) {
25+
return (value & bitmask) === bitmask;
26+
}
27+
28+
var DOMPropertyInjection = {
29+
/**
30+
* Mapping from normalized, camelcased property names to a configuration that
31+
* specifies how the associated DOM property should be accessed or rendered.
32+
*/
33+
MUST_USE_PROPERTY: 0x1,
34+
HAS_BOOLEAN_VALUE: 0x4,
35+
HAS_NUMERIC_VALUE: 0x8,
36+
HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8,
37+
HAS_OVERLOADED_BOOLEAN_VALUE: 0x20,
38+
HAS_STRING_BOOLEAN_VALUE: 0x40,
39+
40+
/**
41+
* Inject some specialized knowledge about the DOM. This takes a config object
42+
* with the following properties:
43+
*
44+
* Properties: object mapping DOM property name to one of the
45+
* DOMPropertyInjection constants or null. If your attribute isn't in here,
46+
* it won't get written to the DOM.
47+
*
48+
* DOMAttributeNames: object mapping React attribute name to the DOM
49+
* attribute name. Attribute names not specified use the **lowercase**
50+
* normalized name.
51+
*
52+
* DOMAttributeNamespaces: object mapping React attribute name to the DOM
53+
* attribute namespace URL. (Attribute names not specified use no namespace.)
54+
*
55+
* DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.
56+
* Property names not specified use the normalized name.
57+
*
58+
* DOMMutationMethods: Properties that require special mutation methods. If
59+
* `value` is undefined, the mutation method should unset the property.
60+
*
61+
* @param {object} domPropertyConfig the config as described above.
62+
*/
63+
injectDOMPropertyConfig: function(domPropertyConfig) {
64+
var Injection = DOMPropertyInjection;
65+
var Properties = domPropertyConfig.Properties || {};
66+
var DOMAttributeNamespaces =
67+
domPropertyConfig.DOMAttributeNamespaces || {};
68+
var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
69+
var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
70+
71+
for (var propName in Properties) {
72+
!!properties.hasOwnProperty(propName)
73+
? invariant(
74+
false,
75+
"injectDOMPropertyConfig(...): You're trying to inject DOM property '%s' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.",
76+
propName
77+
)
78+
: void 0;
79+
80+
var lowerCased = propName.toLowerCase();
81+
var propConfig = Properties[propName];
82+
83+
var propertyInfo = {
84+
attributeName: lowerCased,
85+
attributeNamespace: null,
86+
propertyName: propName,
87+
mutationMethod: null,
88+
89+
mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY),
90+
hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE),
91+
hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE),
92+
hasPositiveNumericValue: checkMask(
93+
propConfig,
94+
Injection.HAS_POSITIVE_NUMERIC_VALUE
95+
),
96+
hasOverloadedBooleanValue: checkMask(
97+
propConfig,
98+
Injection.HAS_OVERLOADED_BOOLEAN_VALUE
99+
),
100+
hasStringBooleanValue: checkMask(
101+
propConfig,
102+
Injection.HAS_STRING_BOOLEAN_VALUE
103+
)
104+
};
105+
!(
106+
propertyInfo.hasBooleanValue +
107+
propertyInfo.hasNumericValue +
108+
propertyInfo.hasOverloadedBooleanValue <=
109+
1
110+
)
111+
? invariant(
112+
false,
113+
"DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s",
114+
propName
115+
)
116+
: void 0;
117+
118+
if (DOMAttributeNames.hasOwnProperty(propName)) {
119+
var attributeName = DOMAttributeNames[propName];
120+
121+
propertyInfo.attributeName = attributeName;
122+
}
123+
124+
if (DOMAttributeNamespaces.hasOwnProperty(propName)) {
125+
propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName];
126+
}
127+
128+
if (DOMMutationMethods.hasOwnProperty(propName)) {
129+
propertyInfo.mutationMethod = DOMMutationMethods[propName];
130+
}
131+
132+
// Downcase references to whitelist properties to check for membership
133+
// without case-sensitivity. This allows the whitelist to pick up
134+
// `allowfullscreen`, which should be written using the property configuration
135+
// for `allowFullscreen`
136+
properties[propName] = propertyInfo;
137+
}
138+
}
139+
};
140+
141+
/* eslint-disable max-len */
142+
var ATTRIBUTE_NAME_START_CHAR =
143+
":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
144+
/* eslint-enable max-len */
145+
var ATTRIBUTE_NAME_CHAR =
146+
ATTRIBUTE_NAME_START_CHAR +
147+
"\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
148+
149+
var ROOT_ATTRIBUTE_NAME = "data-reactroot";
150+
151+
/**
152+
* Map from property "standard name" to an object with info about how to set
153+
* the property in the DOM. Each object contains:
154+
*
155+
* attributeName:
156+
* Used when rendering markup or with `*Attribute()`.
157+
* attributeNamespace
158+
* propertyName:
159+
* Used on DOM node instances. (This includes properties that mutate due to
160+
* external factors.)
161+
* mutationMethod:
162+
* If non-null, used instead of the property or `setAttribute()` after
163+
* initial render.
164+
* mustUseProperty:
165+
* Whether the property must be accessed and mutated as an object property.
166+
* hasBooleanValue:
167+
* Whether the property should be removed when set to a falsey value.
168+
* hasNumericValue:
169+
* Whether the property must be numeric or parse as a numeric and should be
170+
* removed when set to a falsey value.
171+
* hasPositiveNumericValue:
172+
* Whether the property must be positive numeric or parse as a positive
173+
* numeric and should be removed when set to a falsey value.
174+
* hasOverloadedBooleanValue:
175+
* Whether the property can be used as a flag as well as with a value.
176+
* Removed when strictly equal to false; present without a value when
177+
* strictly equal to true; present with a value otherwise.
178+
*/
179+
180+
var properties = {};
181+
182+
/**
183+
* Checks whether a property name is a writeable attribute.
184+
* @method
185+
*/
186+
function shouldSetAttribute(name, value) {
187+
if (isReservedProp(name)) {
188+
return false;
189+
}
190+
if (
191+
name.length > 2 &&
192+
(name[0] === "o" || name[0] === "O") &&
193+
(name[1] === "n" || name[1] === "N")
194+
) {
195+
return false;
196+
}
197+
if (value === null) {
198+
return true;
199+
}
200+
switch (typeof value) {
201+
case "boolean":
202+
return shouldAttributeAcceptBooleanValue(name);
203+
case "undefined":
204+
case "number":
205+
case "string":
206+
case "object":
207+
return true;
208+
default:
209+
// function, symbol
210+
return false;
211+
}
212+
}
213+
214+
function getPropertyInfo(name) {
215+
return properties.hasOwnProperty(name) ? properties[name] : null;
216+
}
217+
218+
function shouldAttributeAcceptBooleanValue(name) {
219+
if (isReservedProp(name)) {
220+
return true;
221+
}
222+
var propertyInfo = getPropertyInfo(name);
223+
if (propertyInfo) {
224+
return (
225+
propertyInfo.hasBooleanValue ||
226+
propertyInfo.hasStringBooleanValue ||
227+
propertyInfo.hasOverloadedBooleanValue
228+
);
229+
}
230+
var prefix = name.toLowerCase().slice(0, 5);
231+
return prefix === "data-" || prefix === "aria-";
232+
}
233+
234+
/**
235+
* Checks to see if a property name is within the list of properties
236+
* reserved for internal React operations. These properties should
237+
* not be set on an HTML element.
238+
*
239+
* @private
240+
* @param {string} name
241+
* @return {boolean} If the name is within reserved props
242+
*/
243+
function isReservedProp(name) {
244+
return RESERVED_PROPS.hasOwnProperty(name);
245+
}
246+
247+
var injection = DOMPropertyInjection;
248+
249+
import quoteAttributeValueForBrowser from './quoteAttributeValueForBrowser';
250+
import warning from 'fbjs/lib/warning';
251+
252+
// isAttributeNameSafe() is currently duplicated in DOMPropertyOperations.
253+
// TODO: Find a better place for this.
254+
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp(
255+
"^[" + ATTRIBUTE_NAME_START_CHAR + "][" + ATTRIBUTE_NAME_CHAR + "]*$"
256+
);
257+
var illegalAttributeNameCache = {};
258+
var validatedAttributeNameCache = {};
259+
function isAttributeNameSafe(attributeName) {
260+
if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {
261+
return true;
262+
}
263+
if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {
264+
return false;
265+
}
266+
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
267+
validatedAttributeNameCache[attributeName] = true;
268+
return true;
269+
}
270+
illegalAttributeNameCache[attributeName] = true;
271+
{
272+
warning(false, "Invalid attribute name: `%s`", attributeName);
273+
}
274+
return false;
275+
}
276+
277+
// shouldIgnoreValue() is currently duplicated in DOMPropertyOperations.
278+
// TODO: Find a better place for this.
279+
function shouldIgnoreValue(propertyInfo, value) {
280+
return (
281+
value == null ||
282+
(propertyInfo.hasBooleanValue && !value) ||
283+
(propertyInfo.hasNumericValue && isNaN(value)) ||
284+
(propertyInfo.hasPositiveNumericValue && value < 1) ||
285+
(propertyInfo.hasOverloadedBooleanValue && value === false)
286+
);
287+
}
288+
289+
/**
290+
* Operations for dealing with DOM properties.
291+
*/
292+
293+
/**
294+
* Creates markup for the ID property.
295+
*
296+
* @param {string} id Unescaped ID.
297+
* @return {string} Markup string.
298+
*/
299+
300+
export function createMarkupForRoot() {
301+
return ROOT_ATTRIBUTE_NAME + '=""';
302+
}
303+
304+
/**
305+
* Creates markup for a property.
306+
*
307+
* @param {string} name
308+
* @param {*} value
309+
* @return {?string} Markup string, or null if the property was invalid.
310+
*/
311+
export function createMarkupForProperty(name, value) {
312+
var propertyInfo = getPropertyInfo(name);
313+
if (propertyInfo) {
314+
if (shouldIgnoreValue(propertyInfo, value)) {
315+
return "";
316+
}
317+
var attributeName = propertyInfo.attributeName;
318+
if (
319+
propertyInfo.hasBooleanValue ||
320+
(propertyInfo.hasOverloadedBooleanValue && value === true)
321+
) {
322+
return attributeName + '=""';
323+
} else if (
324+
typeof value !== "boolean" ||
325+
shouldAttributeAcceptBooleanValue(name)
326+
) {
327+
return attributeName + "=" + quoteAttributeValueForBrowser(value);
328+
}
329+
} else if (shouldSetAttribute(name, value)) {
330+
if (value == null) {
331+
return "";
332+
}
333+
return name + "=" + quoteAttributeValueForBrowser(value);
334+
}
335+
return null;
336+
}
337+
338+
/**
339+
* Creates markup for a custom property.
340+
*
341+
* @param {string} name
342+
* @param {*} value
343+
* @return {string} Markup string, or empty string if the property was invalid.
344+
*/
345+
export function createMarkupForCustomAttribute(name, value) {
346+
if (!isAttributeNameSafe(name) || value == null) {
347+
return "";
348+
}
349+
return name + "=" + quoteAttributeValueForBrowser(value);
350+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /