New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@cicada/render

Package Overview
Dependencies
Maintainers
4
Versions
107
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cicada/render - npm Package Compare versions

Comparing version 1.1.0 to 1.1.1

lib/__test__/util.test.js

21

lib/__test__/integration/dynamicRender.test.js

@@ -55,2 +55,4 @@ 'use strict';

var DISPLAY_NONE = '' + _createAppearance.STYLE_SHEET_PREFIX + _createAppearance.DISPLAY_NONE;
function createButton() {

@@ -202,2 +204,21 @@ var rendered = 0;

});
test('render with visible', function () {
var configWidthVisible = {
type: 'DynamicRender',
bind: 'dynamic',
visible: true
};
var container = (0, _enzyme.mount)(_react2.default.createElement(_Render2.default, {
stateTree: stateTree,
appearance: appearance,
components: components,
background: (0, _createBackground2.default)(backgroundDef, stateTree, appearance),
config: configWidthVisible
}));
var stateId = stateTree.get('dynamic')._id;
container.instance().appearance.setVisibleById(stateId, false);
expect(container.instance().appearance.isVisibleById(stateId)).toBe(false);
expect(container.root.html()).toEqual('<div class="' + DISPLAY_NONE + '"></div>');
});
});

@@ -204,0 +225,0 @@

143

lib/__test__/integration/visible.test.js
'use strict';
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');

@@ -49,5 +69,6 @@

var stateTree = null; /* eslint-disable react/no-multi-comp */
var DISPLAY_NONE = '' + _createAppearance.STYLE_SHEET_PREFIX + _createAppearance.DISPLAY_NONE; /* eslint-disable react/no-multi-comp */
/* eslint-disable newline-per-chained-call */
var stateTree = null;
var appearance = null;

@@ -59,2 +80,43 @@ beforeEach(function () {

/* eslint-disable */
var Inner = function (_React$Component) {
(0, _inherits3.default)(Inner, _React$Component);
function Inner() {
(0, _classCallCheck3.default)(this, Inner);
return (0, _possibleConstructorReturn3.default)(this, (Inner.__proto__ || (0, _getPrototypeOf2.default)(Inner)).apply(this, arguments));
}
(0, _createClass3.default)(Inner, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
'inner'
);
}
}]);
return Inner;
}(_react2.default.Component);
var NestedInner = function (_React$Component2) {
(0, _inherits3.default)(NestedInner, _React$Component2);
function NestedInner() {
(0, _classCallCheck3.default)(this, NestedInner);
return (0, _possibleConstructorReturn3.default)(this, (NestedInner.__proto__ || (0, _getPrototypeOf2.default)(NestedInner)).apply(this, arguments));
}
(0, _createClass3.default)(NestedInner, [{
key: 'render',
value: function render() {
return _react2.default.createElement(Inner, null);
}
}]);
return NestedInner;
}(_react2.default.Component);
/* eslint-enable */
var DemoComponent = {

@@ -70,8 +132,7 @@ getDefaultState: function getDefaultState() {

render: function render(_ref) {
var state = _ref.state,
style = _ref.style;
var state = _ref.state;
return _react2.default.createElement(
'div',
{ style: style },
null,
state.value

@@ -82,18 +143,58 @@ );

test('basic set appearance', function () {
var container = (0, _enzyme.mount)(_react2.default.createElement(_Render2.default, {
stateTree: stateTree,
appearance: appearance,
components: { Demo: (0, _connect2.default)(DemoComponent, 'Demo') },
config: {
bind: 'demo',
type: 'Demo',
visible: true
}
}));
describe('base set appearance', function () {
function checkComponentDisplay(Comp, html) {
var container = (0, _enzyme.mount)(_react2.default.createElement(_Render2.default, {
stateTree: stateTree,
appearance: appearance,
components: { Demo: (0, _connect2.default)(Comp, 'Demo') },
config: {
bind: 'demo',
type: 'Demo',
visible: true
}
}));
var stateId = stateTree.get('demo')._id;
container.instance().appearance.setVisibleById(stateId, false);
expect(container.instance().appearance.isVisibleById(stateId)).toBe(false);
expect(container.find('div').at(0).prop('style')).toEqual({ display: 'none' });
var stateId = stateTree.get('demo')._id;
container.instance().appearance.setVisibleById(stateId, false);
expect(container.instance().appearance.isVisibleById(stateId)).toBe(false);
expect(container.root.html()).toEqual(html);
return { container: container, stateId: stateId };
}
test('basic set and reset', function () {
var _checkComponentDispla = checkComponentDisplay({ render: function render() {
return _react2.default.createElement(
'div',
{ className: 'other' },
'content'
);
} }, '<div class="other ' + DISPLAY_NONE + '">content</div>'),
container = _checkComponentDispla.container,
stateId = _checkComponentDispla.stateId;
container.instance().appearance.setVisibleById(stateId, true);
expect(container.html()).toEqual('<div class="other">content</div>');
});
test('empty set', function () {
checkComponentDisplay({ render: function render() {
return null;
} }, null);
});
test('inner set', function () {
checkComponentDisplay({ render: function render() {
return _react2.default.createElement(Inner, null);
} }, '<div class="' + DISPLAY_NONE + '">inner</div>');
});
// 嵌套多层
test('nestedInner set', function () {
checkComponentDisplay({ render: function render() {
return _react2.default.createElement(NestedInner, null);
} }, '<div class="' + DISPLAY_NONE + '">inner</div>');
});
/* test.skip('stateless set', () => {
const Stateless = () => <div>stateless</div>
// Stateless function components cannot support visible appearance.
checkComponentDisplay({ render: () => <Stateless /> }, '<div>stateless</div>')
}) */
});

@@ -134,3 +235,3 @@

expect(appearance.isVisibleById(stateId)).toBe(false);
expect(container.find('Demo').at(1).find('div').at(0).prop('style')).toEqual({ display: 'none' });
expect(container.html()).toEqual('<div><div>hide</div><div class="' + DISPLAY_NONE + '"></div></div>');
});

@@ -174,3 +275,3 @@

expect(appearance.isVisibleById(stateId)).toBe(false);
expect(container.find('Demo').at(1).find('div').at(0).prop('style')).toEqual({ display: 'none' });
expect(container.html()).toEqual('<div><div>hide</div><div class="' + DISPLAY_NONE + '"></div></div>');
});

@@ -409,2 +409,4 @@ 'use strict';

this.subscribe = function (type, changes) {
// appearance 采用ref去控制不再需要触发render
if (type === _constant.CHANGE_APPEARANCE) return;
// CAUTION 在这里判断是因为未来 React 的 shouldComponentUpdate 会失效

@@ -411,0 +413,0 @@ if (shouldComponentUpdate === undefined || shouldComponentUpdate(_this6.getRenderArg(), type, changes) !== false) {

109

lib/createAppearance.js

@@ -6,2 +6,3 @@ 'use strict';

});
exports.STYLE_SHEET_PREFIX = exports.DISPLAY_NONE = undefined;

@@ -18,2 +19,6 @@ var _extends2 = require('babel-runtime/helpers/extends');

var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _util = require('./util');

@@ -27,6 +32,9 @@

var _constant = require('./constant');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var DISPLAY_NONE = exports.DISPLAY_NONE = 'DISPLAY_NONE';
var STYLE_SHEET_PREFIX = exports.STYLE_SHEET_PREFIX = 'CICADA_APPEAR_';
var prefixReg = new RegExp('^' + STYLE_SHEET_PREFIX);
/* eslint-disable no-use-before-define */
function createAppearance(stateTree) {

@@ -37,5 +45,33 @@ var externalProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

var subscribers = {};
var refCache = {};
var globalSubscribers = (0, _createSubscribers2.default)();
var stateIdByComponentPath = (0, _common.createOneToManyContainer)();
function createStylesheet(clsName, content) {
clsName = '' + STYLE_SHEET_PREFIX + clsName;
if (!document || document.getElementById(clsName)) return clsName;
var styleDom = document.createElement('style');
styleDom.setAttribute('id', clsName);
styleDom.innerText = '.' + clsName + ' ' + content;
document.head.appendChild(styleDom);
return clsName;
}
var displayNoneStyle = createStylesheet(DISPLAY_NONE, '{ display: none !important; }');
function updateAppearanceRef(id) {
var ref = refCache[id];
if (!ref) return;
var _appearance$id = appearance[id],
visible = _appearance$id.visible,
styleList = _appearance$id.styleList,
children = _appearance$id.children;
var classList = visible ? styleList : styleList.concat(displayNoneStyle);
var className = ref.className.split(/\s+/).filter(function (cls) {
return cls && !prefixReg.test(cls);
}).concat(classList).join(' ');
if (className) ref.className = className;
if (children !== undefined) ref.innerHTML = children;
}
function injectExternalListenerArg(id, listener, props) {

@@ -62,20 +98,2 @@ return function () {

var style = appearance[id].style;
if (!appearance[id].visible) {
style.display = 'none';
} else if (display === _constant.DISPLAY_BLOCK) {
delete style.display;
// style.display = 'block'
} else {
style.display = 'inline-block';
}
if (appearance[id].children !== undefined) {
componentArg.children = appearance[id].children;
}
// 所有组件属性默认注入style属性
componentArg.style = style;
var injectedExternalProps = (0, _util.mapValues)(externalProps, function (prop) {

@@ -89,3 +107,24 @@ if (typeof prop !== 'function') return prop;

return render(componentArg);
var comp = render(componentArg);
// maybe null
if (!comp) {
delete refCache[id];
return comp;
}
if ((0, _util.isStatelessComponent)(comp)) {
console.error('Stateless function components cannot support visible appearance.');
delete refCache[id];
return comp;
}
return _react2.default.cloneElement(comp, (0, _extends3.default)({}, comp.props, {
ref: function ref(_ref) {
_ref = _reactDom2.default.findDOMNode(_ref);
if (!_ref || !_ref.classList) {
delete refCache[id];
return;
}
refCache[id] = _ref;
updateAppearanceRef(id);
}
}));
};

@@ -116,8 +155,8 @@ }

return {
register: function register(id, _ref, fn) {
var componentPath = _ref.path;
register: function register(id, _ref2, fn) {
var componentPath = _ref2.path;
var unsubscribe = subscribeById(id, fn);
var unsubscribe = (0, _util.concat)([subscribeById(id, fn), subscribeById(id, (0, _util.partial)(updateAppearanceRef, id))]);
var componentPathKey = componentPath !== undefined ? componentPath.join('.') : undefined;
appearance[id] = { visible: true, style: {}, componentPath: componentPath
appearance[id] = { visible: true, styleList: [], componentPath: componentPath
// CAUTION 在与 react-router 这样的库结合使用时,由于会动态创建组件,

@@ -133,2 +172,3 @@ // 所以 Render 无法给组件打上 path, 要兼容这种情况。

delete appearance[id];
delete refCache[id];
if (componentPathKey !== undefined) {

@@ -158,7 +198,22 @@ stateIdByComponentPath.remove(componentPathKey, id);

subscribeById: subscribeById,
mergeStyleById: function mergeStyleById(id, styleToMerge) {
appearance[id].style = (0, _extends3.default)({}, appearance[id].style, styleToMerge);
addStyleById: function addStyleById(id) {
for (var _len2 = arguments.length, styleList = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
styleList[_key2 - 1] = arguments[_key2];
}
appearance[id].styleList = (0, _util.union)([], appearance[id].styleList.concat(styleList));
notify(id);
},
removeStyleById: function removeStyleById(id) {
for (var _len3 = arguments.length, styleList = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
styleList[_key3 - 1] = arguments[_key3];
}
appearance[id].styleList = appearance[id].styleList.filter(function (cls) {
return !styleList.includes(cls);
});
notify(id);
},
createStylesheet: createStylesheet,
getIdsByComponentPath: function getIdsByComponentPath(pathArr) {

@@ -165,0 +220,0 @@ return stateIdByComponentPath.get(pathArr.join('.'));

@@ -43,2 +43,4 @@ 'use strict';

var _constant = require('./constant');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -70,3 +72,5 @@

_this.subscribe = function () {
_this.subscribe = function (type) {
// appearance 采用ref去控制不再需要触发render
if (type === _constant.CHANGE_APPEARANCE) return;
_this.setState({ version: _this.state.version++ });

@@ -80,3 +84,3 @@ };

var _appearance$register = appearance.register(_this.id, config, _this.subscribe),
var _appearance$register = appearance.register(_this.id, config, (0, _util.partial)(_this.subscribe, _constant.CHANGE_APPEARANCE)),
unsubscribeAppearance = _appearance$register.cancel,

@@ -83,0 +87,0 @@ hijack = _appearance$register.hijack;

@@ -8,2 +8,6 @@ 'use strict';

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _typeof2 = require('babel-runtime/helpers/typeof');

@@ -72,3 +76,8 @@

exports.filterMap = filterMap;
exports.isStatelessComponent = isStatelessComponent;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -453,2 +462,9 @@

});
}
function isStatelessComponent(comp) {
if (!comp || !comp.type || !(typeof comp.type === 'function')) return false;
/* eslint-disable no-proto */
var isReactComponent = (comp.type.__proto__ || (0, _getPrototypeOf2.default)(comp.type)) === _react2.default.Component;
return !isReactComponent;
}
{
"name": "@cicada/render",
"version": "1.1.0",
"version": "1.1.1",
"main": "./lib/index.js",
"scripts": {
"test": "jest ./src",
"test:watch": "jest ./src --watch",
"coverage": "jest --coverage ./src",

@@ -8,0 +9,0 @@ "build": "rm -rf lib && babel src --out-dir lib",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc