From 3e59b16c27089fad5d2722e1c95aee794ad3e04a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=98=8E=E6=98=8E?= <970899069@qq.com> Date: Wed, 30 Dec 2020 10:17:56 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]wxmlToCanvas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- miniprogram_npm/eventemitter3/index.js | 348 +++++ miniprogram_npm/eventemitter3/index.js.map | 1 + miniprogram_npm/widget-ui/index.js | 12 + miniprogram_npm/widget-ui/index.js.map | 1 + miniprogram_npm/wxml-to-canvas/index.js | 779 +++++++++++ miniprogram_npm/wxml-to-canvas/index.json | 4 + miniprogram_npm/wxml-to-canvas/index.wxml | 2 + miniprogram_npm/wxml-to-canvas/index.wxss | 0 miniprogram_npm/wxml-to-canvas/utils.js | 57 + node_modules/eventemitter3/LICENSE | 21 + node_modules/eventemitter3/README.md | 94 ++ node_modules/eventemitter3/index.d.ts | 134 ++ node_modules/eventemitter3/index.js | 336 +++++ node_modules/eventemitter3/package.json | 84 ++ .../eventemitter3/umd/eventemitter3.js | 340 +++++ .../eventemitter3/umd/eventemitter3.min.js | 1 + .../umd/eventemitter3.min.js.map | 1 + node_modules/widget-ui/babel.config.js | 9 + node_modules/widget-ui/dist/element.d.ts | 40 + node_modules/widget-ui/dist/event.d.ts | 5 + node_modules/widget-ui/dist/index.js | 1 + node_modules/widget-ui/dist/style.d.ts | 36 + node_modules/widget-ui/jest.config.js | 6 + node_modules/widget-ui/package.json | 52 + node_modules/widget-ui/src/css-layout.js | 1186 +++++++++++++++++ node_modules/widget-ui/src/element.ts | 172 +++ node_modules/widget-ui/src/event.ts | 15 + node_modules/widget-ui/src/style.ts | 87 ++ .../widget-ui/test/css-layout.test.ts | 183 +++ node_modules/widget-ui/tsconfig.json | 47 + node_modules/widget-ui/tslint.json | 206 +++ node_modules/widget-ui/webpack.config.js | 25 + node_modules/wxml-to-canvas/.babelrc | 10 + node_modules/wxml-to-canvas/.eslintrc.js | 99 ++ node_modules/wxml-to-canvas/LICENSE | 21 + node_modules/wxml-to-canvas/README.md | 187 +++ node_modules/wxml-to-canvas/gulpfile.js | 26 + .../wxml-to-canvas/miniprogram_dist/index.js | 779 +++++++++++ .../miniprogram_dist/index.json | 4 + .../miniprogram_dist/index.wxml | 2 + .../miniprogram_dist/index.wxss | 0 .../wxml-to-canvas/miniprogram_dist/utils.js | 57 + node_modules/wxml-to-canvas/package.json | 91 ++ node_modules/wxml-to-canvas/src/draw.js | 225 ++++ node_modules/wxml-to-canvas/src/index.js | 117 ++ node_modules/wxml-to-canvas/src/index.json | 4 + node_modules/wxml-to-canvas/src/index.wxml | 2 + node_modules/wxml-to-canvas/src/index.wxss | 0 node_modules/wxml-to-canvas/src/utils.js | 57 + node_modules/wxml-to-canvas/src/widget.js | 81 ++ node_modules/wxml-to-canvas/src/xml-parser.js | 164 +++ package-lock.json | 21 + package.json | 3 +- 53 files changed, 6234 insertions(+), 1 deletion(-) create mode 100644 miniprogram_npm/eventemitter3/index.js create mode 100644 miniprogram_npm/eventemitter3/index.js.map create mode 100644 miniprogram_npm/widget-ui/index.js create mode 100644 miniprogram_npm/widget-ui/index.js.map create mode 100644 miniprogram_npm/wxml-to-canvas/index.js create mode 100644 miniprogram_npm/wxml-to-canvas/index.json create mode 100644 miniprogram_npm/wxml-to-canvas/index.wxml create mode 100644 miniprogram_npm/wxml-to-canvas/index.wxss create mode 100644 miniprogram_npm/wxml-to-canvas/utils.js create mode 100644 node_modules/eventemitter3/LICENSE create mode 100644 node_modules/eventemitter3/README.md create mode 100644 node_modules/eventemitter3/index.d.ts create mode 100644 node_modules/eventemitter3/index.js create mode 100644 node_modules/eventemitter3/package.json create mode 100644 node_modules/eventemitter3/umd/eventemitter3.js create mode 100644 node_modules/eventemitter3/umd/eventemitter3.min.js create mode 100644 node_modules/eventemitter3/umd/eventemitter3.min.js.map create mode 100644 node_modules/widget-ui/babel.config.js create mode 100644 node_modules/widget-ui/dist/element.d.ts create mode 100644 node_modules/widget-ui/dist/event.d.ts create mode 100644 node_modules/widget-ui/dist/index.js create mode 100644 node_modules/widget-ui/dist/style.d.ts create mode 100644 node_modules/widget-ui/jest.config.js create mode 100644 node_modules/widget-ui/package.json create mode 100644 node_modules/widget-ui/src/css-layout.js create mode 100644 node_modules/widget-ui/src/element.ts create mode 100644 node_modules/widget-ui/src/event.ts create mode 100644 node_modules/widget-ui/src/style.ts create mode 100644 node_modules/widget-ui/test/css-layout.test.ts create mode 100644 node_modules/widget-ui/tsconfig.json create mode 100644 node_modules/widget-ui/tslint.json create mode 100644 node_modules/widget-ui/webpack.config.js create mode 100644 node_modules/wxml-to-canvas/.babelrc create mode 100644 node_modules/wxml-to-canvas/.eslintrc.js create mode 100644 node_modules/wxml-to-canvas/LICENSE create mode 100644 node_modules/wxml-to-canvas/README.md create mode 100644 node_modules/wxml-to-canvas/gulpfile.js create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.js create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.json create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.wxml create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.wxss create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/utils.js create mode 100644 node_modules/wxml-to-canvas/package.json create mode 100644 node_modules/wxml-to-canvas/src/draw.js create mode 100644 node_modules/wxml-to-canvas/src/index.js create mode 100644 node_modules/wxml-to-canvas/src/index.json create mode 100644 node_modules/wxml-to-canvas/src/index.wxml create mode 100644 node_modules/wxml-to-canvas/src/index.wxss create mode 100644 node_modules/wxml-to-canvas/src/utils.js create mode 100644 node_modules/wxml-to-canvas/src/widget.js create mode 100644 node_modules/wxml-to-canvas/src/xml-parser.js diff --git a/miniprogram_npm/eventemitter3/index.js b/miniprogram_npm/eventemitter3/index.js new file mode 100644 index 0000000..81fe254 --- /dev/null +++ b/miniprogram_npm/eventemitter3/index.js @@ -0,0 +1,348 @@ +module.exports = (function() { +var __MODS__ = {}; +var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; }; +var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; }; +var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } }; +var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; }; +__DEFINE__(1609290924689, function(require, module, exports) { + + +var has = Object.prototype.hasOwnProperty + , prefix = '~'; + +/** + * Constructor to create a storage for our `EE` objects. + * An `Events` instance is a plain object whose properties are event names. + * + * @constructor + * @private + */ +function Events() {} + +// +// We try to not inherit from `Object.prototype`. In some engines creating an +// instance in this way is faster than calling `Object.create(null)` directly. +// If `Object.create(null)` is not supported we prefix the event names with a +// character to make sure that the built-in object properties are not +// overridden or used as an attack vector. +// +if (Object.create) { + Events.prototype = Object.create(null); + + // + // This hack is needed because the `__proto__` property is still inherited in + // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. + // + if (!new Events().__proto__) prefix = false; +} + +/** + * Representation of a single event listener. + * + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} [once=false] Specify if the listener is a one-time listener. + * @constructor + * @private + */ +function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; +} + +/** + * Add a listener for a given event. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} once Specify if the listener is a one-time listener. + * @returns {EventEmitter} + * @private + */ +function addListener(emitter, event, fn, context, once) { + if (typeof fn !== 'function') { + throw new TypeError('The listener must be a function'); + } + + var listener = new EE(fn, context || emitter, once) + , evt = prefix ? prefix + event : event; + + if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; + else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); + else emitter._events[evt] = [emitter._events[evt], listener]; + + return emitter; +} + +/** + * Clear event by name. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} evt The Event name. + * @private + */ +function clearEvent(emitter, evt) { + if (--emitter._eventsCount === 0) emitter._events = new Events(); + else delete emitter._events[evt]; +} + +/** + * Minimal `EventEmitter` interface that is molded against the Node.js + * `EventEmitter` interface. + * + * @constructor + * @public + */ +function EventEmitter() { + this._events = new Events(); + this._eventsCount = 0; +} + +/** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @public + */ +EventEmitter.prototype.eventNames = function eventNames() { + var names = [] + , events + , name; + + if (this._eventsCount === 0) return names; + + for (name in (events = this._events)) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; +}; + +/** + * Return the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Array} The registered listeners. + * @public + */ +EventEmitter.prototype.listeners = function listeners(event) { + var evt = prefix ? prefix + event : event + , handlers = this._events[evt]; + + if (!handlers) return []; + if (handlers.fn) return [handlers.fn]; + + for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { + ee[i] = handlers[i].fn; + } + + return ee; +}; + +/** + * Return the number of listeners listening to a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Number} The number of listeners. + * @public + */ +EventEmitter.prototype.listenerCount = function listenerCount(event) { + var evt = prefix ? prefix + event : event + , listeners = this._events[evt]; + + if (!listeners) return 0; + if (listeners.fn) return 1; + return listeners.length; +}; + +/** + * Calls each of the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Boolean} `true` if the event had listeners, else `false`. + * @public + */ +EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return false; + + var listeners = this._events[evt] + , len = arguments.length + , args + , i; + + if (listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); + + switch (len) { + case 1: return listeners.fn.call(listeners.context), true; + case 2: return listeners.fn.call(listeners.context, a1), true; + case 3: return listeners.fn.call(listeners.context, a1, a2), true; + case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; + } + + for (i = 1, args = new Array(len -1); i < len; i++) { + args[i - 1] = arguments[i]; + } + + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length + , j; + + for (i = 0; i < length; i++) { + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); + + switch (len) { + case 1: listeners[i].fn.call(listeners[i].context); break; + case 2: listeners[i].fn.call(listeners[i].context, a1); break; + case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; + case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; + default: + if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { + args[j - 1] = arguments[j]; + } + + listeners[i].fn.apply(listeners[i].context, args); + } + } + } + + return true; +}; + +/** + * Add a listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.on = function on(event, fn, context) { + return addListener(this, event, fn, context, false); +}; + +/** + * Add a one-time listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.once = function once(event, fn, context) { + return addListener(this, event, fn, context, true); +}; + +/** + * Remove the listeners of a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {Boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return this; + if (!fn) { + clearEvent(this, evt); + return this; + } + + var listeners = this._events[evt]; + + if (listeners.fn) { + if ( + listeners.fn === fn && + (!once || listeners.once) && + (!context || listeners.context === context) + ) { + clearEvent(this, evt); + } + } else { + for (var i = 0, events = [], length = listeners.length; i < length; i++) { + if ( + listeners[i].fn !== fn || + (once && !listeners[i].once) || + (context && listeners[i].context !== context) + ) { + events.push(listeners[i]); + } + } + + // + // Reset the array, or remove it completely if we have no more listeners. + // + if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; + else clearEvent(this, evt); + } + + return this; +}; + +/** + * Remove all listeners, or those of the specified event. + * + * @param {(String|Symbol)} [event] The event name. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { + var evt; + + if (event) { + evt = prefix ? prefix + event : event; + if (this._events[evt]) clearEvent(this, evt); + } else { + this._events = new Events(); + this._eventsCount = 0; + } + + return this; +}; + +// +// Alias methods names because people roll like that. +// +EventEmitter.prototype.off = EventEmitter.prototype.removeListener; +EventEmitter.prototype.addListener = EventEmitter.prototype.on; + +// +// Expose the prefix. +// +EventEmitter.prefixed = prefix; + +// +// Allow `EventEmitter` to be imported as module namespace. +// +EventEmitter.EventEmitter = EventEmitter; + +// +// Expose the module. +// +if ('undefined' !== typeof module) { + module.exports = EventEmitter; +} + +}, function(modId) {var map = {}; return __REQUIRE__(map[modId], modId); }) +return __REQUIRE__(1609290924689); +})() +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/miniprogram_npm/eventemitter3/index.js.map b/miniprogram_npm/eventemitter3/index.js.map new file mode 100644 index 0000000..4f2cb7b --- /dev/null +++ b/miniprogram_npm/eventemitter3/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["index.js"],"names":[],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.js","sourcesContent":["\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n"]} \ No newline at end of file diff --git a/miniprogram_npm/widget-ui/index.js b/miniprogram_npm/widget-ui/index.js new file mode 100644 index 0000000..39dd169 --- /dev/null +++ b/miniprogram_npm/widget-ui/index.js @@ -0,0 +1,12 @@ +module.exports = (function() { +var __MODS__ = {}; +var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; }; +var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; }; +var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } }; +var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; }; +__DEFINE__(1609290924690, function(require, module, exports) { +!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o=e();for(var r in o)("object"==typeof exports?exports:t)[r]=o[r]}}(this,(function(){return function(t){var e={};function o(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,o),i.l=!0,i.exports}return o.m=t,o.c=e,o.d=function(t,e,r){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)o.d(r,i,function(e){return t[e]}.bind(null,i));return r},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=0)}([function(t,e,o){var r=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0});var i=r(o(1)),l=o(2),n=0,a=function(){function t(e){var o=this;void 0===e&&(e={}),this.parent=null,this.id=t.uuid(),this.style={},this.computedStyle={},this.lastComputedStyle={},this.children={},this.layoutBox={left:0,top:0,width:0,height:0},e=Object.assign(l.getDefaultStyle(),e),this.computedStyle=Object.assign(l.getDefaultStyle(),e),this.lastComputedStyle=Object.assign(l.getDefaultStyle(),e),Object.keys(e).forEach((function(t){Object.defineProperty(o.style,t,{configurable:!0,enumerable:!0,get:function(){return e[t]},set:function(r){r!==e[t]&&void 0!==r&&(o.lastComputedStyle=o.computedStyle[t],e[t]=r,o.computedStyle[t]=r,l.scalableStyles.includes(t)&&o.style.scale&&(o.computedStyle[t]=r*o.style.scale),"scale"===t&&l.scalableStyles.forEach((function(t){e[t]&&(o.computedStyle[t]=e[t]*r)})),"hidden"===t&&(r?l.layoutAffectedStyles.forEach((function(t){o.computedStyle[t]=0})):l.layoutAffectedStyles.forEach((function(t){o.computedStyle[t]=o.lastComputedStyle[t]}))))}})})),this.style.scale&&l.scalableStyles.forEach((function(t){if(o.style[t]){var e=o.style[t]*o.style.scale;o.computedStyle[t]=e}})),e.hidden&&l.layoutAffectedStyles.forEach((function(t){o.computedStyle[t]=0}))}return t.uuid=function(){return n++},t.prototype.getAbsolutePosition=function(t){if(!t)return this.getAbsolutePosition(this);if(!t.parent)return{left:0,top:0};var e=this.getAbsolutePosition(t.parent),o=e.left,r=e.top;return{left:o+t.layoutBox.left,top:r+t.layoutBox.top}},t.prototype.add=function(t){t.parent=this,this.children[t.id]=t},t.prototype.remove=function(t){var e=this;t?this.children[t.id]&&(t.remove(),delete this.children[t.id]):Object.keys(this.children).forEach((function(t){e.children[t].remove(),delete e.children[t]}))},t.prototype.getNodeTree=function(){var t=this;return{id:this.id,style:this.computedStyle,children:Object.keys(this.children).map((function(e){return t.children[e].getNodeTree()}))}},t.prototype.applyLayout=function(t){var e=this;["left","top","width","height"].forEach((function(o){t.layout&&"number"==typeof t.layout[o]&&(e.layoutBox[o]=t.layout[o],!e.parent||"left"!==o&&"top"!==o||(e.layoutBox[o]+=e.parent.layoutBox[o]))})),t.children.forEach((function(t){e.children[t.id].applyLayout(t)}))},t.prototype.layout=function(){var t=this.getNodeTree();i.default(t),this.applyLayout(t)},t}();e.default=a},function(t,e,o){o.r(e);var r=function(){var t,e="inherit",o="ltr",r="rtl",i="row",l="row-reverse",n="column",a="column-reverse",u="flex-start",d="center",s="flex-end",y="space-between",c="space-around",f="flex-start",h="center",p="flex-end",g="stretch",v="relative",m="absolute",b={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},x={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},w={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},S={row:"width","row-reverse":"width",column:"height","column-reverse":"height"};function W(t){return void 0===t}function L(t){return t===i||t===l}function k(t,e){if(void 0!==t.style.marginStart&&L(e))return t.style.marginStart;var o=null;switch(e){case"row":o=t.style.marginLeft;break;case"row-reverse":o=t.style.marginRight;break;case"column":o=t.style.marginTop;break;case"column-reverse":o=t.style.marginBottom}return void 0!==o?o:void 0!==t.style.margin?t.style.margin:0}function j(t,e){if(void 0!==t.style.marginEnd&&L(e))return t.style.marginEnd;var o=null;switch(e){case"row":o=t.style.marginRight;break;case"row-reverse":o=t.style.marginLeft;break;case"column":o=t.style.marginBottom;break;case"column-reverse":o=t.style.marginTop}return null!=o?o:void 0!==t.style.margin?t.style.margin:0}function B(t,e){if(void 0!==t.style.borderStartWidth&&t.style.borderStartWidth>=0&&L(e))return t.style.borderStartWidth;var o=null;switch(e){case"row":o=t.style.borderLeftWidth;break;case"row-reverse":o=t.style.borderRightWidth;break;case"column":o=t.style.borderTopWidth;break;case"column-reverse":o=t.style.borderBottomWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function E(t,e){if(void 0!==t.style.borderEndWidth&&t.style.borderEndWidth>=0&&L(e))return t.style.borderEndWidth;var o=null;switch(e){case"row":o=t.style.borderRightWidth;break;case"row-reverse":o=t.style.borderLeftWidth;break;case"column":o=t.style.borderBottomWidth;break;case"column-reverse":o=t.style.borderTopWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function C(t,e){return function(t,e){if(void 0!==t.style.paddingStart&&t.style.paddingStart>=0&&L(e))return t.style.paddingStart;var o=null;switch(e){case"row":o=t.style.paddingLeft;break;case"row-reverse":o=t.style.paddingRight;break;case"column":o=t.style.paddingTop;break;case"column-reverse":o=t.style.paddingBottom}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+B(t,e)}function T(t,e){return function(t,e){if(void 0!==t.style.paddingEnd&&t.style.paddingEnd>=0&&L(e))return t.style.paddingEnd;var o=null;switch(e){case"row":o=t.style.paddingRight;break;case"row-reverse":o=t.style.paddingLeft;break;case"column":o=t.style.paddingBottom;break;case"column-reverse":o=t.style.paddingTop}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+E(t,e)}function O(t,e){return B(t,e)+E(t,e)}function _(t,e){return k(t,e)+j(t,e)}function R(t,e){return C(t,e)+T(t,e)}function A(t,e){return e.style.alignSelf?e.style.alignSelf:t.style.alignItems?t.style.alignItems:"stretch"}function P(t,e){if(e===r){if(t===i)return l;if(t===l)return i}return t}function D(t,e){return function(t){return t===n||t===a}(t)?P(i,e):n}function H(t){return t.style.position?t.style.position:"relative"}function M(t){return H(t)===v&&t.style.flex>0}function I(t,e){return t.layout[S[e]]+_(t,e)}function N(t,e){return void 0!==t.style[S[e]]&&t.style[S[e]]>=0}function F(t,e){return void 0!==t.style[e]}function q(t,e){return void 0!==t.style[e]?t.style[e]:0}function z(t,e,o){var r={row:t.style.minWidth,"row-reverse":t.style.minWidth,column:t.style.minHeight,"column-reverse":t.style.minHeight}[e],i={row:t.style.maxWidth,"row-reverse":t.style.maxWidth,column:t.style.maxHeight,"column-reverse":t.style.maxHeight}[e],l=o;return void 0!==i&&i>=0&&l>i&&(l=i),void 0!==r&&r>=0&&le?t:e}function G(t,e){void 0===t.layout[S[e]]&&N(t,e)&&(t.layout[S[e]]=U(z(t,e,t.style[S[e]]),R(t,e)))}function J(t,e,o){e.layout[x[o]]=t.layout[S[o]]-e.layout[S[o]]-e.layout[w[o]]}function K(t,e){return void 0!==t.style[b[e]]?q(t,b[e]):-q(t,x[e])}function Q(r,E,Q){var X=function(t,r){var i;return(i=t.style.direction?t.style.direction:e)===e&&(i=void 0===r?o:r),i}(r,Q),Y=P(function(t){return t.style.flexDirection?t.style.flexDirection:n}(r),X),Z=D(Y,X),$=P(i,X);G(r,Y),G(r,Z),r.layout.direction=X,r.layout[b[Y]]+=k(r,Y)+K(r,Y),r.layout[x[Y]]+=j(r,Y)+K(r,Y),r.layout[b[Z]]+=k(r,Z)+K(r,Z),r.layout[x[Z]]+=j(r,Z)+K(r,Z);var tt=r.children.length,et=R(r,$);if(function(t){return void 0!==t.style.measure}(r)){var ot=!W(r.layout[S[$]]),rt=t;rt=N(r,$)?r.style.width:ot?r.layout[S[$]]:E-_(r,$),rt-=et;var it=!N(r,$)&&!ot,lt=!N(r,n)&&W(r.layout[S[n]]);if(it||lt){var nt=r.style.measure(rt);it&&(r.layout.width=nt.width+et),lt&&(r.layout.height=nt.height+R(r,n))}if(0===tt)return}var at,ut,dt,st,yt=function(t){return"wrap"===t.style.flexWrap}(r),ct=function(t){return t.style.justifyContent?t.style.justifyContent:"flex-start"}(r),ft=C(r,Y),ht=C(r,Z),pt=R(r,Y),gt=R(r,Z),vt=!W(r.layout[S[Y]]),mt=!W(r.layout[S[Z]]),bt=L(Y),xt=null,wt=null,St=t;vt&&(St=r.layout[S[Y]]-pt);for(var Wt=0,Lt=0,kt=0,jt=0,Bt=0,Et=0;LtSt&&at!==Wt){Rt--,kt=1;break}At&&(H(dt)!==v||M(dt))&&(At=!1,Pt=at),Dt&&(H(dt)!==v||Xt!==g&&Xt!==f||W(dt.layout[S[Z]]))&&(Dt=!1,Ht=at),At&&(dt.layout[w[Y]]+=Nt,vt&&J(r,dt,Y),Nt+=I(dt,Y),Ft=U(Ft,z(dt,Z,I(dt,Z)))),Dt&&(dt.layout[w[Z]]+=jt+ht,mt&&J(r,dt,Z)),kt=0,Tt+=qt,Lt=at+1}var zt=0,Ut=0,Gt=0;if(Gt=vt?St-Tt:U(Tt,0)-Tt,0!==Ot){var Jt,Kt,Qt=Gt/_t;for(It=Mt;null!==It;)(Jt=Qt*It.style.flex+R(It,Y))!==(Kt=z(It,Y,Jt))&&(Gt-=Kt,_t-=It.style.flex),It=It.nextFlexChild;for((Qt=Gt/_t)<0&&(Qt=0),It=Mt;null!==It;)It.layout[S[Y]]=z(It,Y,Qt*It.style.flex+R(It,Y)),Ct=t,N(r,$)?Ct=r.layout[S[$]]-et:bt||(Ct=E-_(r,$)-et),V(It,Ct,X),dt=It,It=It.nextFlexChild,dt.nextFlexChild=null}else ct!==u&&(ct===d?zt=Gt/2:ct===s?zt=Gt:ct===y?(Gt=U(Gt,0),Ut=Ot+Rt-1!=0?Gt/(Ot+Rt-1):0):ct===c&&(zt=(Ut=Gt/(Ot+Rt))/2));for(Nt+=zt,at=Pt;at1&&mt){var $t=r.layout[S[Z]]-gt,te=$t-jt,ee=0,oe=ht,re=function(t){return t.style.alignContent?t.style.alignContent:"flex-start"}(r);re===p?oe+=te:re===h?oe+=te/2:re===g&&$t>jt&&(ee=te/Et);var ie=0;for(at=0;at=0&&L(e))return t.style.borderStartWidth;var o=null;switch(e){case\"row\":o=t.style.borderLeftWidth;break;case\"row-reverse\":o=t.style.borderRightWidth;break;case\"column\":o=t.style.borderTopWidth;break;case\"column-reverse\":o=t.style.borderBottomWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function E(t,e){if(void 0!==t.style.borderEndWidth&&t.style.borderEndWidth>=0&&L(e))return t.style.borderEndWidth;var o=null;switch(e){case\"row\":o=t.style.borderRightWidth;break;case\"row-reverse\":o=t.style.borderLeftWidth;break;case\"column\":o=t.style.borderBottomWidth;break;case\"column-reverse\":o=t.style.borderTopWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function C(t,e){return function(t,e){if(void 0!==t.style.paddingStart&&t.style.paddingStart>=0&&L(e))return t.style.paddingStart;var o=null;switch(e){case\"row\":o=t.style.paddingLeft;break;case\"row-reverse\":o=t.style.paddingRight;break;case\"column\":o=t.style.paddingTop;break;case\"column-reverse\":o=t.style.paddingBottom}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+B(t,e)}function T(t,e){return function(t,e){if(void 0!==t.style.paddingEnd&&t.style.paddingEnd>=0&&L(e))return t.style.paddingEnd;var o=null;switch(e){case\"row\":o=t.style.paddingRight;break;case\"row-reverse\":o=t.style.paddingLeft;break;case\"column\":o=t.style.paddingBottom;break;case\"column-reverse\":o=t.style.paddingTop}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+E(t,e)}function O(t,e){return B(t,e)+E(t,e)}function _(t,e){return k(t,e)+j(t,e)}function R(t,e){return C(t,e)+T(t,e)}function A(t,e){return e.style.alignSelf?e.style.alignSelf:t.style.alignItems?t.style.alignItems:\"stretch\"}function P(t,e){if(e===r){if(t===i)return l;if(t===l)return i}return t}function D(t,e){return function(t){return t===n||t===a}(t)?P(i,e):n}function H(t){return t.style.position?t.style.position:\"relative\"}function M(t){return H(t)===v&&t.style.flex>0}function I(t,e){return t.layout[S[e]]+_(t,e)}function N(t,e){return void 0!==t.style[S[e]]&&t.style[S[e]]>=0}function F(t,e){return void 0!==t.style[e]}function q(t,e){return void 0!==t.style[e]?t.style[e]:0}function z(t,e,o){var r={row:t.style.minWidth,\"row-reverse\":t.style.minWidth,column:t.style.minHeight,\"column-reverse\":t.style.minHeight}[e],i={row:t.style.maxWidth,\"row-reverse\":t.style.maxWidth,column:t.style.maxHeight,\"column-reverse\":t.style.maxHeight}[e],l=o;return void 0!==i&&i>=0&&l>i&&(l=i),void 0!==r&&r>=0&&le?t:e}function G(t,e){void 0===t.layout[S[e]]&&N(t,e)&&(t.layout[S[e]]=U(z(t,e,t.style[S[e]]),R(t,e)))}function J(t,e,o){e.layout[x[o]]=t.layout[S[o]]-e.layout[S[o]]-e.layout[w[o]]}function K(t,e){return void 0!==t.style[b[e]]?q(t,b[e]):-q(t,x[e])}function Q(r,E,Q){var X=function(t,r){var i;return(i=t.style.direction?t.style.direction:e)===e&&(i=void 0===r?o:r),i}(r,Q),Y=P(function(t){return t.style.flexDirection?t.style.flexDirection:n}(r),X),Z=D(Y,X),$=P(i,X);G(r,Y),G(r,Z),r.layout.direction=X,r.layout[b[Y]]+=k(r,Y)+K(r,Y),r.layout[x[Y]]+=j(r,Y)+K(r,Y),r.layout[b[Z]]+=k(r,Z)+K(r,Z),r.layout[x[Z]]+=j(r,Z)+K(r,Z);var tt=r.children.length,et=R(r,$);if(function(t){return void 0!==t.style.measure}(r)){var ot=!W(r.layout[S[$]]),rt=t;rt=N(r,$)?r.style.width:ot?r.layout[S[$]]:E-_(r,$),rt-=et;var it=!N(r,$)&&!ot,lt=!N(r,n)&&W(r.layout[S[n]]);if(it||lt){var nt=r.style.measure(rt);it&&(r.layout.width=nt.width+et),lt&&(r.layout.height=nt.height+R(r,n))}if(0===tt)return}var at,ut,dt,st,yt=function(t){return\"wrap\"===t.style.flexWrap}(r),ct=function(t){return t.style.justifyContent?t.style.justifyContent:\"flex-start\"}(r),ft=C(r,Y),ht=C(r,Z),pt=R(r,Y),gt=R(r,Z),vt=!W(r.layout[S[Y]]),mt=!W(r.layout[S[Z]]),bt=L(Y),xt=null,wt=null,St=t;vt&&(St=r.layout[S[Y]]-pt);for(var Wt=0,Lt=0,kt=0,jt=0,Bt=0,Et=0;LtSt&&at!==Wt){Rt--,kt=1;break}At&&(H(dt)!==v||M(dt))&&(At=!1,Pt=at),Dt&&(H(dt)!==v||Xt!==g&&Xt!==f||W(dt.layout[S[Z]]))&&(Dt=!1,Ht=at),At&&(dt.layout[w[Y]]+=Nt,vt&&J(r,dt,Y),Nt+=I(dt,Y),Ft=U(Ft,z(dt,Z,I(dt,Z)))),Dt&&(dt.layout[w[Z]]+=jt+ht,mt&&J(r,dt,Z)),kt=0,Tt+=qt,Lt=at+1}var zt=0,Ut=0,Gt=0;if(Gt=vt?St-Tt:U(Tt,0)-Tt,0!==Ot){var Jt,Kt,Qt=Gt/_t;for(It=Mt;null!==It;)(Jt=Qt*It.style.flex+R(It,Y))!==(Kt=z(It,Y,Jt))&&(Gt-=Kt,_t-=It.style.flex),It=It.nextFlexChild;for((Qt=Gt/_t)<0&&(Qt=0),It=Mt;null!==It;)It.layout[S[Y]]=z(It,Y,Qt*It.style.flex+R(It,Y)),Ct=t,N(r,$)?Ct=r.layout[S[$]]-et:bt||(Ct=E-_(r,$)-et),V(It,Ct,X),dt=It,It=It.nextFlexChild,dt.nextFlexChild=null}else ct!==u&&(ct===d?zt=Gt/2:ct===s?zt=Gt:ct===y?(Gt=U(Gt,0),Ut=Ot+Rt-1!=0?Gt/(Ot+Rt-1):0):ct===c&&(zt=(Ut=Gt/(Ot+Rt))/2));for(Nt+=zt,at=Pt;at1&&mt){var $t=r.layout[S[Z]]-gt,te=$t-jt,ee=0,oe=ht,re=function(t){return t.style.alignContent?t.style.alignContent:\"flex-start\"}(r);re===p?oe+=te:re===h?oe+=te/2:re===g&&$t>jt&&(ee=te/Et);var ie=0;for(at=0;at { + let result = null + + if (/^#/.test(color) && (color.length === 7 || color.length === 9)) { + return color + // eslint-disable-next-line no-cond-assign + } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) { + return '#' + result[2].split(',').map((part, index) => { + part = part.trim() + part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10) + part = part.toString(16) + if (part.length === 1) { + part = '0' + part + } + return part + }).join('') + } else { + return '#00000000' + } +} + +const splitLineToCamelCase = (str) => str.split('-').map((part, index) => { + if (index === 0) { + return part + } + return part[0].toUpperCase() + part.slice(1) +}).join('') + +const compareVersion = (v1, v2) => { + v1 = v1.split('.') + v2 = v2.split('.') + const len = Math.max(v1.length, v2.length) + while (v1.length < len) { + v1.push('0') + } + while (v2.length < len) { + v2.push('0') + } + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i], 10) + const num2 = parseInt(v2[i], 10) + + if (num1 > num2) { + return 1 + } else if (num1 < num2) { + return -1 + } + } + + return 0 +} + +module.exports = { + hex, + splitLineToCamelCase, + compareVersion +} + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + +const xmlParse = __webpack_require__(2) +const {Widget} = __webpack_require__(3) +const {Draw} = __webpack_require__(5) +const {compareVersion} = __webpack_require__(0) + +const canvasId = 'weui-canvas' + +Component({ + properties: { + width: { + type: Number, + value: 400 + }, + height: { + type: Number, + value: 300 + } + }, + data: { + use2dCanvas: false, // 2.9.2 后可用canvas 2d 接口 + }, + lifetimes: { + attached() { + const {SDKVersion, pixelRatio: dpr} = wx.getSystemInfoSync() + const use2dCanvas = compareVersion(SDKVersion, '2.9.2') >= 0 + this.dpr = dpr + this.setData({use2dCanvas}, () => { + if (use2dCanvas) { + const query = this.createSelectorQuery() + query.select(`#${canvasId}`) + .fields({node: true, size: true}) + .exec(res => { + const canvas = res[0].node + const ctx = canvas.getContext('2d') + canvas.width = res[0].width * dpr + canvas.height = res[0].height * dpr + ctx.scale(dpr, dpr) + this.ctx = ctx + this.canvas = canvas + }) + } else { + this.ctx = wx.createCanvasContext(canvasId, this) + } + }) + } + }, + methods: { + async renderToCanvas(args) { + const {wxml, style} = args + const ctx = this.ctx + const canvas = this.canvas + const use2dCanvas = this.data.use2dCanvas + + if (use2dCanvas && !canvas) { + return Promise.reject(new Error('renderToCanvas: fail canvas has not been created')) + } + + ctx.clearRect(0, 0, this.data.width, this.data.height) + const {root: xom} = xmlParse(wxml) + + const widget = new Widget(xom, style) + const container = widget.init() + this.boundary = { + top: container.layoutBox.top, + left: container.layoutBox.left, + width: container.computedStyle.width, + height: container.computedStyle.height, + } + const draw = new Draw(ctx, canvas, use2dCanvas) + await draw.drawNode(container) + + if (!use2dCanvas) { + await this.canvasDraw(ctx) + } + return Promise.resolve(container) + }, + + canvasDraw(ctx, reserve) { + return new Promise(resolve => { + ctx.draw(reserve, () => { + resolve() + }) + }) + }, + + canvasToTempFilePath(args = {}) { + const use2dCanvas = this.data.use2dCanvas + + return new Promise((resolve, reject) => { + const { + top, left, width, height + } = this.boundary + + const copyArgs = { + x: left, + y: top, + width, + height, + destWidth: width * this.dpr, + destHeight: height * this.dpr, + canvasId, + fileType: args.fileType || 'png', + quality: args.quality || 1, + success: resolve, + fail: reject + } + + if (use2dCanvas) { + delete copyArgs.canvasId + copyArgs.canvas = this.canvas + } + wx.canvasToTempFilePath(copyArgs, this) + }) + } + } +}) + + +/***/ }), +/* 2 */ +/***/ (function(module, exports) { + + +/** + * Module dependencies. + */ + + +/** + * Expose `parse`. + */ + + +/** + * Parse the given string of `xml`. + * + * @param {String} xml + * @return {Object} + * @api public + */ + +function parse(xml) { + xml = xml.trim() + + // strip comments + xml = xml.replace(//g, '') + + return document() + + /** + * XML document. + */ + + function document() { + return { + declaration: declaration(), + root: tag() + } + } + + /** + * Declaration. + */ + + function declaration() { + const m = match(/^<\?xml\s*/) + if (!m) return + + // tag + const node = { + attributes: {} + } + + // attributes + while (!(eos() || is('?>'))) { + const attr = attribute() + if (!attr) return node + node.attributes[attr.name] = attr.value + } + + match(/\?>\s*/) + + return node + } + + /** + * Tag. + */ + + function tag() { + const m = match(/^<([\w-:.]+)\s*/) + if (!m) return + + // name + const node = { + name: m[1], + attributes: {}, + children: [] + } + + // attributes + while (!(eos() || is('>') || is('?>') || is('/>'))) { + const attr = attribute() + if (!attr) return node + node.attributes[attr.name] = attr.value + } + + // self closing tag + if (match(/^\s*\/>\s*/)) { + return node + } + + match(/\??>\s*/) + + // content + node.content = content() + + // children + let child + while (child = tag()) { + node.children.push(child) + } + + // closing + match(/^<\/[\w-:.]+>\s*/) + + return node + } + + /** + * Text content. + */ + + function content() { + const m = match(/^([^<]*)/) + if (m) return m[1] + return '' + } + + /** + * Attribute. + */ + + function attribute() { + const m = match(/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/) + if (!m) return + return {name: m[1], value: strip(m[2])} + } + + /** + * Strip quotes from `val`. + */ + + function strip(val) { + return val.replace(/^['"]|['"]$/g, '') + } + + /** + * Match `re` and advance the string. + */ + + function match(re) { + const m = xml.match(re) + if (!m) return + xml = xml.slice(m[0].length) + return m + } + + /** + * End-of-source. + */ + + function eos() { + return xml.length == 0 + } + + /** + * Check for `prefix`. + */ + + function is(prefix) { + return xml.indexOf(prefix) == 0 + } +} + +module.exports = parse + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +const Block = __webpack_require__(4) +const {splitLineToCamelCase} = __webpack_require__(0) + +class Element extends Block { + constructor(prop) { + super(prop.style) + this.name = prop.name + this.attributes = prop.attributes + } +} + + +class Widget { + constructor(xom, style) { + this.xom = xom + this.style = style + + this.inheritProps = ['fontSize', 'lineHeight', 'textAlign', 'verticalAlign', 'color'] + } + + init() { + this.container = this.create(this.xom) + this.container.layout() + + this.inheritStyle(this.container) + return this.container + } + + // 继承父节点的样式 + inheritStyle(node) { + const parent = node.parent || null + const children = node.children || {} + const computedStyle = node.computedStyle + + if (parent) { + this.inheritProps.forEach(prop => { + computedStyle[prop] = computedStyle[prop] || parent.computedStyle[prop] + }) + } + + Object.values(children).forEach(child => { + this.inheritStyle(child) + }) + } + + create(node) { + let classNames = (node.attributes.class || '').split(' ') + classNames = classNames.map(item => splitLineToCamelCase(item.trim())) + const style = {} + classNames.forEach(item => { + Object.assign(style, this.style[item] || {}) + }) + + const args = {name: node.name, style} + + const attrs = Object.keys(node.attributes) + const attributes = {} + for (const attr of attrs) { + const value = node.attributes[attr] + const CamelAttr = splitLineToCamelCase(attr) + + if (value === '' || value === 'true') { + attributes[CamelAttr] = true + } else if (value === 'false') { + attributes[CamelAttr] = false + } else { + attributes[CamelAttr] = value + } + } + attributes.text = node.content + args.attributes = attributes + const element = new Element(args) + node.children.forEach(childNode => { + const childElement = this.create(childNode) + element.add(childElement) + }) + return element + } +} + +module.exports = {Widget} + + +/***/ }), +/* 4 */ +/***/ (function(module, exports) { + +module.exports = require("widget-ui"); + +/***/ }), +/* 5 */ +/***/ (function(module, exports) { + +class Draw { + constructor(context, canvas, use2dCanvas = false) { + this.ctx = context + this.canvas = canvas || null + this.use2dCanvas = use2dCanvas + } + + roundRect(x, y, w, h, r, fill = true, stroke = false) { + if (r < 0) return + const ctx = this.ctx + + ctx.beginPath() + ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 3 / 2) + ctx.arc(x + w - r, y + r, r, Math.PI * 3 / 2, 0) + ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2) + ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI) + ctx.lineTo(x, y + r) + if (stroke) ctx.stroke() + if (fill) ctx.fill() + } + + drawView(box, style) { + const ctx = this.ctx + const { + left: x, top: y, width: w, height: h + } = box + const { + borderRadius = 0, + borderWidth = 0, + borderColor, + color = '#000', + backgroundColor = 'transparent', + } = style + ctx.save() + // 外环 + if (borderWidth > 0) { + ctx.fillStyle = borderColor || color + this.roundRect(x, y, w, h, borderRadius) + } + + // 内环 + ctx.fillStyle = backgroundColor + const innerWidth = w - 2 * borderWidth + const innerHeight = h - 2 * borderWidth + const innerRadius = borderRadius - borderWidth >= 0 ? borderRadius - borderWidth : 0 + this.roundRect(x + borderWidth, y + borderWidth, innerWidth, innerHeight, innerRadius) + ctx.restore() + } + + async drawImage(img, box, style) { + await new Promise((resolve, reject) => { + const ctx = this.ctx + const canvas = this.canvas + + const { + borderRadius = 0 + } = style + const { + left: x, top: y, width: w, height: h + } = box + ctx.save() + this.roundRect(x, y, w, h, borderRadius, false, false) + ctx.clip() + + const _drawImage = (img) => { + if (this.use2dCanvas) { + const Image = canvas.createImage() + Image.onload = () => { + ctx.drawImage(Image, x, y, w, h) + ctx.restore() + resolve() + } + Image.onerror = () => { reject(new Error(`createImage fail: ${img}`)) } + Image.src = img + } else { + ctx.drawImage(img, x, y, w, h) + ctx.restore() + resolve() + } + } + + const isTempFile = /^wxfile:\/\//.test(img) + const isNetworkFile = /^https?:\/\//.test(img) + + if (isTempFile) { + _drawImage(img) + } else if (isNetworkFile) { + wx.downloadFile({ + url: img, + success(res) { + if (res.statusCode === 200) { + _drawImage(res.tempFilePath) + } else { + reject(new Error(`downloadFile:fail ${img}`)) + } + }, + fail() { + reject(new Error(`downloadFile:fail ${img}`)) + } + }) + } else { + reject(new Error(`image format error: ${img}`)) + } + }) + } + + // eslint-disable-next-line complexity + drawText(text, box, style) { + const ctx = this.ctx + let { + left: x, top: y, width: w, height: h + } = box + let { + color = '#000', + lineHeight = '1.4em', + fontSize = 14, + textAlign = 'left', + verticalAlign = 'top', + backgroundColor = 'transparent' + } = style + + if (typeof lineHeight === 'string') { // 2em + lineHeight = Math.ceil(parseFloat(lineHeight.replace('em')) * fontSize) + } + if (!text || (lineHeight > h)) return + + ctx.save() + ctx.textBaseline = 'top' + ctx.font = `${fontSize}px sans-serif` + ctx.textAlign = textAlign + + // 背景色 + ctx.fillStyle = backgroundColor + this.roundRect(x, y, w, h, 0) + + // 文字颜色 + ctx.fillStyle = color + + // 水平布局 + switch (textAlign) { + case 'left': + break + case 'center': + x += 0.5 * w + break + case 'right': + x += w + break + default: break + } + + const textWidth = ctx.measureText(text).width + const actualHeight = Math.ceil(textWidth / w) * lineHeight + let paddingTop = Math.ceil((h - actualHeight) / 2) + if (paddingTop < 0) paddingTop = 0 + + // 垂直布局 + switch (verticalAlign) { + case 'top': + break + case 'middle': + y += paddingTop + break + case 'bottom': + y += 2 * paddingTop + break + default: break + } + + const inlinePaddingTop = Math.ceil((lineHeight - fontSize) / 2) + + // 不超过一行 + if (textWidth <= w) { + ctx.fillText(text, x, y + inlinePaddingTop) + return + } + + // 多行文本 + const chars = text.split('') + const _y = y + + // 逐行绘制 + let line = '' + for (const ch of chars) { + const testLine = line + ch + const testWidth = ctx.measureText(testLine).width + + if (testWidth > w) { + ctx.fillText(line, x, y + inlinePaddingTop) + y += lineHeight + line = ch + if ((y + lineHeight) > (_y + h)) break + } else { + line = testLine + } + } + + // 避免溢出 + if ((y + lineHeight) <= (_y + h)) { + ctx.fillText(line, x, y + inlinePaddingTop) + } + ctx.restore() + } + + async drawNode(element) { + const {layoutBox, computedStyle, name} = element + const {src, text} = element.attributes + if (name === 'view') { + this.drawView(layoutBox, computedStyle) + } else if (name === 'image') { + await this.drawImage(src, layoutBox, computedStyle) + } else if (name === 'text') { + this.drawText(text, layoutBox, computedStyle) + } + const childs = Object.values(element.children) + for (const child of childs) { + await this.drawNode(child) + } + } +} + + +module.exports = { + Draw +} + + +/***/ }) +/******/ ]); +}); \ No newline at end of file diff --git a/miniprogram_npm/wxml-to-canvas/index.json b/miniprogram_npm/wxml-to-canvas/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/miniprogram_npm/wxml-to-canvas/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/miniprogram_npm/wxml-to-canvas/index.wxml b/miniprogram_npm/wxml-to-canvas/index.wxml new file mode 100644 index 0000000..a0010ad --- /dev/null +++ b/miniprogram_npm/wxml-to-canvas/index.wxml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/miniprogram_npm/wxml-to-canvas/index.wxss b/miniprogram_npm/wxml-to-canvas/index.wxss new file mode 100644 index 0000000..e69de29 diff --git a/miniprogram_npm/wxml-to-canvas/utils.js b/miniprogram_npm/wxml-to-canvas/utils.js new file mode 100644 index 0000000..c3cf7d7 --- /dev/null +++ b/miniprogram_npm/wxml-to-canvas/utils.js @@ -0,0 +1,57 @@ +const hex = (color) => { + let result = null + + if (/^#/.test(color) && (color.length === 7 || color.length === 9)) { + return color + // eslint-disable-next-line no-cond-assign + } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) { + return '#' + result[2].split(',').map((part, index) => { + part = part.trim() + part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10) + part = part.toString(16) + if (part.length === 1) { + part = '0' + part + } + return part + }).join('') + } else { + return '#00000000' + } +} + +const splitLineToCamelCase = (str) => str.split('-').map((part, index) => { + if (index === 0) { + return part + } + return part[0].toUpperCase() + part.slice(1) +}).join('') + +const compareVersion = (v1, v2) => { + v1 = v1.split('.') + v2 = v2.split('.') + const len = Math.max(v1.length, v2.length) + while (v1.length < len) { + v1.push('0') + } + while (v2.length < len) { + v2.push('0') + } + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i], 10) + const num2 = parseInt(v2[i], 10) + + if (num1 > num2) { + return 1 + } else if (num1 < num2) { + return -1 + } + } + + return 0 +} + +module.exports = { + hex, + splitLineToCamelCase, + compareVersion +} diff --git a/node_modules/eventemitter3/LICENSE b/node_modules/eventemitter3/LICENSE new file mode 100644 index 0000000..abcbd54 --- /dev/null +++ b/node_modules/eventemitter3/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Arnout Kazemier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/eventemitter3/README.md b/node_modules/eventemitter3/README.md new file mode 100644 index 0000000..aba7e18 --- /dev/null +++ b/node_modules/eventemitter3/README.md @@ -0,0 +1,94 @@ +# EventEmitter3 + +[![Version npm](https://img.shields.io/npm/v/eventemitter3.svg?style=flat-square)](https://www.npmjs.com/package/eventemitter3)[![Build Status](https://img.shields.io/travis/primus/eventemitter3/master.svg?style=flat-square)](https://travis-ci.org/primus/eventemitter3)[![Dependencies](https://img.shields.io/david/primus/eventemitter3.svg?style=flat-square)](https://david-dm.org/primus/eventemitter3)[![Coverage Status](https://img.shields.io/coveralls/primus/eventemitter3/master.svg?style=flat-square)](https://coveralls.io/r/primus/eventemitter3?branch=master)[![IRC channel](https://img.shields.io/badge/IRC-irc.freenode.net%23primus-00a8ff.svg?style=flat-square)](https://webchat.freenode.net/?channels=primus) + +[![Sauce Test Status](https://saucelabs.com/browser-matrix/eventemitter3.svg)](https://saucelabs.com/u/eventemitter3) + +EventEmitter3 is a high performance EventEmitter. It has been micro-optimized +for various of code paths making this, one of, if not the fastest EventEmitter +available for Node.js and browsers. The module is API compatible with the +EventEmitter that ships by default with Node.js but there are some slight +differences: + +- Domain support has been removed. +- We do not `throw` an error when you emit an `error` event and nobody is + listening. +- The `newListener` and `removeListener` events have been removed as they + are useful only in some uncommon use-cases. +- The `setMaxListeners`, `getMaxListeners`, `prependListener` and + `prependOnceListener` methods are not available. +- Support for custom context for events so there is no need to use `fn.bind`. +- The `removeListener` method removes all matching listeners, not only the + first. + +It's a drop in replacement for existing EventEmitters, but just faster. Free +performance, who wouldn't want that? The EventEmitter is written in EcmaScript 3 +so it will work in the oldest browsers and node versions that you need to +support. + +## Installation + +```bash +$ npm install --save eventemitter3 +``` + +## CDN + +Recommended CDN: + +```text +https://unpkg.com/eventemitter3@latest/umd/eventemitter3.min.js +``` + +## Usage + +After installation the only thing you need to do is require the module: + +```js +var EventEmitter = require('eventemitter3'); +``` + +And you're ready to create your own EventEmitter instances. For the API +documentation, please follow the official Node.js documentation: + +http://nodejs.org/api/events.html + +### Contextual emits + +We've upgraded the API of the `EventEmitter.on`, `EventEmitter.once` and +`EventEmitter.removeListener` to accept an extra argument which is the `context` +or `this` value that should be set for the emitted events. This means you no +longer have the overhead of an event that required `fn.bind` in order to get a +custom `this` value. + +```js +var EE = new EventEmitter() + , context = { foo: 'bar' }; + +function emitted() { + console.log(this === context); // true +} + +EE.once('event-name', emitted, context); +EE.on('another-event', emitted, context); +EE.removeListener('another-event', emitted, context); +``` + +### Tests and benchmarks + +This module is well tested. You can run: + +- `npm test` to run the tests under Node.js. +- `npm run test-browser` to run the tests in real browsers via Sauce Labs. + +We also have a set of benchmarks to compare EventEmitter3 with some available +alternatives. To run the benchmarks run `npm run benchmark`. + +Tests and benchmarks are not included in the npm package. If you want to play +with them you have to clone the GitHub repository. +Note that you will have to run an additional `npm i` in the benchmarks folder +before `npm run benchmark`. + +## License + +[MIT](LICENSE) diff --git a/node_modules/eventemitter3/index.d.ts b/node_modules/eventemitter3/index.d.ts new file mode 100644 index 0000000..118f68b --- /dev/null +++ b/node_modules/eventemitter3/index.d.ts @@ -0,0 +1,134 @@ +/** + * Minimal `EventEmitter` interface that is molded against the Node.js + * `EventEmitter` interface. + */ +declare class EventEmitter< + EventTypes extends EventEmitter.ValidEventTypes = string | symbol, + Context extends any = any +> { + static prefixed: string | boolean; + + /** + * Return an array listing the events for which the emitter has registered + * listeners. + */ + eventNames(): Array>; + + /** + * Return the listeners registered for a given event. + */ + listeners>( + event: T + ): Array>; + + /** + * Return the number of listeners listening to a given event. + */ + listenerCount(event: EventEmitter.EventNames): number; + + /** + * Calls each of the listeners registered for a given event. + */ + emit>( + event: T, + ...args: EventEmitter.EventArgs + ): boolean; + + /** + * Add a listener for a given event. + */ + on>( + event: T, + fn: EventEmitter.EventListener, + context?: Context + ): this; + addListener>( + event: T, + fn: EventEmitter.EventListener, + context?: Context + ): this; + + /** + * Add a one-time listener for a given event. + */ + once>( + event: T, + fn: EventEmitter.EventListener, + context?: Context + ): this; + + /** + * Remove the listeners of a given event. + */ + removeListener>( + event: T, + fn?: EventEmitter.EventListener, + context?: Context, + once?: boolean + ): this; + off>( + event: T, + fn?: EventEmitter.EventListener, + context?: Context, + once?: boolean + ): this; + + /** + * Remove all listeners, or those of the specified event. + */ + removeAllListeners(event?: EventEmitter.EventNames): this; +} + +declare namespace EventEmitter { + export interface ListenerFn { + (...args: Args): void; + } + + export interface EventEmitterStatic { + new < + EventTypes extends ValidEventTypes = string | symbol, + Context = any + >(): EventEmitter; + } + + /** + * `object` should be in either of the following forms: + * ``` + * interface EventTypes { + * 'event-with-parameters': any[] + * 'event-with-example-handler': (...args: any[]) => void + * } + * ``` + */ + export type ValidEventTypes = string | symbol | object; + + export type EventNames = T extends string | symbol + ? T + : keyof T; + + export type ArgumentMap = { + [K in keyof T]: T[K] extends (...args: any[]) => void + ? Parameters + : T[K] extends any[] + ? T[K] + : any[]; + }; + + export type EventListener< + T extends ValidEventTypes, + K extends EventNames + > = T extends string | symbol + ? (...args: any[]) => void + : ( + ...args: ArgumentMap>[Extract] + ) => void; + + export type EventArgs< + T extends ValidEventTypes, + K extends EventNames + > = Parameters>; + + export const EventEmitter: EventEmitterStatic; +} + +export = EventEmitter; diff --git a/node_modules/eventemitter3/index.js b/node_modules/eventemitter3/index.js new file mode 100644 index 0000000..6ea485c --- /dev/null +++ b/node_modules/eventemitter3/index.js @@ -0,0 +1,336 @@ +'use strict'; + +var has = Object.prototype.hasOwnProperty + , prefix = '~'; + +/** + * Constructor to create a storage for our `EE` objects. + * An `Events` instance is a plain object whose properties are event names. + * + * @constructor + * @private + */ +function Events() {} + +// +// We try to not inherit from `Object.prototype`. In some engines creating an +// instance in this way is faster than calling `Object.create(null)` directly. +// If `Object.create(null)` is not supported we prefix the event names with a +// character to make sure that the built-in object properties are not +// overridden or used as an attack vector. +// +if (Object.create) { + Events.prototype = Object.create(null); + + // + // This hack is needed because the `__proto__` property is still inherited in + // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. + // + if (!new Events().__proto__) prefix = false; +} + +/** + * Representation of a single event listener. + * + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} [once=false] Specify if the listener is a one-time listener. + * @constructor + * @private + */ +function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; +} + +/** + * Add a listener for a given event. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} once Specify if the listener is a one-time listener. + * @returns {EventEmitter} + * @private + */ +function addListener(emitter, event, fn, context, once) { + if (typeof fn !== 'function') { + throw new TypeError('The listener must be a function'); + } + + var listener = new EE(fn, context || emitter, once) + , evt = prefix ? prefix + event : event; + + if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; + else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); + else emitter._events[evt] = [emitter._events[evt], listener]; + + return emitter; +} + +/** + * Clear event by name. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} evt The Event name. + * @private + */ +function clearEvent(emitter, evt) { + if (--emitter._eventsCount === 0) emitter._events = new Events(); + else delete emitter._events[evt]; +} + +/** + * Minimal `EventEmitter` interface that is molded against the Node.js + * `EventEmitter` interface. + * + * @constructor + * @public + */ +function EventEmitter() { + this._events = new Events(); + this._eventsCount = 0; +} + +/** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @public + */ +EventEmitter.prototype.eventNames = function eventNames() { + var names = [] + , events + , name; + + if (this._eventsCount === 0) return names; + + for (name in (events = this._events)) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; +}; + +/** + * Return the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Array} The registered listeners. + * @public + */ +EventEmitter.prototype.listeners = function listeners(event) { + var evt = prefix ? prefix + event : event + , handlers = this._events[evt]; + + if (!handlers) return []; + if (handlers.fn) return [handlers.fn]; + + for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { + ee[i] = handlers[i].fn; + } + + return ee; +}; + +/** + * Return the number of listeners listening to a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Number} The number of listeners. + * @public + */ +EventEmitter.prototype.listenerCount = function listenerCount(event) { + var evt = prefix ? prefix + event : event + , listeners = this._events[evt]; + + if (!listeners) return 0; + if (listeners.fn) return 1; + return listeners.length; +}; + +/** + * Calls each of the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Boolean} `true` if the event had listeners, else `false`. + * @public + */ +EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return false; + + var listeners = this._events[evt] + , len = arguments.length + , args + , i; + + if (listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); + + switch (len) { + case 1: return listeners.fn.call(listeners.context), true; + case 2: return listeners.fn.call(listeners.context, a1), true; + case 3: return listeners.fn.call(listeners.context, a1, a2), true; + case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; + } + + for (i = 1, args = new Array(len -1); i < len; i++) { + args[i - 1] = arguments[i]; + } + + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length + , j; + + for (i = 0; i < length; i++) { + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); + + switch (len) { + case 1: listeners[i].fn.call(listeners[i].context); break; + case 2: listeners[i].fn.call(listeners[i].context, a1); break; + case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; + case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; + default: + if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { + args[j - 1] = arguments[j]; + } + + listeners[i].fn.apply(listeners[i].context, args); + } + } + } + + return true; +}; + +/** + * Add a listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.on = function on(event, fn, context) { + return addListener(this, event, fn, context, false); +}; + +/** + * Add a one-time listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.once = function once(event, fn, context) { + return addListener(this, event, fn, context, true); +}; + +/** + * Remove the listeners of a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {Boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return this; + if (!fn) { + clearEvent(this, evt); + return this; + } + + var listeners = this._events[evt]; + + if (listeners.fn) { + if ( + listeners.fn === fn && + (!once || listeners.once) && + (!context || listeners.context === context) + ) { + clearEvent(this, evt); + } + } else { + for (var i = 0, events = [], length = listeners.length; i < length; i++) { + if ( + listeners[i].fn !== fn || + (once && !listeners[i].once) || + (context && listeners[i].context !== context) + ) { + events.push(listeners[i]); + } + } + + // + // Reset the array, or remove it completely if we have no more listeners. + // + if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; + else clearEvent(this, evt); + } + + return this; +}; + +/** + * Remove all listeners, or those of the specified event. + * + * @param {(String|Symbol)} [event] The event name. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { + var evt; + + if (event) { + evt = prefix ? prefix + event : event; + if (this._events[evt]) clearEvent(this, evt); + } else { + this._events = new Events(); + this._eventsCount = 0; + } + + return this; +}; + +// +// Alias methods names because people roll like that. +// +EventEmitter.prototype.off = EventEmitter.prototype.removeListener; +EventEmitter.prototype.addListener = EventEmitter.prototype.on; + +// +// Expose the prefix. +// +EventEmitter.prefixed = prefix; + +// +// Allow `EventEmitter` to be imported as module namespace. +// +EventEmitter.EventEmitter = EventEmitter; + +// +// Expose the module. +// +if ('undefined' !== typeof module) { + module.exports = EventEmitter; +} diff --git a/node_modules/eventemitter3/package.json b/node_modules/eventemitter3/package.json new file mode 100644 index 0000000..6f6e2fd --- /dev/null +++ b/node_modules/eventemitter3/package.json @@ -0,0 +1,84 @@ +{ + "_from": "eventemitter3@^4.0.0", + "_id": "eventemitter3@4.0.7", + "_inBundle": false, + "_integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "_location": "/eventemitter3", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "eventemitter3@^4.0.0", + "name": "eventemitter3", + "escapedName": "eventemitter3", + "rawSpec": "^4.0.0", + "saveSpec": null, + "fetchSpec": "^4.0.0" + }, + "_requiredBy": [ + "/widget-ui" + ], + "_resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "_shasum": "2de9b68f6528d5644ef5c59526a1b4a07306169f", + "_spec": "eventemitter3@^4.0.0", + "_where": "/Users/WebTmm/Desktop/AGuestSaas/node_modules/widget-ui", + "author": { + "name": "Arnout Kazemier" + }, + "bugs": { + "url": "https://github.com/primus/eventemitter3/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "EventEmitter3 focuses on performance while maintaining a Node.js AND browser compatible interface.", + "devDependencies": { + "assume": "^2.2.0", + "browserify": "^16.5.0", + "mocha": "^8.0.1", + "nyc": "^15.1.0", + "pre-commit": "^1.2.0", + "sauce-browsers": "^2.0.0", + "sauce-test": "^1.3.3", + "uglify-js": "^3.9.0" + }, + "files": [ + "index.js", + "index.d.ts", + "umd" + ], + "homepage": "https://github.com/primus/eventemitter3#readme", + "keywords": [ + "EventEmitter", + "EventEmitter2", + "EventEmitter3", + "Events", + "addEventListener", + "addListener", + "emit", + "emits", + "emitter", + "event", + "once", + "pub/sub", + "publish", + "reactor", + "subscribe" + ], + "license": "MIT", + "main": "index.js", + "name": "eventemitter3", + "repository": { + "type": "git", + "url": "git://github.com/primus/eventemitter3.git" + }, + "scripts": { + "benchmark": "find benchmarks/run -name '*.js' -exec benchmarks/start.sh {} \\;", + "browserify": "rm -rf umd && mkdir umd && browserify index.js -s EventEmitter3 -o umd/eventemitter3.js", + "minify": "uglifyjs umd/eventemitter3.js --source-map -cm -o umd/eventemitter3.min.js", + "prepublishOnly": "npm run browserify && npm run minify", + "test": "nyc --reporter=html --reporter=text mocha test/test.js", + "test-browser": "node test/browser.js" + }, + "typings": "index.d.ts", + "version": "4.0.7" +} diff --git a/node_modules/eventemitter3/umd/eventemitter3.js b/node_modules/eventemitter3/umd/eventemitter3.js new file mode 100644 index 0000000..888fcb8 --- /dev/null +++ b/node_modules/eventemitter3/umd/eventemitter3.js @@ -0,0 +1,340 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.EventEmitter3 = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i=0&&L(e))return t.style.borderStartWidth;var o=null;switch(e){case"row":o=t.style.borderLeftWidth;break;case"row-reverse":o=t.style.borderRightWidth;break;case"column":o=t.style.borderTopWidth;break;case"column-reverse":o=t.style.borderBottomWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function E(t,e){if(void 0!==t.style.borderEndWidth&&t.style.borderEndWidth>=0&&L(e))return t.style.borderEndWidth;var o=null;switch(e){case"row":o=t.style.borderRightWidth;break;case"row-reverse":o=t.style.borderLeftWidth;break;case"column":o=t.style.borderBottomWidth;break;case"column-reverse":o=t.style.borderTopWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function C(t,e){return function(t,e){if(void 0!==t.style.paddingStart&&t.style.paddingStart>=0&&L(e))return t.style.paddingStart;var o=null;switch(e){case"row":o=t.style.paddingLeft;break;case"row-reverse":o=t.style.paddingRight;break;case"column":o=t.style.paddingTop;break;case"column-reverse":o=t.style.paddingBottom}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+B(t,e)}function T(t,e){return function(t,e){if(void 0!==t.style.paddingEnd&&t.style.paddingEnd>=0&&L(e))return t.style.paddingEnd;var o=null;switch(e){case"row":o=t.style.paddingRight;break;case"row-reverse":o=t.style.paddingLeft;break;case"column":o=t.style.paddingBottom;break;case"column-reverse":o=t.style.paddingTop}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+E(t,e)}function O(t,e){return B(t,e)+E(t,e)}function _(t,e){return k(t,e)+j(t,e)}function R(t,e){return C(t,e)+T(t,e)}function A(t,e){return e.style.alignSelf?e.style.alignSelf:t.style.alignItems?t.style.alignItems:"stretch"}function P(t,e){if(e===r){if(t===i)return l;if(t===l)return i}return t}function D(t,e){return function(t){return t===n||t===a}(t)?P(i,e):n}function H(t){return t.style.position?t.style.position:"relative"}function M(t){return H(t)===v&&t.style.flex>0}function I(t,e){return t.layout[S[e]]+_(t,e)}function N(t,e){return void 0!==t.style[S[e]]&&t.style[S[e]]>=0}function F(t,e){return void 0!==t.style[e]}function q(t,e){return void 0!==t.style[e]?t.style[e]:0}function z(t,e,o){var r={row:t.style.minWidth,"row-reverse":t.style.minWidth,column:t.style.minHeight,"column-reverse":t.style.minHeight}[e],i={row:t.style.maxWidth,"row-reverse":t.style.maxWidth,column:t.style.maxHeight,"column-reverse":t.style.maxHeight}[e],l=o;return void 0!==i&&i>=0&&l>i&&(l=i),void 0!==r&&r>=0&&le?t:e}function G(t,e){void 0===t.layout[S[e]]&&N(t,e)&&(t.layout[S[e]]=U(z(t,e,t.style[S[e]]),R(t,e)))}function J(t,e,o){e.layout[x[o]]=t.layout[S[o]]-e.layout[S[o]]-e.layout[w[o]]}function K(t,e){return void 0!==t.style[b[e]]?q(t,b[e]):-q(t,x[e])}function Q(r,E,Q){var X=function(t,r){var i;return(i=t.style.direction?t.style.direction:e)===e&&(i=void 0===r?o:r),i}(r,Q),Y=P(function(t){return t.style.flexDirection?t.style.flexDirection:n}(r),X),Z=D(Y,X),$=P(i,X);G(r,Y),G(r,Z),r.layout.direction=X,r.layout[b[Y]]+=k(r,Y)+K(r,Y),r.layout[x[Y]]+=j(r,Y)+K(r,Y),r.layout[b[Z]]+=k(r,Z)+K(r,Z),r.layout[x[Z]]+=j(r,Z)+K(r,Z);var tt=r.children.length,et=R(r,$);if(function(t){return void 0!==t.style.measure}(r)){var ot=!W(r.layout[S[$]]),rt=t;rt=N(r,$)?r.style.width:ot?r.layout[S[$]]:E-_(r,$),rt-=et;var it=!N(r,$)&&!ot,lt=!N(r,n)&&W(r.layout[S[n]]);if(it||lt){var nt=r.style.measure(rt);it&&(r.layout.width=nt.width+et),lt&&(r.layout.height=nt.height+R(r,n))}if(0===tt)return}var at,ut,dt,st,yt=function(t){return"wrap"===t.style.flexWrap}(r),ct=function(t){return t.style.justifyContent?t.style.justifyContent:"flex-start"}(r),ft=C(r,Y),ht=C(r,Z),pt=R(r,Y),gt=R(r,Z),vt=!W(r.layout[S[Y]]),mt=!W(r.layout[S[Z]]),bt=L(Y),xt=null,wt=null,St=t;vt&&(St=r.layout[S[Y]]-pt);for(var Wt=0,Lt=0,kt=0,jt=0,Bt=0,Et=0;LtSt&&at!==Wt){Rt--,kt=1;break}At&&(H(dt)!==v||M(dt))&&(At=!1,Pt=at),Dt&&(H(dt)!==v||Xt!==g&&Xt!==f||W(dt.layout[S[Z]]))&&(Dt=!1,Ht=at),At&&(dt.layout[w[Y]]+=Nt,vt&&J(r,dt,Y),Nt+=I(dt,Y),Ft=U(Ft,z(dt,Z,I(dt,Z)))),Dt&&(dt.layout[w[Z]]+=jt+ht,mt&&J(r,dt,Z)),kt=0,Tt+=qt,Lt=at+1}var zt=0,Ut=0,Gt=0;if(Gt=vt?St-Tt:U(Tt,0)-Tt,0!==Ot){var Jt,Kt,Qt=Gt/_t;for(It=Mt;null!==It;)(Jt=Qt*It.style.flex+R(It,Y))!==(Kt=z(It,Y,Jt))&&(Gt-=Kt,_t-=It.style.flex),It=It.nextFlexChild;for((Qt=Gt/_t)<0&&(Qt=0),It=Mt;null!==It;)It.layout[S[Y]]=z(It,Y,Qt*It.style.flex+R(It,Y)),Ct=t,N(r,$)?Ct=r.layout[S[$]]-et:bt||(Ct=E-_(r,$)-et),V(It,Ct,X),dt=It,It=It.nextFlexChild,dt.nextFlexChild=null}else ct!==u&&(ct===d?zt=Gt/2:ct===s?zt=Gt:ct===y?(Gt=U(Gt,0),Ut=Ot+Rt-1!=0?Gt/(Ot+Rt-1):0):ct===c&&(zt=(Ut=Gt/(Ot+Rt))/2));for(Nt+=zt,at=Pt;at1&&mt){var $t=r.layout[S[Z]]-gt,te=$t-jt,ee=0,oe=ht,re=function(t){return t.style.alignContent?t.style.alignContent:"flex-start"}(r);re===p?oe+=te:re===h?oe+=te/2:re===g&&$t>jt&&(ee=te/Et);var ie=0;for(at=0;at { + left: undefined; + top: undefined; + right: undefined; + bottom: undefined; + width: undefined; + height: undefined; + maxWidth: undefined; + maxHeight: undefined; + minWidth: undefined; + minHeight: undefined; + margin: undefined; + marginLeft: undefined; + marginRight: undefined; + marginTop: undefined; + marginBottom: undefined; + padding: undefined; + paddingLeft: undefined; + paddingRight: undefined; + paddingTop: undefined; + paddingBottom: undefined; + borderWidth: undefined; + flexDirection: undefined; + justifyContent: undefined; + alignItems: undefined; + alignSelf: undefined; + flex: undefined; + flexWrap: undefined; + position: undefined; + hidden: boolean; + scale: number; +}; +export { getDefaultStyle, scalableStyles, textStyles, layoutAffectedStyles }; diff --git a/node_modules/widget-ui/jest.config.js b/node_modules/widget-ui/jest.config.js new file mode 100644 index 0000000..837466b --- /dev/null +++ b/node_modules/widget-ui/jest.config.js @@ -0,0 +1,6 @@ +module.exports = { + transform: { + "^.+\\.js$": "babel-jest", + "^.+\\.ts$": "ts-jest" + } +}; \ No newline at end of file diff --git a/node_modules/widget-ui/package.json b/node_modules/widget-ui/package.json new file mode 100644 index 0000000..c336a07 --- /dev/null +++ b/node_modules/widget-ui/package.json @@ -0,0 +1,52 @@ +{ + "_from": "widget-ui@^1.0.2", + "_id": "widget-ui@1.0.2", + "_inBundle": false, + "_integrity": "sha512-gDXosr5mflJdMA1weU1A47aTsTFfMJhfA4EKgO5XFebY3eVklf80KD4GODfrjo8J2WQ+9YjL1Rd9UUmKIzhShw==", + "_location": "/widget-ui", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "widget-ui@^1.0.2", + "name": "widget-ui", + "escapedName": "widget-ui", + "rawSpec": "^1.0.2", + "saveSpec": null, + "fetchSpec": "^1.0.2" + }, + "_requiredBy": [ + "/wxml-to-canvas" + ], + "_resolved": "https://registry.npmjs.org/widget-ui/-/widget-ui-1.0.2.tgz", + "_shasum": "d65a560b91739fbd0ea7c2f5f2d28fe4c0132470", + "_spec": "widget-ui@^1.0.2", + "_where": "/Users/WebTmm/Desktop/AGuestSaas/node_modules/wxml-to-canvas", + "author": "", + "bundleDependencies": false, + "dependencies": { + "eventemitter3": "^4.0.0" + }, + "deprecated": false, + "description": "", + "devDependencies": { + "@babel/preset-env": "^7.6.3", + "@babel/preset-typescript": "^7.6.0", + "@types/jest": "^24.0.18", + "babel-jest": "^24.9.0", + "jest": "^24.9.0", + "ts-jest": "^24.1.0", + "ts-loader": "^6.2.0", + "typescript": "^3.6.4", + "webpack": "^4.41.1", + "webpack-cli": "^3.3.9" + }, + "license": "ISC", + "main": "dist/index.js", + "name": "widget-ui", + "scripts": { + "build": "webpack", + "test": "jest" + }, + "version": "1.0.2" +} diff --git a/node_modules/widget-ui/src/css-layout.js b/node_modules/widget-ui/src/css-layout.js new file mode 100644 index 0000000..790c753 --- /dev/null +++ b/node_modules/widget-ui/src/css-layout.js @@ -0,0 +1,1186 @@ +/* eslint-disable */ +// https://www.npmjs.com/package/css-layout +// change: module export strategy. Use ES6 Module + +/** + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +var computeLayout = (function() { + + var CSS_UNDEFINED; + + var CSS_DIRECTION_INHERIT = 'inherit'; + var CSS_DIRECTION_LTR = 'ltr'; + var CSS_DIRECTION_RTL = 'rtl'; + + var CSS_FLEX_DIRECTION_ROW = 'row'; + var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse'; + var CSS_FLEX_DIRECTION_COLUMN = 'column'; + var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse'; + + var CSS_JUSTIFY_FLEX_START = 'flex-start'; + var CSS_JUSTIFY_CENTER = 'center'; + var CSS_JUSTIFY_FLEX_END = 'flex-end'; + var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between'; + var CSS_JUSTIFY_SPACE_AROUND = 'space-around'; + + var CSS_ALIGN_FLEX_START = 'flex-start'; + var CSS_ALIGN_CENTER = 'center'; + var CSS_ALIGN_FLEX_END = 'flex-end'; + var CSS_ALIGN_STRETCH = 'stretch'; + + var CSS_POSITION_RELATIVE = 'relative'; + var CSS_POSITION_ABSOLUTE = 'absolute'; + + var leading = { + 'row': 'left', + 'row-reverse': 'right', + 'column': 'top', + 'column-reverse': 'bottom' + }; + var trailing = { + 'row': 'right', + 'row-reverse': 'left', + 'column': 'bottom', + 'column-reverse': 'top' + }; + var pos = { + 'row': 'left', + 'row-reverse': 'right', + 'column': 'top', + 'column-reverse': 'bottom' + }; + var dim = { + 'row': 'width', + 'row-reverse': 'width', + 'column': 'height', + 'column-reverse': 'height' + }; + + // When transpiled to Java / C the node type has layout, children and style + // properties. For the JavaScript version this function adds these properties + // if they don't already exist. + function fillNodes(node) { + if (!node.layout || node.isDirty) { + node.layout = { + width: undefined, + height: undefined, + top: 0, + left: 0, + right: 0, + bottom: 0 + }; + } + + if (!node.style) { + node.style = {}; + } + + if (!node.children) { + node.children = []; + } + node.children.forEach(fillNodes); + return node; + } + + function isUndefined(value) { + return value === undefined; + } + + function isRowDirection(flexDirection) { + return flexDirection === CSS_FLEX_DIRECTION_ROW || + flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE; + } + + function isColumnDirection(flexDirection) { + return flexDirection === CSS_FLEX_DIRECTION_COLUMN || + flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE; + } + + function getLeadingMargin(node, axis) { + if (node.style.marginStart !== undefined && isRowDirection(axis)) { + return node.style.marginStart; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.marginLeft; break; + case 'row-reverse': value = node.style.marginRight; break; + case 'column': value = node.style.marginTop; break; + case 'column-reverse': value = node.style.marginBottom; break; + } + + if (value !== undefined) { + return value; + } + + if (node.style.margin !== undefined) { + return node.style.margin; + } + + return 0; + } + + function getTrailingMargin(node, axis) { + if (node.style.marginEnd !== undefined && isRowDirection(axis)) { + return node.style.marginEnd; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.marginRight; break; + case 'row-reverse': value = node.style.marginLeft; break; + case 'column': value = node.style.marginBottom; break; + case 'column-reverse': value = node.style.marginTop; break; + } + + if (value != null) { + return value; + } + + if (node.style.margin !== undefined) { + return node.style.margin; + } + + return 0; + } + + function getLeadingPadding(node, axis) { + if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0 + && isRowDirection(axis)) { + return node.style.paddingStart; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.paddingLeft; break; + case 'row-reverse': value = node.style.paddingRight; break; + case 'column': value = node.style.paddingTop; break; + case 'column-reverse': value = node.style.paddingBottom; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.padding !== undefined && node.style.padding >= 0) { + return node.style.padding; + } + + return 0; + } + + function getTrailingPadding(node, axis) { + if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0 + && isRowDirection(axis)) { + return node.style.paddingEnd; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.paddingRight; break; + case 'row-reverse': value = node.style.paddingLeft; break; + case 'column': value = node.style.paddingBottom; break; + case 'column-reverse': value = node.style.paddingTop; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.padding !== undefined && node.style.padding >= 0) { + return node.style.padding; + } + + return 0; + } + + function getLeadingBorder(node, axis) { + if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0 + && isRowDirection(axis)) { + return node.style.borderStartWidth; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.borderLeftWidth; break; + case 'row-reverse': value = node.style.borderRightWidth; break; + case 'column': value = node.style.borderTopWidth; break; + case 'column-reverse': value = node.style.borderBottomWidth; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) { + return node.style.borderWidth; + } + + return 0; + } + + function getTrailingBorder(node, axis) { + if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0 + && isRowDirection(axis)) { + return node.style.borderEndWidth; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.borderRightWidth; break; + case 'row-reverse': value = node.style.borderLeftWidth; break; + case 'column': value = node.style.borderBottomWidth; break; + case 'column-reverse': value = node.style.borderTopWidth; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) { + return node.style.borderWidth; + } + + return 0; + } + + function getLeadingPaddingAndBorder(node, axis) { + return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); + } + + function getTrailingPaddingAndBorder(node, axis) { + return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); + } + + function getBorderAxis(node, axis) { + return getLeadingBorder(node, axis) + getTrailingBorder(node, axis); + } + + function getMarginAxis(node, axis) { + return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); + } + + function getPaddingAndBorderAxis(node, axis) { + return getLeadingPaddingAndBorder(node, axis) + + getTrailingPaddingAndBorder(node, axis); + } + + function getJustifyContent(node) { + if (node.style.justifyContent) { + return node.style.justifyContent; + } + return 'flex-start'; + } + + function getAlignContent(node) { + if (node.style.alignContent) { + return node.style.alignContent; + } + return 'flex-start'; + } + + function getAlignItem(node, child) { + if (child.style.alignSelf) { + return child.style.alignSelf; + } + if (node.style.alignItems) { + return node.style.alignItems; + } + return 'stretch'; + } + + function resolveAxis(axis, direction) { + if (direction === CSS_DIRECTION_RTL) { + if (axis === CSS_FLEX_DIRECTION_ROW) { + return CSS_FLEX_DIRECTION_ROW_REVERSE; + } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) { + return CSS_FLEX_DIRECTION_ROW; + } + } + + return axis; + } + + function resolveDirection(node, parentDirection) { + var direction; + if (node.style.direction) { + direction = node.style.direction; + } else { + direction = CSS_DIRECTION_INHERIT; + } + + if (direction === CSS_DIRECTION_INHERIT) { + direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection); + } + + return direction; + } + + function getFlexDirection(node) { + if (node.style.flexDirection) { + return node.style.flexDirection; + } + return CSS_FLEX_DIRECTION_COLUMN; + } + + function getCrossFlexDirection(flexDirection, direction) { + if (isColumnDirection(flexDirection)) { + return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); + } else { + return CSS_FLEX_DIRECTION_COLUMN; + } + } + + function getPositionType(node) { + if (node.style.position) { + return node.style.position; + } + return 'relative'; + } + + function isFlex(node) { + return ( + getPositionType(node) === CSS_POSITION_RELATIVE && + node.style.flex > 0 + ); + } + + function isFlexWrap(node) { + return node.style.flexWrap === 'wrap'; + } + + function getDimWithMargin(node, axis) { + return node.layout[dim[axis]] + getMarginAxis(node, axis); + } + + function isDimDefined(node, axis) { + return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0; + } + + function isPosDefined(node, pos) { + return node.style[pos] !== undefined; + } + + function isMeasureDefined(node) { + return node.style.measure !== undefined; + } + + function getPosition(node, pos) { + if (node.style[pos] !== undefined) { + return node.style[pos]; + } + return 0; + } + + function boundAxis(node, axis, value) { + var min = { + 'row': node.style.minWidth, + 'row-reverse': node.style.minWidth, + 'column': node.style.minHeight, + 'column-reverse': node.style.minHeight + }[axis]; + + var max = { + 'row': node.style.maxWidth, + 'row-reverse': node.style.maxWidth, + 'column': node.style.maxHeight, + 'column-reverse': node.style.maxHeight + }[axis]; + + var boundValue = value; + if (max !== undefined && max >= 0 && boundValue > max) { + boundValue = max; + } + if (min !== undefined && min >= 0 && boundValue < min) { + boundValue = min; + } + return boundValue; + } + + function fmaxf(a, b) { + if (a > b) { + return a; + } + return b; + } + + // When the user specifically sets a value for width or height + function setDimensionFromStyle(node, axis) { + // The parent already computed us a width or height. We just skip it + if (node.layout[dim[axis]] !== undefined) { + return; + } + // We only run if there's a width or height defined + if (!isDimDefined(node, axis)) { + return; + } + + // The dimensions can never be smaller than the padding and border + node.layout[dim[axis]] = fmaxf( + boundAxis(node, axis, node.style[dim[axis]]), + getPaddingAndBorderAxis(node, axis) + ); + } + + function setTrailingPosition(node, child, axis) { + child.layout[trailing[axis]] = node.layout[dim[axis]] - + child.layout[dim[axis]] - child.layout[pos[axis]]; + } + + // If both left and right are defined, then use left. Otherwise return + // +left or -right depending on which is defined. + function getRelativePosition(node, axis) { + if (node.style[leading[axis]] !== undefined) { + return getPosition(node, leading[axis]); + } + return -getPosition(node, trailing[axis]); + } + + function layoutNodeImpl(node, parentMaxWidth, /*css_direction_t*/parentDirection) { + var/*css_direction_t*/ direction = resolveDirection(node, parentDirection); + var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction); + var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction); + var/*(c)!css_flex_direction_t*//*(java)!int*/ resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); + + // Handle width and height style attributes + setDimensionFromStyle(node, mainAxis); + setDimensionFromStyle(node, crossAxis); + + // Set the resolved resolution in the node's layout + node.layout.direction = direction; + + // The position is set by the parent, but we need to complete it with a + // delta composed of the margin and left/top/right/bottom + node.layout[leading[mainAxis]] += getLeadingMargin(node, mainAxis) + + getRelativePosition(node, mainAxis); + node.layout[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + + getRelativePosition(node, mainAxis); + node.layout[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + + getRelativePosition(node, crossAxis); + node.layout[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + + getRelativePosition(node, crossAxis); + + // Inline immutable values from the target node to avoid excessive method + // invocations during the layout calculation. + var/*int*/ childCount = node.children.length; + var/*float*/ paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); + + if (isMeasureDefined(node)) { + var/*bool*/ isResolvedRowDimDefined = !isUndefined(node.layout[dim[resolvedRowAxis]]); + + var/*float*/ width = CSS_UNDEFINED; + if (isDimDefined(node, resolvedRowAxis)) { + width = node.style.width; + } else if (isResolvedRowDimDefined) { + width = node.layout[dim[resolvedRowAxis]]; + } else { + width = parentMaxWidth - + getMarginAxis(node, resolvedRowAxis); + } + width -= paddingAndBorderAxisResolvedRow; + + // We only need to give a dimension for the text if we haven't got any + // for it computed yet. It can either be from the style attribute or because + // the element is flexible. + var/*bool*/ isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined; + var/*bool*/ isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && + isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]); + + // Let's not measure the text if we already know both dimensions + if (isRowUndefined || isColumnUndefined) { + var/*css_dim_t*/ measureDim = node.style.measure( + /*(c)!node->context,*/ + /*(java)!layoutContext.measureOutput,*/ + width + ); + if (isRowUndefined) { + node.layout.width = measureDim.width + + paddingAndBorderAxisResolvedRow; + } + if (isColumnUndefined) { + node.layout.height = measureDim.height + + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + } + } + if (childCount === 0) { + return; + } + } + + var/*bool*/ isNodeFlexWrap = isFlexWrap(node); + + var/*css_justify_t*/ justifyContent = getJustifyContent(node); + + var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); + var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); + var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); + var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); + + var/*bool*/ isMainDimDefined = !isUndefined(node.layout[dim[mainAxis]]); + var/*bool*/ isCrossDimDefined = !isUndefined(node.layout[dim[crossAxis]]); + var/*bool*/ isMainRowDirection = isRowDirection(mainAxis); + + var/*int*/ i; + var/*int*/ ii; + var/*css_node_t**/ child; + var/*(c)!css_flex_direction_t*//*(java)!int*/ axis; + + var/*css_node_t**/ firstAbsoluteChild = null; + var/*css_node_t**/ currentAbsoluteChild = null; + + var/*float*/ definedMainDim = CSS_UNDEFINED; + if (isMainDimDefined) { + definedMainDim = node.layout[dim[mainAxis]] - paddingAndBorderAxisMain; + } + + // We want to execute the next two loops one per line with flex-wrap + var/*int*/ startLine = 0; + var/*int*/ endLine = 0; + // var/*int*/ nextOffset = 0; + var/*int*/ alreadyComputedNextLayout = 0; + // We aggregate the total dimensions of the container in those two variables + var/*float*/ linesCrossDim = 0; + var/*float*/ linesMainDim = 0; + var/*int*/ linesCount = 0; + while (endLine < childCount) { + // Layout non flexible children and count children by type + + // mainContentDim is accumulation of the dimensions and margin of all the + // non flexible children. This will be used in order to either set the + // dimensions of the node if none already exist, or to compute the + // remaining space left for the flexible children. + var/*float*/ mainContentDim = 0; + + // There are three kind of children, non flexible, flexible and absolute. + // We need to know how many there are in order to distribute the space. + var/*int*/ flexibleChildrenCount = 0; + var/*float*/ totalFlexible = 0; + var/*int*/ nonFlexibleChildrenCount = 0; + + // Use the line loop to position children in the main axis for as long + // as they are using a simple stacking behaviour. Children that are + // immediately stacked in the initial loop will not be touched again + // in . + var/*bool*/ isSimpleStackMain = + (isMainDimDefined && justifyContent === CSS_JUSTIFY_FLEX_START) || + (!isMainDimDefined && justifyContent !== CSS_JUSTIFY_CENTER); + var/*int*/ firstComplexMain = (isSimpleStackMain ? childCount : startLine); + + // Use the initial line loop to position children in the cross axis for + // as long as they are relatively positioned with alignment STRETCH or + // FLEX_START. Children that are immediately stacked in the initial loop + // will not be touched again in . + var/*bool*/ isSimpleStackCross = true; + var/*int*/ firstComplexCross = childCount; + + var/*css_node_t**/ firstFlexChild = null; + var/*css_node_t**/ currentFlexChild = null; + + var/*float*/ mainDim = leadingPaddingAndBorderMain; + var/*float*/ crossDim = 0; + + var/*float*/ maxWidth; + for (i = startLine; i < childCount; ++i) { + child = node.children[i]; + child.lineIndex = linesCount; + + child.nextAbsoluteChild = null; + child.nextFlexChild = null; + + var/*css_align_t*/ alignItem = getAlignItem(node, child); + + // Pre-fill cross axis dimensions when the child is using stretch before + // we call the recursive layout pass + if (alignItem === CSS_ALIGN_STRETCH && + getPositionType(child) === CSS_POSITION_RELATIVE && + isCrossDimDefined && + !isDimDefined(child, crossAxis)) { + child.layout[dim[crossAxis]] = fmaxf( + boundAxis(child, crossAxis, node.layout[dim[crossAxis]] - + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), + // You never want to go smaller than padding + getPaddingAndBorderAxis(child, crossAxis) + ); + } else if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { + // Store a private linked list of absolutely positioned children + // so that we can efficiently traverse them later. + if (firstAbsoluteChild === null) { + firstAbsoluteChild = child; + } + if (currentAbsoluteChild !== null) { + currentAbsoluteChild.nextAbsoluteChild = child; + } + currentAbsoluteChild = child; + + // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both + // left and right or top and bottom). + for (ii = 0; ii < 2; ii++) { + axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + if (!isUndefined(node.layout[dim[axis]]) && + !isDimDefined(child, axis) && + isPosDefined(child, leading[axis]) && + isPosDefined(child, trailing[axis])) { + child.layout[dim[axis]] = fmaxf( + boundAxis(child, axis, node.layout[dim[axis]] - + getPaddingAndBorderAxis(node, axis) - + getMarginAxis(child, axis) - + getPosition(child, leading[axis]) - + getPosition(child, trailing[axis])), + // You never want to go smaller than padding + getPaddingAndBorderAxis(child, axis) + ); + } + } + } + + var/*float*/ nextContentDim = 0; + + // It only makes sense to consider a child flexible if we have a computed + // dimension for the node. + if (isMainDimDefined && isFlex(child)) { + flexibleChildrenCount++; + totalFlexible += child.style.flex; + + // Store a private linked list of flexible children so that we can + // efficiently traverse them later. + if (firstFlexChild === null) { + firstFlexChild = child; + } + if (currentFlexChild !== null) { + currentFlexChild.nextFlexChild = child; + } + currentFlexChild = child; + + // Even if we don't know its exact size yet, we already know the padding, + // border and margin. We'll use this partial information, which represents + // the smallest possible size for the child, to compute the remaining + // available space. + nextContentDim = getPaddingAndBorderAxis(child, mainAxis) + + getMarginAxis(child, mainAxis); + + } else { + maxWidth = CSS_UNDEFINED; + if (!isMainRowDirection) { + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node.layout[dim[resolvedRowAxis]] - + paddingAndBorderAxisResolvedRow; + } else { + maxWidth = parentMaxWidth - + getMarginAxis(node, resolvedRowAxis) - + paddingAndBorderAxisResolvedRow; + } + } + + // This is the main recursive call. We layout non flexible children. + if (alreadyComputedNextLayout === 0) { + layoutNode(/*(java)!layoutContext, */child, maxWidth, direction); + } + + // Absolute positioned elements do not take part of the layout, so we + // don't use them to compute mainContentDim + if (getPositionType(child) === CSS_POSITION_RELATIVE) { + nonFlexibleChildrenCount++; + // At this point we know the final size and margin of the element. + nextContentDim = getDimWithMargin(child, mainAxis); + } + } + + // The element we are about to add would make us go to the next line + if (isNodeFlexWrap && + isMainDimDefined && + mainContentDim + nextContentDim > definedMainDim && + // If there's only one element, then it's bigger than the content + // and needs its own line + i !== startLine) { + nonFlexibleChildrenCount--; + alreadyComputedNextLayout = 1; + break; + } + + // Disable simple stacking in the main axis for the current line as + // we found a non-trivial child. The remaining children will be laid out + // in . + if (isSimpleStackMain && + (getPositionType(child) !== CSS_POSITION_RELATIVE || isFlex(child))) { + isSimpleStackMain = false; + firstComplexMain = i; + } + + // Disable simple stacking in the cross axis for the current line as + // we found a non-trivial child. The remaining children will be laid out + // in . + if (isSimpleStackCross && + (getPositionType(child) !== CSS_POSITION_RELATIVE || + (alignItem !== CSS_ALIGN_STRETCH && alignItem !== CSS_ALIGN_FLEX_START) || + isUndefined(child.layout[dim[crossAxis]]))) { + isSimpleStackCross = false; + firstComplexCross = i; + } + + if (isSimpleStackMain) { + child.layout[pos[mainAxis]] += mainDim; + if (isMainDimDefined) { + setTrailingPosition(node, child, mainAxis); + } + + mainDim += getDimWithMargin(child, mainAxis); + crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis))); + } + + if (isSimpleStackCross) { + child.layout[pos[crossAxis]] += linesCrossDim + leadingPaddingAndBorderCross; + if (isCrossDimDefined) { + setTrailingPosition(node, child, crossAxis); + } + } + + alreadyComputedNextLayout = 0; + mainContentDim += nextContentDim; + endLine = i + 1; + } + + // Layout flexible children and allocate empty space + + // In order to position the elements in the main axis, we have two + // controls. The space between the beginning and the first element + // and the space between each two elements. + var/*float*/ leadingMainDim = 0; + var/*float*/ betweenMainDim = 0; + + // The remaining available space that needs to be allocated + var/*float*/ remainingMainDim = 0; + if (isMainDimDefined) { + remainingMainDim = definedMainDim - mainContentDim; + } else { + remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim; + } + + // If there are flexible children in the mix, they are going to fill the + // remaining space + if (flexibleChildrenCount !== 0) { + var/*float*/ flexibleMainDim = remainingMainDim / totalFlexible; + var/*float*/ baseMainDim; + var/*float*/ boundMainDim; + + // If the flex share of remaining space doesn't meet min/max bounds, + // remove this child from flex calculations. + currentFlexChild = firstFlexChild; + while (currentFlexChild !== null) { + baseMainDim = flexibleMainDim * currentFlexChild.style.flex + + getPaddingAndBorderAxis(currentFlexChild, mainAxis); + boundMainDim = boundAxis(currentFlexChild, mainAxis, baseMainDim); + + if (baseMainDim !== boundMainDim) { + remainingMainDim -= boundMainDim; + totalFlexible -= currentFlexChild.style.flex; + } + + currentFlexChild = currentFlexChild.nextFlexChild; + } + flexibleMainDim = remainingMainDim / totalFlexible; + + // The non flexible children can overflow the container, in this case + // we should just assume that there is no space available. + if (flexibleMainDim < 0) { + flexibleMainDim = 0; + } + + currentFlexChild = firstFlexChild; + while (currentFlexChild !== null) { + // At this point we know the final size of the element in the main + // dimension + currentFlexChild.layout[dim[mainAxis]] = boundAxis(currentFlexChild, mainAxis, + flexibleMainDim * currentFlexChild.style.flex + + getPaddingAndBorderAxis(currentFlexChild, mainAxis) + ); + + maxWidth = CSS_UNDEFINED; + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node.layout[dim[resolvedRowAxis]] - + paddingAndBorderAxisResolvedRow; + } else if (!isMainRowDirection) { + maxWidth = parentMaxWidth - + getMarginAxis(node, resolvedRowAxis) - + paddingAndBorderAxisResolvedRow; + } + + // And we recursively call the layout algorithm for this child + layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, direction); + + child = currentFlexChild; + currentFlexChild = currentFlexChild.nextFlexChild; + child.nextFlexChild = null; + } + + // We use justifyContent to figure out how to allocate the remaining + // space available + } else if (justifyContent !== CSS_JUSTIFY_FLEX_START) { + if (justifyContent === CSS_JUSTIFY_CENTER) { + leadingMainDim = remainingMainDim / 2; + } else if (justifyContent === CSS_JUSTIFY_FLEX_END) { + leadingMainDim = remainingMainDim; + } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) { + remainingMainDim = fmaxf(remainingMainDim, 0); + if (flexibleChildrenCount + nonFlexibleChildrenCount - 1 !== 0) { + betweenMainDim = remainingMainDim / + (flexibleChildrenCount + nonFlexibleChildrenCount - 1); + } else { + betweenMainDim = 0; + } + } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) { + // Space on the edges is half of the space between elements + betweenMainDim = remainingMainDim / + (flexibleChildrenCount + nonFlexibleChildrenCount); + leadingMainDim = betweenMainDim / 2; + } + } + + // Position elements in the main axis and compute dimensions + + // At this point, all the children have their dimensions set. We need to + // find their position. In order to do that, we accumulate data in + // variables that are also useful to compute the total dimensions of the + // container! + mainDim += leadingMainDim; + + for (i = firstComplexMain; i < endLine; ++i) { + child = node.children[i]; + + if (getPositionType(child) === CSS_POSITION_ABSOLUTE && + isPosDefined(child, leading[mainAxis])) { + // In case the child is position absolute and has left/top being + // defined, we override the position to whatever the user said + // (and margin/border). + child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + + getLeadingBorder(node, mainAxis) + + getLeadingMargin(child, mainAxis); + } else { + // If the child is position absolute (without top/left) or relative, + // we put it at the current accumulated offset. + child.layout[pos[mainAxis]] += mainDim; + + // Define the trailing position accordingly. + if (isMainDimDefined) { + setTrailingPosition(node, child, mainAxis); + } + + // Now that we placed the element, we need to update the variables + // We only need to do that for relative elements. Absolute elements + // do not take part in that phase. + if (getPositionType(child) === CSS_POSITION_RELATIVE) { + // The main dimension is the sum of all the elements dimension plus + // the spacing. + mainDim += betweenMainDim + getDimWithMargin(child, mainAxis); + // The cross dimension is the max of the elements dimension since there + // can only be one element in that cross dimension. + crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis))); + } + } + } + + var/*float*/ containerCrossAxis = node.layout[dim[crossAxis]]; + if (!isCrossDimDefined) { + containerCrossAxis = fmaxf( + // For the cross dim, we add both sides at the end because the value + // is aggregate via a max function. Intermediate negative values + // can mess this computation otherwise + boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross + ); + } + + // Position elements in the cross axis + for (i = firstComplexCross; i < endLine; ++i) { + child = node.children[i]; + + if (getPositionType(child) === CSS_POSITION_ABSOLUTE && + isPosDefined(child, leading[crossAxis])) { + // In case the child is absolutely positionned and has a + // top/left/bottom/right being set, we override all the previously + // computed positions to set it correctly. + child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + + getLeadingBorder(node, crossAxis) + + getLeadingMargin(child, crossAxis); + + } else { + var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross; + + // For a relative children, we're either using alignItems (parent) or + // alignSelf (child) in order to determine the position in the cross axis + if (getPositionType(child) === CSS_POSITION_RELATIVE) { + // This variable is intentionally re-defined as the code is transpiled to a block scope language + var/*css_align_t*/ alignItem = getAlignItem(node, child); + if (alignItem === CSS_ALIGN_STRETCH) { + // You can only stretch if the dimension has not already been set + // previously. + if (isUndefined(child.layout[dim[crossAxis]])) { + child.layout[dim[crossAxis]] = fmaxf( + boundAxis(child, crossAxis, containerCrossAxis - + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), + // You never want to go smaller than padding + getPaddingAndBorderAxis(child, crossAxis) + ); + } + } else if (alignItem !== CSS_ALIGN_FLEX_START) { + // The remaining space between the parent dimensions+padding and child + // dimensions+margin. + var/*float*/ remainingCrossDim = containerCrossAxis - + paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis); + + if (alignItem === CSS_ALIGN_CENTER) { + leadingCrossDim += remainingCrossDim / 2; + } else { // CSS_ALIGN_FLEX_END + leadingCrossDim += remainingCrossDim; + } + } + } + + // And we apply the position + child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim; + + // Define the trailing position accordingly. + if (isCrossDimDefined) { + setTrailingPosition(node, child, crossAxis); + } + } + } + + linesCrossDim += crossDim; + linesMainDim = fmaxf(linesMainDim, mainDim); + linesCount += 1; + startLine = endLine; + } + + // + // + // Note(prenaux): More than one line, we need to layout the crossAxis + // according to alignContent. + // + // Note that we could probably remove and handle the one line case + // here too, but for the moment this is safer since it won't interfere with + // previously working code. + // + // See specs: + // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm + // section 9.4 + // + if (linesCount > 1 && isCrossDimDefined) { + var/*float*/ nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] - + paddingAndBorderAxisCross; + var/*float*/ remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; + + var/*float*/ crossDimLead = 0; + var/*float*/ currentLead = leadingPaddingAndBorderCross; + + var/*css_align_t*/ alignContent = getAlignContent(node); + if (alignContent === CSS_ALIGN_FLEX_END) { + currentLead += remainingAlignContentDim; + } else if (alignContent === CSS_ALIGN_CENTER) { + currentLead += remainingAlignContentDim / 2; + } else if (alignContent === CSS_ALIGN_STRETCH) { + if (nodeCrossAxisInnerSize > linesCrossDim) { + crossDimLead = (remainingAlignContentDim / linesCount); + } + } + + var/*int*/ endIndex = 0; + for (i = 0; i < linesCount; ++i) { + var/*int*/ startIndex = endIndex; + + // compute the line's height and find the endIndex + var/*float*/ lineHeight = 0; + for (ii = startIndex; ii < childCount; ++ii) { + child = node.children[ii]; + if (getPositionType(child) !== CSS_POSITION_RELATIVE) { + continue; + } + if (child.lineIndex !== i) { + break; + } + if (!isUndefined(child.layout[dim[crossAxis]])) { + lineHeight = fmaxf( + lineHeight, + child.layout[dim[crossAxis]] + getMarginAxis(child, crossAxis) + ); + } + } + endIndex = ii; + lineHeight += crossDimLead; + + for (ii = startIndex; ii < endIndex; ++ii) { + child = node.children[ii]; + if (getPositionType(child) !== CSS_POSITION_RELATIVE) { + continue; + } + + var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child); + if (alignContentAlignItem === CSS_ALIGN_FLEX_START) { + child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); + } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) { + child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[dim[crossAxis]]; + } else if (alignContentAlignItem === CSS_ALIGN_CENTER) { + var/*float*/ childHeight = child.layout[dim[crossAxis]]; + child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; + } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) { + child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); + // TODO(prenaux): Correctly set the height of items with undefined + // (auto) crossAxis dimension. + } + } + + currentLead += lineHeight; + } + } + + var/*bool*/ needsMainTrailingPos = false; + var/*bool*/ needsCrossTrailingPos = false; + + // If the user didn't specify a width or height, and it has not been set + // by the container, then we set it via the children. + if (!isMainDimDefined) { + node.layout[dim[mainAxis]] = fmaxf( + // We're missing the last padding at this point to get the final + // dimension + boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), + // We can never assign a width smaller than the padding and borders + paddingAndBorderAxisMain + ); + + if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || + mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) { + needsMainTrailingPos = true; + } + } + + if (!isCrossDimDefined) { + node.layout[dim[crossAxis]] = fmaxf( + // For the cross dim, we add both sides at the end because the value + // is aggregate via a max function. Intermediate negative values + // can mess this computation otherwise + boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross + ); + + if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || + crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) { + needsCrossTrailingPos = true; + } + } + + // Set trailing position if necessary + if (needsMainTrailingPos || needsCrossTrailingPos) { + for (i = 0; i < childCount; ++i) { + child = node.children[i]; + + if (needsMainTrailingPos) { + setTrailingPosition(node, child, mainAxis); + } + + if (needsCrossTrailingPos) { + setTrailingPosition(node, child, crossAxis); + } + } + } + + // Calculate dimensions for absolutely positioned elements + currentAbsoluteChild = firstAbsoluteChild; + while (currentAbsoluteChild !== null) { + // Pre-fill dimensions when using absolute position and both offsets for + // the axis are defined (either both left and right or top and bottom). + for (ii = 0; ii < 2; ii++) { + axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + + if (!isUndefined(node.layout[dim[axis]]) && + !isDimDefined(currentAbsoluteChild, axis) && + isPosDefined(currentAbsoluteChild, leading[axis]) && + isPosDefined(currentAbsoluteChild, trailing[axis])) { + currentAbsoluteChild.layout[dim[axis]] = fmaxf( + boundAxis(currentAbsoluteChild, axis, node.layout[dim[axis]] - + getBorderAxis(node, axis) - + getMarginAxis(currentAbsoluteChild, axis) - + getPosition(currentAbsoluteChild, leading[axis]) - + getPosition(currentAbsoluteChild, trailing[axis]) + ), + // You never want to go smaller than padding + getPaddingAndBorderAxis(currentAbsoluteChild, axis) + ); + } + + if (isPosDefined(currentAbsoluteChild, trailing[axis]) && + !isPosDefined(currentAbsoluteChild, leading[axis])) { + currentAbsoluteChild.layout[leading[axis]] = + node.layout[dim[axis]] - + currentAbsoluteChild.layout[dim[axis]] - + getPosition(currentAbsoluteChild, trailing[axis]); + } + } + + child = currentAbsoluteChild; + currentAbsoluteChild = currentAbsoluteChild.nextAbsoluteChild; + child.nextAbsoluteChild = null; + } + } + + function layoutNode(node, parentMaxWidth, parentDirection) { + node.shouldUpdate = true; + + var direction = node.style.direction || CSS_DIRECTION_LTR; + var skipLayout = + !node.isDirty && + node.lastLayout && + node.lastLayout.requestedHeight === node.layout.height && + node.lastLayout.requestedWidth === node.layout.width && + node.lastLayout.parentMaxWidth === parentMaxWidth && + node.lastLayout.direction === direction; + + if (skipLayout) { + node.layout.width = node.lastLayout.width; + node.layout.height = node.lastLayout.height; + node.layout.top = node.lastLayout.top; + node.layout.left = node.lastLayout.left; + } else { + if (!node.lastLayout) { + node.lastLayout = {}; + } + + node.lastLayout.requestedWidth = node.layout.width; + node.lastLayout.requestedHeight = node.layout.height; + node.lastLayout.parentMaxWidth = parentMaxWidth; + node.lastLayout.direction = direction; + + // Reset child layouts + node.children.forEach(function(child) { + child.layout.width = undefined; + child.layout.height = undefined; + child.layout.top = 0; + child.layout.left = 0; + }); + + layoutNodeImpl(node, parentMaxWidth, parentDirection); + + node.lastLayout.width = node.layout.width; + node.lastLayout.height = node.layout.height; + node.lastLayout.top = node.layout.top; + node.lastLayout.left = node.layout.left; + } + } + + return { + layoutNodeImpl: layoutNodeImpl, + computeLayout: layoutNode, + fillNodes: fillNodes + }; +})(); + +export default function(node) { + // disabling ESLint because this code relies on the above include + computeLayout.fillNodes(node); + computeLayout.computeLayout(node); +}; diff --git a/node_modules/widget-ui/src/element.ts b/node_modules/widget-ui/src/element.ts new file mode 100644 index 0000000..4677bc0 --- /dev/null +++ b/node_modules/widget-ui/src/element.ts @@ -0,0 +1,172 @@ + +import computeLayout from "./css-layout"; +import { getDefaultStyle, scalableStyles, layoutAffectedStyles } from "./style"; + +type LayoutData = { + left: number, + top: number, + width: number, + height: number +}; + +type LayoutNode = { + id: number, + style: Object, + children: LayoutNode[], + layout?: LayoutData +}; + +let uuid = 0; + +class Element { + public static uuid(): number { + return uuid++; + } + + public parent: Element | null = null; + public id: number = Element.uuid(); + public style: { [key: string]: any } = {}; + public computedStyle: { [key: string]: any } = {}; + public lastComputedStyle: { [key: string]: any } = {}; + public children: { [key: string]: Element } = {}; + public layoutBox: LayoutData = { left: 0, top: 0, width: 0, height: 0 }; + + constructor(style: { [key: string]: any } = {}) { + // 拷贝一份,防止被外部逻辑修改 + style = Object.assign(getDefaultStyle(), style); + this.computedStyle = Object.assign(getDefaultStyle(), style); + this.lastComputedStyle = Object.assign(getDefaultStyle(), style); + + Object.keys(style).forEach(key => { + Object.defineProperty(this.style, key, { + configurable: true, + enumerable: true, + get: () => style[key], + set: (value: any) => { + if (value === style[key] || value === undefined) { + return; + } + + this.lastComputedStyle = this.computedStyle[key] + style[key] = value + this.computedStyle[key] = value + + // 如果设置的是一个可缩放的属性, 计算自己 + if (scalableStyles.includes(key) && this.style.scale) { + this.computedStyle[key] = value * this.style.scale + } + + // 如果设置的是 scale, 则把所有可缩放的属性计算 + if (key === "scale") { + scalableStyles.forEach(prop => { + if (style[prop]) { + this.computedStyle[prop] = style[prop] * value + } + }) + } + + if (key === "hidden") { + if (value) { + layoutAffectedStyles.forEach((key: string) => { + this.computedStyle[key] = 0; + }); + } else { + layoutAffectedStyles.forEach((key: string) => { + this.computedStyle[key] = this.lastComputedStyle[key]; + }); + } + } + } + }) + }) + + if (this.style.scale) { + scalableStyles.forEach((key: string) => { + if (this.style[key]) { + const computedValue = this.style[key] * this.style.scale; + this.computedStyle[key] = computedValue; + } + }); + } + + if (style.hidden) { + layoutAffectedStyles.forEach((key: string) => { + this.computedStyle[key] = 0; + }); + } + } + + getAbsolutePosition(element: Element) { + if (!element) { + return this.getAbsolutePosition(this) + } + + if (!element.parent) { + return { + left: 0, + top: 0 + } + } + + const {left, top} = this.getAbsolutePosition(element.parent) + + return { + left: left + element.layoutBox.left, + top: top + element.layoutBox.top + } + } + + public add(element: Element) { + element.parent = this; + this.children[element.id] = element; + } + + public remove(element?: Element) { + // 删除自己 + if (!element) { + Object.keys(this.children).forEach(id => { + const child = this.children[id] + child.remove() + delete this.children[id] + }) + } else if (this.children[element.id]) { + // 是自己的子节点才删除 + element.remove() + delete this.children[element.id]; + } + } + + public getNodeTree(): LayoutNode { + return { + id: this.id, + style: this.computedStyle, + children: Object.keys(this.children).map((id: string) => { + const child = this.children[id]; + return child.getNodeTree(); + }) + } + } + + public applyLayout(layoutNode: LayoutNode) { + ["left", "top", "width", "height"].forEach((key: string) => { + if (layoutNode.layout && typeof layoutNode.layout[key] === "number") { + this.layoutBox[key] = layoutNode.layout[key]; + if (this.parent && (key === "left" || key === "top")) { + this.layoutBox[key] += this.parent.layoutBox[key]; + } + } + }); + + layoutNode.children.forEach((child: LayoutNode) => { + this.children[child.id].applyLayout(child); + }); + } + + layout() { + const nodeTree = this.getNodeTree(); + computeLayout(nodeTree); + this.applyLayout(nodeTree); + } +} + +export default Element; \ No newline at end of file diff --git a/node_modules/widget-ui/src/event.ts b/node_modules/widget-ui/src/event.ts new file mode 100644 index 0000000..fe41980 --- /dev/null +++ b/node_modules/widget-ui/src/event.ts @@ -0,0 +1,15 @@ +import _EventEmitter from "eventemitter3"; +const emitter = new _EventEmitter(); +export default class EventEmitter { + public emit(event: string, data?: any) { + emitter.emit(event, data); + } + + public on(event: string, callback) { + emitter.on(event, callback); + } + + public off(event: string, callback) { + emitter.off(event, callback); + } +} \ No newline at end of file diff --git a/node_modules/widget-ui/src/style.ts b/node_modules/widget-ui/src/style.ts new file mode 100644 index 0000000..7d595c2 --- /dev/null +++ b/node_modules/widget-ui/src/style.ts @@ -0,0 +1,87 @@ +const textStyles: string[] = ["color", "fontSize", "textAlign", "fontWeight", "lineHeight", "lineBreak"]; + +const scalableStyles: string[] = ["left", "top", "right", "bottom", "width", "height", + "margin", "marginLeft", "marginRight", "marginTop", "marginBottom", + "padding", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", + "borderWidth", "borderLeftWidth", "borderRightWidth", "borderTopWidth", "borderBottomWidth"]; + +const layoutAffectedStyles: string[] = [ + "margin", "marginTop", "marginBottom", "marginLeft", "marginRight", + "padding", "paddingTop", "paddingBottom", "paddingLeft", "paddingRight", + "width", "height"]; + +type Style = { + left: number, + top: number, + right: number, + bottom: number, + width: number, + height: number, + maxWidth: number, + maxHeight: number, + minWidth: number, + minHeight: number, + margin: number, + marginLeft: number, + marginRight: number, + marginTop: number, + marginBottom: number, + padding: number, + paddingLeft: number, + paddingRight: number, + paddingTop: number, + paddingBottom: number, + borderWidth: number, + borderLeftWidth: number, + borderRightWidth: number, + borderTopWidth: number, + borderBottomWidth: number, + flexDirection: "column" | "row", + justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around", + alignItems: "flex-start" | "center" | "flex-end" | "stretch", + alignSelf: "flex-start" | "center" | "flex-end" | "stretch", + flex: number, + flexWrap: "wrap" | "nowrap", + position: "relative" | "absolute", + + hidden: boolean, + scale: number +} + +const getDefaultStyle = () => ({ + left: undefined, + top: undefined, + right: undefined, + bottom: undefined, + width: undefined, + height: undefined, + maxWidth: undefined, + maxHeight: undefined, + minWidth: undefined, + minHeight: undefined, + margin: undefined, + marginLeft: undefined, + marginRight: undefined, + marginTop: undefined, + marginBottom: undefined, + padding: undefined, + paddingLeft: undefined, + paddingRight: undefined, + paddingTop: undefined, + paddingBottom: undefined, + borderWidth: undefined, + flexDirection: undefined, + justifyContent: undefined, + alignItems: undefined, + alignSelf: undefined, + flex: undefined, + flexWrap: undefined, + position: undefined, + + hidden: false, + scale: 1 +}) + +export { + getDefaultStyle, scalableStyles, textStyles, layoutAffectedStyles +} diff --git a/node_modules/widget-ui/test/css-layout.test.ts b/node_modules/widget-ui/test/css-layout.test.ts new file mode 100644 index 0000000..9657d2c --- /dev/null +++ b/node_modules/widget-ui/test/css-layout.test.ts @@ -0,0 +1,183 @@ + +import Element from "../src/element"; + +test("layout", () => { + const container = new Element({ + width: 100, + height: 100, + padding: 10, + borderWidth: 2 + }) + + const div1 = new Element({ + left: 5, + top: 5, + width: 14, + height: 14 + }) + + container.add(div1); + container.layout(); + // css-layout 是 border-box + expect(container.layoutBox.left).toBe(0); + expect(container.layoutBox.top).toBe(0); + expect(container.layoutBox.width).toBe(100); + expect(container.layoutBox.height).toBe(100); + + expect(div1.layoutBox.left).toBe(10 + 2 + 5); + expect(div1.layoutBox.top).toBe(10 + 2 + 5); + expect(div1.layoutBox.width).toBe(14); + expect(div1.layoutBox.height).toBe(14); +}); + +test("overflow", () => { + const container = new Element({ + width: 100, + height: 100, + padding: 10, + borderWidth: 2 + }) + + const div1 = new Element({ + width: 114, + height: 114, + }) + + container.add(div1); + container.layout(); + + // 写死尺寸的情况下子元素不收缩父元素不撑开 + expect(container.layoutBox.width).toBe(100); + expect(container.layoutBox.height).toBe(100); + + expect(div1.layoutBox.left).toBe(10 + 2); + expect(div1.layoutBox.top).toBe(10 + 2); + expect(div1.layoutBox.width).toBe(114); + expect(div1.layoutBox.height).toBe(114); +}); + +test("right bottom", () => { + const container = new Element({ + width: 100, + height: 100, + padding: 10, + borderWidth: 2 + }) + + const div1 = new Element({ + width: 14, + height: 14, + right: 13, + bottom: 9, + position: "absolute" + }) + + container.add(div1); + container.layout(); + + // right bottom 只有在 position 为 absolute 的情况下才有用 + expect(container.layoutBox.width).toBe(100); + expect(container.layoutBox.height).toBe(100); + + // 但这时就是以整个父元素为边界,而不是 border + padding 后的边界 + expect(div1.layoutBox.left).toBe(100 - 13 - 14); + expect(div1.layoutBox.top).toBe(100 - 9 - 14); +}); + +test("flex center", () => { + const container = new Element({ + width: 100, + height: 100, + padding: 10, + borderWidth: 2, + flexDirection: "row", + justifyContent: "center", + alignItems: "center" + }) + + const div1 = new Element({ + width: 14, + height: 14 + }) + + container.add(div1); + container.layout(); + // 使用 flex 水平垂直居中 + expect(div1.layoutBox.left).toBe((100 - 14)/2); + expect(div1.layoutBox.top).toBe((100 - 14)/2); +}) + +test("flex top bottom", () => { + const container = new Element({ + width: 100, + height: 100, + padding: 10, + borderWidth: 2, + flexDirection: "column", + justifyContent: "space-between", + alignItems: "stretch" + }) + + // flex 实现一上一下两行水平填满 + const div1 = new Element({ + height: 10 + }) + + const div2 = new Element({ + height: 20 + }) + + container.add(div1); + container.add(div2); + container.layout(); + + expect(div1.layoutBox.left).toBe(10 + 2); + expect(div1.layoutBox.top).toBe(10 + 2); + expect(div1.layoutBox.width).toBe(100 - 10*2 - 2*2); + + expect(div2.layoutBox.left).toBe(10 + 2); + expect(div2.layoutBox.top).toBe(100 - 10 - 2 - 20); + expect(div2.layoutBox.width).toBe(100 - 10*2 - 2*2); +}) + +test("rewrite uuid", () => { + // 小程序为了保证 webview 和 service 侧的 coverview 不冲突,所以设置了不同的自增起点 + // uuid 静态方法就是为了根据不同的需求去覆写 + let uuid = 79648527; + Element.uuid = () => uuid++; + const container = new Element(); + expect(container.id).toEqual(79648527); + const div = new Element(); + expect(div.id).toEqual(79648528); +}); + +test("absolute left top", () => { + const container = new Element({ + width: 300, + height: 200, + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center' + }) + + + const div1 = new Element({ + width: 80, + height: 60 + }) + + const div2 = new Element({ + width: 40, + height: 30 + }) + + div1.add(div2) + container.add(div1) + container.layout() + + expect(div1.layoutBox.left).toBe(110) + expect(div1.layoutBox.top).toBe(70) + + expect(div2.layoutBox.left).toBe(110) + expect(div2.layoutBox.top).toBe(70) +}) \ No newline at end of file diff --git a/node_modules/widget-ui/tsconfig.json b/node_modules/widget-ui/tsconfig.json new file mode 100644 index 0000000..5e628f9 --- /dev/null +++ b/node_modules/widget-ui/tsconfig.json @@ -0,0 +1,47 @@ +{ + "compilerOptions": { + "baseUrl": "src", + "resolveJsonModule": true, + "downlevelIteration": false, + "target": "es5", + "module": "commonjs", + "lib": [ + "es5", + "es2015.promise", + "es2016", + "dom" + ], + "outDir": "./dist", + "paths": { + "@/*": [ + "*" + ], + "*": [ + "*" + ] + }, + "typeRoots": [ + "./node_modules/@types" + ], + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "declaration": true, + "stripInternal": true, + "experimentalDecorators": true, + "noImplicitReturns": true, + "alwaysStrict": true, + "noFallthroughCasesInSwitch": true, + "removeComments": false, + "strictNullChecks": true, + "strictFunctionTypes": true, + "skipLibCheck": true, + "pretty": true, + "strictPropertyInitialization": true + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/node_modules/widget-ui/tslint.json b/node_modules/widget-ui/tslint.json new file mode 100644 index 0000000..f6dac04 --- /dev/null +++ b/node_modules/widget-ui/tslint.json @@ -0,0 +1,206 @@ +{ + "defaultSeverity": "error", + "extends": [], + "rules": { + "adjacent-overload-signatures": true, + "align": { + "options": [ + "parameters", + "statements" + ] + }, + "arrow-return-shorthand": true, + "ban-types": { + "options": [ + [ + "Object", + "Avoid using the `Object` type. Did you mean `object`?" + ], + [ + "Function", + "Avoid using the `Function` type. Prefer a specific function type, like `() => void`." + ], + [ + "Boolean", + "Avoid using the `Boolean` type. Did you mean `boolean`?" + ], + [ + "Number", + "Avoid using the `Number` type. Did you mean `number`?" + ], + [ + "String", + "Avoid using the `String` type. Did you mean `string`?" + ], + [ + "Symbol", + "Avoid using the `Symbol` type. Did you mean `symbol`?" + ] + ] + }, + "comment-format": { + "options": [ + "check-space" + ] + }, + "curly": { + "options": [ + "ignore-same-line" + ] + }, + "cyclomatic-complexity": false, + "import-spacing": true, + "indent": { + "options": [ + "spaces" + ] + }, + "interface-over-type-literal": true, + "member-ordering": [ + true, + { + "order": [ + "public-static-field", + "public-instance-field", + "private-static-field", + "private-instance-field", + "public-constructor", + "private-constructor", + "public-instance-method", + "protected-instance-method", + "private-instance-method" + ], + "alphabetize": false + } + ], + "no-angle-bracket-type-assertion": true, + "no-arg": true, + "no-conditional-assignment": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-eval": true, + "no-internal-module": true, + "no-misused-new": true, + "no-reference-import": true, + "no-string-literal": true, + "no-string-throw": true, + "no-unnecessary-initializer": true, + "no-unsafe-finally": true, + "no-unused-expression": true, + "no-use-before-declare": false, + "no-var-keyword": true, + "no-var-requires": true, + "one-line": { + "options": [ + "check-catch", + "check-else", + "check-finally", + "check-open-brace", + "check-whitespace" + ] + }, + "one-variable-per-declaration": { + "options": [ + "ignore-for-loop" + ] + }, + "ordered-imports": { + "options": { + "import-sources-order": "case-insensitive", + "module-source-path": "full", + "named-imports-order": "case-insensitive" + } + }, + "prefer-const": true, + "prefer-for-of": false, + "quotemark": { + "options": [ + "double", + "avoid-escape" + ] + }, + "radix": true, + "semicolon": { + "options": [ + "always" + ] + }, + "space-before-function-paren": { + "options": { + "anonymous": "never", + "asyncArrow": "always", + "constructor": "never", + "method": "never", + "named": "never" + } + }, + "trailing-comma": { + "options": { + "esSpecCompliant": true, + "multiline": { + "objects": "always", + "arrays": "always", + "functions": "always", + "typeLiterals": "always" + }, + "singleline": "never" + } + }, + "triple-equals": { + "options": [ + "allow-null-check" + ] + }, + "typedef": false, + "typedef-whitespace": { + "options": [ + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }, + { + "call-signature": "onespace", + "index-signature": "onespace", + "parameter": "onespace", + "property-declaration": "onespace", + "variable-declaration": "onespace" + } + ] + }, + "typeof-compare": false, + "unified-signatures": true, + "use-isnan": true, + "whitespace": { + "options": [ + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type", + "check-typecast" + ] + } + }, + "jsRules": {}, + "rulesDirectory": [], + "no-var-requires": false, + "trailing-comma": [ + true, + { + "multiline": { + "objects": "always", + "arrays": "always", + "functions": "always", + "typeLiterals": "ignore" + }, + "esSpecCompliant": true + } + ], + "no-unused-expression": [ + true, + "allow-fast-null-checks" + ] +} \ No newline at end of file diff --git a/node_modules/widget-ui/webpack.config.js b/node_modules/widget-ui/webpack.config.js new file mode 100644 index 0000000..2a3a7e2 --- /dev/null +++ b/node_modules/widget-ui/webpack.config.js @@ -0,0 +1,25 @@ +const path = require("path"); + +module.exports = { + mode: "production", + entry: path.resolve(__dirname, "src/element.ts"), + module: { + rules: [ + { + test: /\.ts$/, + use: "ts-loader", + exclude: /node_modules/ + } + ] + }, + resolve: { + extensions: [".js", ".ts"] + }, + output: { + filename: "index.js", + path: path.resolve(__dirname, "dist"), + libraryTarget: "umd", // 采用通用模块定义 + libraryExport: "default", // 兼容 ES6(ES2015) 的模块系统、CommonJS 和 AMD 模块规范 + globalObject: "this" // 兼容node和浏览器运行,避免window is not undefined情况 + } +}; \ No newline at end of file diff --git a/node_modules/wxml-to-canvas/.babelrc b/node_modules/wxml-to-canvas/.babelrc new file mode 100644 index 0000000..c062b77 --- /dev/null +++ b/node_modules/wxml-to-canvas/.babelrc @@ -0,0 +1,10 @@ +{ + "plugins": [ + ["module-resolver", { + "root": ["./src"], + "alias": {} + }], + "@babel/transform-runtime" + ], + "presets": ["@babel/preset-env"] +} \ No newline at end of file diff --git a/node_modules/wxml-to-canvas/.eslintrc.js b/node_modules/wxml-to-canvas/.eslintrc.js new file mode 100644 index 0000000..6576a30 --- /dev/null +++ b/node_modules/wxml-to-canvas/.eslintrc.js @@ -0,0 +1,99 @@ +module.exports = { + 'extends': [ + 'airbnb-base', + 'plugin:promise/recommended' + ], + 'parserOptions': { + 'ecmaVersion': 9, + 'ecmaFeatures': { + 'jsx': false + }, + 'sourceType': 'module' + }, + 'env': { + 'es6': true, + 'node': true, + 'jest': true + }, + 'plugins': [ + 'import', + 'node', + 'promise' + ], + 'rules': { + 'arrow-parens': 'off', + 'comma-dangle': [ + 'error', + 'only-multiline' + ], + 'complexity': ['error', 10], + 'func-names': 'off', + 'global-require': 'off', + 'handle-callback-err': [ + 'error', + '^(err|error)$' + ], + 'import/no-unresolved': [ + 'error', + { + 'caseSensitive': true, + 'commonjs': true, + 'ignore': ['^[^.]'] + } + ], + 'import/prefer-default-export': 'off', + 'linebreak-style': 'off', + 'no-catch-shadow': 'error', + 'no-continue': 'off', + 'no-div-regex': 'warn', + 'no-else-return': 'off', + 'no-param-reassign': 'off', + 'no-plusplus': 'off', + 'no-shadow': 'off', + 'no-multi-assign': 'off', + 'no-underscore-dangle': 'off', + 'node/no-deprecated-api': 'error', + 'node/process-exit-as-throw': 'error', + 'object-curly-spacing': [ + 'error', + 'never' + ], + 'operator-linebreak': [ + 'error', + 'after', + { + 'overrides': { + ':': 'before', + '?': 'before' + } + } + ], + 'prefer-arrow-callback': 'off', + 'prefer-destructuring': 'off', + 'prefer-template': 'off', + 'quote-props': [ + 1, + 'as-needed', + { + 'unnecessary': true + } + ], + 'semi': [ + 'error', + 'never' + ], + 'no-await-in-loop': 'off', + 'no-restricted-syntax': 'off', + 'promise/always-return': 'off', + }, + 'globals': { + 'window': true, + 'document': true, + 'App': true, + 'Page': true, + 'Component': true, + 'Behavior': true, + 'wx': true, + 'getCurrentPages': true, + } +} diff --git a/node_modules/wxml-to-canvas/LICENSE b/node_modules/wxml-to-canvas/LICENSE new file mode 100644 index 0000000..3617210 --- /dev/null +++ b/node_modules/wxml-to-canvas/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 wechat-miniprogram + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/wxml-to-canvas/README.md b/node_modules/wxml-to-canvas/README.md new file mode 100644 index 0000000..8ee64df --- /dev/null +++ b/node_modules/wxml-to-canvas/README.md @@ -0,0 +1,187 @@ +# wxml-to-canvas + +[![](https://img.shields.io/npm/v/wxml-to-canvas)](https://www.npmjs.com/package/wxml-to-canvas) +[![](https://img.shields.io/npm/l/wxml-to-canvas)](https://github.com/wechat-miniprogram/wxml-to-canvas) + +小程序内通过静态模板和样式绘制 canvas ,导出图片,可用于生成分享图等场景。[代码片段](https://developers.weixin.qq.com/s/r6UBlEm17pc6) + + +## 使用方法 + +#### Step1. npm 安装,参考 [小程序 npm 支持](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html) + +``` +npm install --save wxml-to-canvas +``` + +#### Step2. JSON 组件声明 + +``` +{ + "usingComponents": { + "wxml-to-canvas": "wxml-to-canvas", + } +} +``` + +#### Step3. wxml 引入组件 + +``` + + +``` + +##### 属性列表 + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| --------------- | ------- | ------- | ---- | ---------------------- | +| width | Number | 400 | 否 | 画布宽度 | +| height | Number | 300 | 否 | 画布高度 | + + +#### Step4. js 获取实例 + +``` +const {wxml, style} = require('./demo.js') +Page({ + data: { + src: '' + }, + onLoad() { + this.widget = this.selectComponent('.widget') + }, + renderToCanvas() { + const p1 = this.widget.renderToCanvas({ wxml, style }) + p1.then((res) => { + this.container = res + this.extraImage() + }) + }, + extraImage() { + const p2 = this.widget.canvasToTempFilePath() + p2.then(res => { + this.setData({ + src: res.tempFilePath, + width: this.container.layoutBox.width, + height: this.container.layoutBox.height + }) + }) + } +}) +``` + +## wxml 模板 + +支持 `view`、`text`、`image` 三种标签,通过 class 匹配 style 对象中的样式。 + +``` + + + + + yeah! + + + + + +``` + +## 样式 + +对象属性值为对应 wxml 标签的 cass 驼峰形式。**需为每个元素指定 width 和 height 属性**,否则会导致布局错误。 + +存在多个 className 时,位置靠后的优先级更高,子元素会继承父级元素的可继承属性。 + +元素均为 flex 布局。left/top 等 仅在 absolute 定位下生效。 + +``` +const style = { + container: { + width: 300, + height: 200, + flexDirection: 'row', + justifyContent: 'space-around', + backgroundColor: '#ccc', + alignItems: 'center', + }, + itemBox: { + width: 80, + height: 60, + }, + red: { + backgroundColor: '#ff0000' + }, + green: { + backgroundColor: '#00ff00' + }, + blue: { + backgroundColor: '#0000ff' + }, + text: { + width: 80, + height: 60, + textAlign: 'center', + verticalAlign: 'middle', + } +} +``` + +## 接口 + +#### f1. `renderToCanvas({wxml, style}): Promise` + +渲染到 canvas,传入 wxml 模板 和 style 对象,返回的容器对象包含布局和样式信息。 + +#### f2. `canvasToTempFilePath({fileType, quality}): Promise` + +提取画布中容器所在区域内容生成相同大小的图片,返回临时文件地址。 + +`fileType` 支持 `jpg`、`png` 两种格式,quality 为图片的质量,目前仅对 jpg 有效。取值范围为 (0, 1],不在范围内时当作 1.0 处理。 + +## 支持的 css 属性 + +### 布局相关 + +| 属性名 | 支持的值或类型 | 默认值 | +| --------------------- | --------------------------------------------------------- | ---------- | +| width | number | 0 | +| height | number | 0 | +| position | relative, absolute | relative | +| left | number | 0 | +| top | number | 0 | +| right | number | 0 | +| bottom | number | 0 | +| margin | number | 0 | +| padding | number | 0 | +| borderWidth | number | 0 | +| borderRadius | number | 0 | +| flexDirection | column, row | row | +| flexShrink | number | 1 | +| flexGrow | number | | +| flexWrap | wrap, nowrap | nowrap | +| justifyContent | flex-start, center, flex-end, space-between, space-around | flex-start | +| alignItems, alignSelf | flex-start, center, flex-end, stretch | flex-start | + +支持 marginLeft、paddingLeft 等 + +### 文字 + +| 属性名 | 支持的值或类型 | 默认值 | +| --------------- | ------------------- | ----------- | +| fontSize | number | 14 | +| lineHeight | number / string | '1.4em' | +| textAlign | left, center, right | left | +| verticalAlign | top, middle, bottom | top | +| color | string | #000000 | +| backgroundColor | string | transparent | + +lineHeight 可取带 em 单位的字符串或数字类型。 + +### 变形 + +| 属性名 | 支持的值或类型 | 默认值 | +| ------ | -------------- | ------ | +| scale | number | 1 | diff --git a/node_modules/wxml-to-canvas/gulpfile.js b/node_modules/wxml-to-canvas/gulpfile.js new file mode 100644 index 0000000..fb292c2 --- /dev/null +++ b/node_modules/wxml-to-canvas/gulpfile.js @@ -0,0 +1,26 @@ +const gulp = require('gulp') +const clean = require('gulp-clean') + +const config = require('./tools/config') +const BuildTask = require('./tools/build') +const id = require('./package.json').name || 'miniprogram-custom-component' + +// 构建任务实例 +// eslint-disable-next-line no-new +new BuildTask(id, config.entry) + +// 清空生成目录和文件 +gulp.task('clean', gulp.series(() => gulp.src(config.distPath, {read: false, allowEmpty: true}).pipe(clean()), done => { + if (config.isDev) { + return gulp.src(config.demoDist, {read: false, allowEmpty: true}) + .pipe(clean()) + } + + return done() +})) +// 监听文件变化并进行开发模式构建 +gulp.task('watch', gulp.series(`${id}-watch`)) +// 开发模式构建 +gulp.task('dev', gulp.series(`${id}-dev`)) +// 生产模式构建 +gulp.task('default', gulp.series(`${id}-default`)) diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.js b/node_modules/wxml-to-canvas/miniprogram_dist/index.js new file mode 100644 index 0000000..2a4f21e --- /dev/null +++ b/node_modules/wxml-to-canvas/miniprogram_dist/index.js @@ -0,0 +1,779 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else { + var a = factory(); + for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; + } +})(window, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +const hex = (color) => { + let result = null + + if (/^#/.test(color) && (color.length === 7 || color.length === 9)) { + return color + // eslint-disable-next-line no-cond-assign + } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) { + return '#' + result[2].split(',').map((part, index) => { + part = part.trim() + part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10) + part = part.toString(16) + if (part.length === 1) { + part = '0' + part + } + return part + }).join('') + } else { + return '#00000000' + } +} + +const splitLineToCamelCase = (str) => str.split('-').map((part, index) => { + if (index === 0) { + return part + } + return part[0].toUpperCase() + part.slice(1) +}).join('') + +const compareVersion = (v1, v2) => { + v1 = v1.split('.') + v2 = v2.split('.') + const len = Math.max(v1.length, v2.length) + while (v1.length < len) { + v1.push('0') + } + while (v2.length < len) { + v2.push('0') + } + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i], 10) + const num2 = parseInt(v2[i], 10) + + if (num1 > num2) { + return 1 + } else if (num1 < num2) { + return -1 + } + } + + return 0 +} + +module.exports = { + hex, + splitLineToCamelCase, + compareVersion +} + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + +const xmlParse = __webpack_require__(2) +const {Widget} = __webpack_require__(3) +const {Draw} = __webpack_require__(5) +const {compareVersion} = __webpack_require__(0) + +const canvasId = 'weui-canvas' + +Component({ + properties: { + width: { + type: Number, + value: 400 + }, + height: { + type: Number, + value: 300 + } + }, + data: { + use2dCanvas: false, // 2.9.2 后可用canvas 2d 接口 + }, + lifetimes: { + attached() { + const {SDKVersion, pixelRatio: dpr} = wx.getSystemInfoSync() + const use2dCanvas = compareVersion(SDKVersion, '2.9.2') >= 0 + this.dpr = dpr + this.setData({use2dCanvas}, () => { + if (use2dCanvas) { + const query = this.createSelectorQuery() + query.select(`#${canvasId}`) + .fields({node: true, size: true}) + .exec(res => { + const canvas = res[0].node + const ctx = canvas.getContext('2d') + canvas.width = res[0].width * dpr + canvas.height = res[0].height * dpr + ctx.scale(dpr, dpr) + this.ctx = ctx + this.canvas = canvas + }) + } else { + this.ctx = wx.createCanvasContext(canvasId, this) + } + }) + } + }, + methods: { + async renderToCanvas(args) { + const {wxml, style} = args + const ctx = this.ctx + const canvas = this.canvas + const use2dCanvas = this.data.use2dCanvas + + if (use2dCanvas && !canvas) { + return Promise.reject(new Error('renderToCanvas: fail canvas has not been created')) + } + + ctx.clearRect(0, 0, this.data.width, this.data.height) + const {root: xom} = xmlParse(wxml) + + const widget = new Widget(xom, style) + const container = widget.init() + this.boundary = { + top: container.layoutBox.top, + left: container.layoutBox.left, + width: container.computedStyle.width, + height: container.computedStyle.height, + } + const draw = new Draw(ctx, canvas, use2dCanvas) + await draw.drawNode(container) + + if (!use2dCanvas) { + await this.canvasDraw(ctx) + } + return Promise.resolve(container) + }, + + canvasDraw(ctx, reserve) { + return new Promise(resolve => { + ctx.draw(reserve, () => { + resolve() + }) + }) + }, + + canvasToTempFilePath(args = {}) { + const use2dCanvas = this.data.use2dCanvas + + return new Promise((resolve, reject) => { + const { + top, left, width, height + } = this.boundary + + const copyArgs = { + x: left, + y: top, + width, + height, + destWidth: width * this.dpr, + destHeight: height * this.dpr, + canvasId, + fileType: args.fileType || 'png', + quality: args.quality || 1, + success: resolve, + fail: reject + } + + if (use2dCanvas) { + delete copyArgs.canvasId + copyArgs.canvas = this.canvas + } + wx.canvasToTempFilePath(copyArgs, this) + }) + } + } +}) + + +/***/ }), +/* 2 */ +/***/ (function(module, exports) { + + +/** + * Module dependencies. + */ + + +/** + * Expose `parse`. + */ + + +/** + * Parse the given string of `xml`. + * + * @param {String} xml + * @return {Object} + * @api public + */ + +function parse(xml) { + xml = xml.trim() + + // strip comments + xml = xml.replace(//g, '') + + return document() + + /** + * XML document. + */ + + function document() { + return { + declaration: declaration(), + root: tag() + } + } + + /** + * Declaration. + */ + + function declaration() { + const m = match(/^<\?xml\s*/) + if (!m) return + + // tag + const node = { + attributes: {} + } + + // attributes + while (!(eos() || is('?>'))) { + const attr = attribute() + if (!attr) return node + node.attributes[attr.name] = attr.value + } + + match(/\?>\s*/) + + return node + } + + /** + * Tag. + */ + + function tag() { + const m = match(/^<([\w-:.]+)\s*/) + if (!m) return + + // name + const node = { + name: m[1], + attributes: {}, + children: [] + } + + // attributes + while (!(eos() || is('>') || is('?>') || is('/>'))) { + const attr = attribute() + if (!attr) return node + node.attributes[attr.name] = attr.value + } + + // self closing tag + if (match(/^\s*\/>\s*/)) { + return node + } + + match(/\??>\s*/) + + // content + node.content = content() + + // children + let child + while (child = tag()) { + node.children.push(child) + } + + // closing + match(/^<\/[\w-:.]+>\s*/) + + return node + } + + /** + * Text content. + */ + + function content() { + const m = match(/^([^<]*)/) + if (m) return m[1] + return '' + } + + /** + * Attribute. + */ + + function attribute() { + const m = match(/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/) + if (!m) return + return {name: m[1], value: strip(m[2])} + } + + /** + * Strip quotes from `val`. + */ + + function strip(val) { + return val.replace(/^['"]|['"]$/g, '') + } + + /** + * Match `re` and advance the string. + */ + + function match(re) { + const m = xml.match(re) + if (!m) return + xml = xml.slice(m[0].length) + return m + } + + /** + * End-of-source. + */ + + function eos() { + return xml.length == 0 + } + + /** + * Check for `prefix`. + */ + + function is(prefix) { + return xml.indexOf(prefix) == 0 + } +} + +module.exports = parse + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +const Block = __webpack_require__(4) +const {splitLineToCamelCase} = __webpack_require__(0) + +class Element extends Block { + constructor(prop) { + super(prop.style) + this.name = prop.name + this.attributes = prop.attributes + } +} + + +class Widget { + constructor(xom, style) { + this.xom = xom + this.style = style + + this.inheritProps = ['fontSize', 'lineHeight', 'textAlign', 'verticalAlign', 'color'] + } + + init() { + this.container = this.create(this.xom) + this.container.layout() + + this.inheritStyle(this.container) + return this.container + } + + // 继承父节点的样式 + inheritStyle(node) { + const parent = node.parent || null + const children = node.children || {} + const computedStyle = node.computedStyle + + if (parent) { + this.inheritProps.forEach(prop => { + computedStyle[prop] = computedStyle[prop] || parent.computedStyle[prop] + }) + } + + Object.values(children).forEach(child => { + this.inheritStyle(child) + }) + } + + create(node) { + let classNames = (node.attributes.class || '').split(' ') + classNames = classNames.map(item => splitLineToCamelCase(item.trim())) + const style = {} + classNames.forEach(item => { + Object.assign(style, this.style[item] || {}) + }) + + const args = {name: node.name, style} + + const attrs = Object.keys(node.attributes) + const attributes = {} + for (const attr of attrs) { + const value = node.attributes[attr] + const CamelAttr = splitLineToCamelCase(attr) + + if (value === '' || value === 'true') { + attributes[CamelAttr] = true + } else if (value === 'false') { + attributes[CamelAttr] = false + } else { + attributes[CamelAttr] = value + } + } + attributes.text = node.content + args.attributes = attributes + const element = new Element(args) + node.children.forEach(childNode => { + const childElement = this.create(childNode) + element.add(childElement) + }) + return element + } +} + +module.exports = {Widget} + + +/***/ }), +/* 4 */ +/***/ (function(module, exports) { + +module.exports = require("widget-ui"); + +/***/ }), +/* 5 */ +/***/ (function(module, exports) { + +class Draw { + constructor(context, canvas, use2dCanvas = false) { + this.ctx = context + this.canvas = canvas || null + this.use2dCanvas = use2dCanvas + } + + roundRect(x, y, w, h, r, fill = true, stroke = false) { + if (r < 0) return + const ctx = this.ctx + + ctx.beginPath() + ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 3 / 2) + ctx.arc(x + w - r, y + r, r, Math.PI * 3 / 2, 0) + ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2) + ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI) + ctx.lineTo(x, y + r) + if (stroke) ctx.stroke() + if (fill) ctx.fill() + } + + drawView(box, style) { + const ctx = this.ctx + const { + left: x, top: y, width: w, height: h + } = box + const { + borderRadius = 0, + borderWidth = 0, + borderColor, + color = '#000', + backgroundColor = 'transparent', + } = style + ctx.save() + // 外环 + if (borderWidth > 0) { + ctx.fillStyle = borderColor || color + this.roundRect(x, y, w, h, borderRadius) + } + + // 内环 + ctx.fillStyle = backgroundColor + const innerWidth = w - 2 * borderWidth + const innerHeight = h - 2 * borderWidth + const innerRadius = borderRadius - borderWidth >= 0 ? borderRadius - borderWidth : 0 + this.roundRect(x + borderWidth, y + borderWidth, innerWidth, innerHeight, innerRadius) + ctx.restore() + } + + async drawImage(img, box, style) { + await new Promise((resolve, reject) => { + const ctx = this.ctx + const canvas = this.canvas + + const { + borderRadius = 0 + } = style + const { + left: x, top: y, width: w, height: h + } = box + ctx.save() + this.roundRect(x, y, w, h, borderRadius, false, false) + ctx.clip() + + const _drawImage = (img) => { + if (this.use2dCanvas) { + const Image = canvas.createImage() + Image.onload = () => { + ctx.drawImage(Image, x, y, w, h) + ctx.restore() + resolve() + } + Image.onerror = () => { reject(new Error(`createImage fail: ${img}`)) } + Image.src = img + } else { + ctx.drawImage(img, x, y, w, h) + ctx.restore() + resolve() + } + } + + const isTempFile = /^wxfile:\/\//.test(img) + const isNetworkFile = /^https?:\/\//.test(img) + + if (isTempFile) { + _drawImage(img) + } else if (isNetworkFile) { + wx.downloadFile({ + url: img, + success(res) { + if (res.statusCode === 200) { + _drawImage(res.tempFilePath) + } else { + reject(new Error(`downloadFile:fail ${img}`)) + } + }, + fail() { + reject(new Error(`downloadFile:fail ${img}`)) + } + }) + } else { + reject(new Error(`image format error: ${img}`)) + } + }) + } + + // eslint-disable-next-line complexity + drawText(text, box, style) { + const ctx = this.ctx + let { + left: x, top: y, width: w, height: h + } = box + let { + color = '#000', + lineHeight = '1.4em', + fontSize = 14, + textAlign = 'left', + verticalAlign = 'top', + backgroundColor = 'transparent' + } = style + + if (typeof lineHeight === 'string') { // 2em + lineHeight = Math.ceil(parseFloat(lineHeight.replace('em')) * fontSize) + } + if (!text || (lineHeight > h)) return + + ctx.save() + ctx.textBaseline = 'top' + ctx.font = `${fontSize}px sans-serif` + ctx.textAlign = textAlign + + // 背景色 + ctx.fillStyle = backgroundColor + this.roundRect(x, y, w, h, 0) + + // 文字颜色 + ctx.fillStyle = color + + // 水平布局 + switch (textAlign) { + case 'left': + break + case 'center': + x += 0.5 * w + break + case 'right': + x += w + break + default: break + } + + const textWidth = ctx.measureText(text).width + const actualHeight = Math.ceil(textWidth / w) * lineHeight + let paddingTop = Math.ceil((h - actualHeight) / 2) + if (paddingTop < 0) paddingTop = 0 + + // 垂直布局 + switch (verticalAlign) { + case 'top': + break + case 'middle': + y += paddingTop + break + case 'bottom': + y += 2 * paddingTop + break + default: break + } + + const inlinePaddingTop = Math.ceil((lineHeight - fontSize) / 2) + + // 不超过一行 + if (textWidth <= w) { + ctx.fillText(text, x, y + inlinePaddingTop) + return + } + + // 多行文本 + const chars = text.split('') + const _y = y + + // 逐行绘制 + let line = '' + for (const ch of chars) { + const testLine = line + ch + const testWidth = ctx.measureText(testLine).width + + if (testWidth > w) { + ctx.fillText(line, x, y + inlinePaddingTop) + y += lineHeight + line = ch + if ((y + lineHeight) > (_y + h)) break + } else { + line = testLine + } + } + + // 避免溢出 + if ((y + lineHeight) <= (_y + h)) { + ctx.fillText(line, x, y + inlinePaddingTop) + } + ctx.restore() + } + + async drawNode(element) { + const {layoutBox, computedStyle, name} = element + const {src, text} = element.attributes + if (name === 'view') { + this.drawView(layoutBox, computedStyle) + } else if (name === 'image') { + await this.drawImage(src, layoutBox, computedStyle) + } else if (name === 'text') { + this.drawText(text, layoutBox, computedStyle) + } + const childs = Object.values(element.children) + for (const child of childs) { + await this.drawNode(child) + } + } +} + + +module.exports = { + Draw +} + + +/***/ }) +/******/ ]); +}); \ No newline at end of file diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.json b/node_modules/wxml-to-canvas/miniprogram_dist/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/node_modules/wxml-to-canvas/miniprogram_dist/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.wxml b/node_modules/wxml-to-canvas/miniprogram_dist/index.wxml new file mode 100644 index 0000000..a0010ad --- /dev/null +++ b/node_modules/wxml-to-canvas/miniprogram_dist/index.wxml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.wxss b/node_modules/wxml-to-canvas/miniprogram_dist/index.wxss new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/utils.js b/node_modules/wxml-to-canvas/miniprogram_dist/utils.js new file mode 100644 index 0000000..c3cf7d7 --- /dev/null +++ b/node_modules/wxml-to-canvas/miniprogram_dist/utils.js @@ -0,0 +1,57 @@ +const hex = (color) => { + let result = null + + if (/^#/.test(color) && (color.length === 7 || color.length === 9)) { + return color + // eslint-disable-next-line no-cond-assign + } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) { + return '#' + result[2].split(',').map((part, index) => { + part = part.trim() + part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10) + part = part.toString(16) + if (part.length === 1) { + part = '0' + part + } + return part + }).join('') + } else { + return '#00000000' + } +} + +const splitLineToCamelCase = (str) => str.split('-').map((part, index) => { + if (index === 0) { + return part + } + return part[0].toUpperCase() + part.slice(1) +}).join('') + +const compareVersion = (v1, v2) => { + v1 = v1.split('.') + v2 = v2.split('.') + const len = Math.max(v1.length, v2.length) + while (v1.length < len) { + v1.push('0') + } + while (v2.length < len) { + v2.push('0') + } + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i], 10) + const num2 = parseInt(v2[i], 10) + + if (num1 > num2) { + return 1 + } else if (num1 < num2) { + return -1 + } + } + + return 0 +} + +module.exports = { + hex, + splitLineToCamelCase, + compareVersion +} diff --git a/node_modules/wxml-to-canvas/package.json b/node_modules/wxml-to-canvas/package.json new file mode 100644 index 0000000..54fe015 --- /dev/null +++ b/node_modules/wxml-to-canvas/package.json @@ -0,0 +1,91 @@ +{ + "_from": "wxml-to-canvas", + "_id": "wxml-to-canvas@1.1.1", + "_inBundle": false, + "_integrity": "sha512-3mDjHzujY/UgdCOXij/MnmwJYerVjwkyQHMBFBE8zh89DK7h7UTzoydWFqEBjIC0rfZM+AXl5kDh9hUcsNpSmg==", + "_location": "/wxml-to-canvas", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "wxml-to-canvas", + "name": "wxml-to-canvas", + "escapedName": "wxml-to-canvas", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/wxml-to-canvas/-/wxml-to-canvas-1.1.1.tgz", + "_shasum": "64771473fb1e251bdad94f8c6ffa7dd64290e7ca", + "_spec": "wxml-to-canvas", + "_where": "/Users/WebTmm/Desktop/AGuestSaas", + "author": { + "name": "sanfordsun" + }, + "bundleDependencies": false, + "dependencies": { + "widget-ui": "^1.0.2" + }, + "deprecated": false, + "description": "[![](https://img.shields.io/npm/v/wxml-to-canvas)](https://www.npmjs.com/package/wxml-to-canvas) [![](https://img.shields.io/npm/l/wxml-to-canvas)](https://github.com/wechat-miniprogram/wxml-to-canvas)", + "devDependencies": { + "colors": "^1.3.1", + "eslint": "^5.14.1", + "eslint-config-airbnb-base": "13.1.0", + "eslint-loader": "^2.1.2", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-node": "^7.0.1", + "eslint-plugin-promise": "^3.8.0", + "gulp": "^4.0.0", + "gulp-clean": "^0.4.0", + "gulp-if": "^2.0.2", + "gulp-install": "^1.1.0", + "gulp-less": "^4.0.1", + "gulp-rename": "^1.4.0", + "gulp-sourcemaps": "^2.6.5", + "jest": "^23.5.0", + "miniprogram-simulate": "^1.0.0", + "through2": "^2.0.3", + "vinyl": "^2.2.0", + "webpack": "^4.29.5", + "webpack-cli": "^3.3.10", + "webpack-node-externals": "^1.7.2" + }, + "jest": { + "testEnvironment": "jsdom", + "testURL": "https://jest.test", + "collectCoverageFrom": [ + "src/**/*.js" + ], + "moduleDirectories": [ + "node_modules", + "src" + ] + }, + "license": "MIT", + "main": "miniprogram_dist/index.js", + "miniprogram": "miniprogram_dist", + "name": "wxml-to-canvas", + "repository": { + "type": "git", + "url": "" + }, + "scripts": { + "build": "gulp", + "clean": "gulp clean", + "clean-dev": "gulp clean --develop", + "coverage": "jest ./test/* --coverage --bail", + "dev": "gulp dev --develop", + "dist": "npm run build", + "lint": "eslint \"src/**/*.js\" --fix", + "lint-tools": "eslint \"tools/**/*.js\" --rule \"import/no-extraneous-dependencies: false\" --fix", + "test": "jest --bail", + "test-debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --bail", + "watch": "gulp watch --develop --watch" + }, + "version": "1.1.1" +} diff --git a/node_modules/wxml-to-canvas/src/draw.js b/node_modules/wxml-to-canvas/src/draw.js new file mode 100644 index 0000000..42e69c4 --- /dev/null +++ b/node_modules/wxml-to-canvas/src/draw.js @@ -0,0 +1,225 @@ +class Draw { + constructor(context, canvas, use2dCanvas = false) { + this.ctx = context + this.canvas = canvas || null + this.use2dCanvas = use2dCanvas + } + + roundRect(x, y, w, h, r, fill = true, stroke = false) { + if (r < 0) return + const ctx = this.ctx + + ctx.beginPath() + ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 3 / 2) + ctx.arc(x + w - r, y + r, r, Math.PI * 3 / 2, 0) + ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2) + ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI) + ctx.lineTo(x, y + r) + if (stroke) ctx.stroke() + if (fill) ctx.fill() + } + + drawView(box, style) { + const ctx = this.ctx + const { + left: x, top: y, width: w, height: h + } = box + const { + borderRadius = 0, + borderWidth = 0, + borderColor, + color = '#000', + backgroundColor = 'transparent', + } = style + ctx.save() + // 外环 + if (borderWidth > 0) { + ctx.fillStyle = borderColor || color + this.roundRect(x, y, w, h, borderRadius) + } + + // 内环 + ctx.fillStyle = backgroundColor + const innerWidth = w - 2 * borderWidth + const innerHeight = h - 2 * borderWidth + const innerRadius = borderRadius - borderWidth >= 0 ? borderRadius - borderWidth : 0 + this.roundRect(x + borderWidth, y + borderWidth, innerWidth, innerHeight, innerRadius) + ctx.restore() + } + + async drawImage(img, box, style) { + await new Promise((resolve, reject) => { + const ctx = this.ctx + const canvas = this.canvas + + const { + borderRadius = 0 + } = style + const { + left: x, top: y, width: w, height: h + } = box + ctx.save() + this.roundRect(x, y, w, h, borderRadius, false, false) + ctx.clip() + + const _drawImage = (img) => { + if (this.use2dCanvas) { + const Image = canvas.createImage() + Image.onload = () => { + ctx.drawImage(Image, x, y, w, h) + ctx.restore() + resolve() + } + Image.onerror = () => { reject(new Error(`createImage fail: ${img}`)) } + Image.src = img + } else { + ctx.drawImage(img, x, y, w, h) + ctx.restore() + resolve() + } + } + + const isTempFile = /^wxfile:\/\//.test(img) + const isNetworkFile = /^https?:\/\//.test(img) + + if (isTempFile) { + _drawImage(img) + } else if (isNetworkFile) { + wx.downloadFile({ + url: img, + success(res) { + if (res.statusCode === 200) { + _drawImage(res.tempFilePath) + } else { + reject(new Error(`downloadFile:fail ${img}`)) + } + }, + fail() { + reject(new Error(`downloadFile:fail ${img}`)) + } + }) + } else { + reject(new Error(`image format error: ${img}`)) + } + }) + } + + // eslint-disable-next-line complexity + drawText(text, box, style) { + const ctx = this.ctx + let { + left: x, top: y, width: w, height: h + } = box + let { + color = '#000', + lineHeight = '1.4em', + fontSize = 14, + textAlign = 'left', + verticalAlign = 'top', + backgroundColor = 'transparent' + } = style + + if (typeof lineHeight === 'string') { // 2em + lineHeight = Math.ceil(parseFloat(lineHeight.replace('em')) * fontSize) + } + if (!text || (lineHeight > h)) return + + ctx.save() + ctx.textBaseline = 'top' + ctx.font = `${fontSize}px sans-serif` + ctx.textAlign = textAlign + + // 背景色 + ctx.fillStyle = backgroundColor + this.roundRect(x, y, w, h, 0) + + // 文字颜色 + ctx.fillStyle = color + + // 水平布局 + switch (textAlign) { + case 'left': + break + case 'center': + x += 0.5 * w + break + case 'right': + x += w + break + default: break + } + + const textWidth = ctx.measureText(text).width + const actualHeight = Math.ceil(textWidth / w) * lineHeight + let paddingTop = Math.ceil((h - actualHeight) / 2) + if (paddingTop < 0) paddingTop = 0 + + // 垂直布局 + switch (verticalAlign) { + case 'top': + break + case 'middle': + y += paddingTop + break + case 'bottom': + y += 2 * paddingTop + break + default: break + } + + const inlinePaddingTop = Math.ceil((lineHeight - fontSize) / 2) + + // 不超过一行 + if (textWidth <= w) { + ctx.fillText(text, x, y + inlinePaddingTop) + return + } + + // 多行文本 + const chars = text.split('') + const _y = y + + // 逐行绘制 + let line = '' + for (const ch of chars) { + const testLine = line + ch + const testWidth = ctx.measureText(testLine).width + + if (testWidth > w) { + ctx.fillText(line, x, y + inlinePaddingTop) + y += lineHeight + line = ch + if ((y + lineHeight) > (_y + h)) break + } else { + line = testLine + } + } + + // 避免溢出 + if ((y + lineHeight) <= (_y + h)) { + ctx.fillText(line, x, y + inlinePaddingTop) + } + ctx.restore() + } + + async drawNode(element) { + const {layoutBox, computedStyle, name} = element + const {src, text} = element.attributes + if (name === 'view') { + this.drawView(layoutBox, computedStyle) + } else if (name === 'image') { + await this.drawImage(src, layoutBox, computedStyle) + } else if (name === 'text') { + this.drawText(text, layoutBox, computedStyle) + } + const childs = Object.values(element.children) + for (const child of childs) { + await this.drawNode(child) + } + } +} + + +module.exports = { + Draw +} diff --git a/node_modules/wxml-to-canvas/src/index.js b/node_modules/wxml-to-canvas/src/index.js new file mode 100644 index 0000000..ffa8834 --- /dev/null +++ b/node_modules/wxml-to-canvas/src/index.js @@ -0,0 +1,117 @@ + +const xmlParse = require('./xml-parser') +const {Widget} = require('./widget') +const {Draw} = require('./draw') +const {compareVersion} = require('./utils') + +const canvasId = 'weui-canvas' + +Component({ + properties: { + width: { + type: Number, + value: 400 + }, + height: { + type: Number, + value: 300 + } + }, + data: { + use2dCanvas: false, // 2.9.2 后可用canvas 2d 接口 + }, + lifetimes: { + attached() { + const {SDKVersion, pixelRatio: dpr} = wx.getSystemInfoSync() + const use2dCanvas = compareVersion(SDKVersion, '2.9.2') >= 0 + this.dpr = dpr + this.setData({use2dCanvas}, () => { + if (use2dCanvas) { + const query = this.createSelectorQuery() + query.select(`#${canvasId}`) + .fields({node: true, size: true}) + .exec(res => { + const canvas = res[0].node + const ctx = canvas.getContext('2d') + canvas.width = res[0].width * dpr + canvas.height = res[0].height * dpr + ctx.scale(dpr, dpr) + this.ctx = ctx + this.canvas = canvas + }) + } else { + this.ctx = wx.createCanvasContext(canvasId, this) + } + }) + } + }, + methods: { + async renderToCanvas(args) { + const {wxml, style} = args + const ctx = this.ctx + const canvas = this.canvas + const use2dCanvas = this.data.use2dCanvas + + if (use2dCanvas && !canvas) { + return Promise.reject(new Error('renderToCanvas: fail canvas has not been created')) + } + + ctx.clearRect(0, 0, this.data.width, this.data.height) + const {root: xom} = xmlParse(wxml) + + const widget = new Widget(xom, style) + const container = widget.init() + this.boundary = { + top: container.layoutBox.top, + left: container.layoutBox.left, + width: container.computedStyle.width, + height: container.computedStyle.height, + } + const draw = new Draw(ctx, canvas, use2dCanvas) + await draw.drawNode(container) + + if (!use2dCanvas) { + await this.canvasDraw(ctx) + } + return Promise.resolve(container) + }, + + canvasDraw(ctx, reserve) { + return new Promise(resolve => { + ctx.draw(reserve, () => { + resolve() + }) + }) + }, + + canvasToTempFilePath(args = {}) { + const use2dCanvas = this.data.use2dCanvas + + return new Promise((resolve, reject) => { + const { + top, left, width, height + } = this.boundary + + const copyArgs = { + x: left, + y: top, + width, + height, + destWidth: width * this.dpr, + destHeight: height * this.dpr, + canvasId, + fileType: args.fileType || 'png', + quality: args.quality || 1, + success: resolve, + fail: reject + } + + if (use2dCanvas) { + delete copyArgs.canvasId + copyArgs.canvas = this.canvas + } + wx.canvasToTempFilePath(copyArgs, this) + }) + } + } +}) diff --git a/node_modules/wxml-to-canvas/src/index.json b/node_modules/wxml-to-canvas/src/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/node_modules/wxml-to-canvas/src/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/node_modules/wxml-to-canvas/src/index.wxml b/node_modules/wxml-to-canvas/src/index.wxml new file mode 100644 index 0000000..a0010ad --- /dev/null +++ b/node_modules/wxml-to-canvas/src/index.wxml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/node_modules/wxml-to-canvas/src/index.wxss b/node_modules/wxml-to-canvas/src/index.wxss new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/wxml-to-canvas/src/utils.js b/node_modules/wxml-to-canvas/src/utils.js new file mode 100644 index 0000000..c3cf7d7 --- /dev/null +++ b/node_modules/wxml-to-canvas/src/utils.js @@ -0,0 +1,57 @@ +const hex = (color) => { + let result = null + + if (/^#/.test(color) && (color.length === 7 || color.length === 9)) { + return color + // eslint-disable-next-line no-cond-assign + } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) { + return '#' + result[2].split(',').map((part, index) => { + part = part.trim() + part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10) + part = part.toString(16) + if (part.length === 1) { + part = '0' + part + } + return part + }).join('') + } else { + return '#00000000' + } +} + +const splitLineToCamelCase = (str) => str.split('-').map((part, index) => { + if (index === 0) { + return part + } + return part[0].toUpperCase() + part.slice(1) +}).join('') + +const compareVersion = (v1, v2) => { + v1 = v1.split('.') + v2 = v2.split('.') + const len = Math.max(v1.length, v2.length) + while (v1.length < len) { + v1.push('0') + } + while (v2.length < len) { + v2.push('0') + } + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i], 10) + const num2 = parseInt(v2[i], 10) + + if (num1 > num2) { + return 1 + } else if (num1 < num2) { + return -1 + } + } + + return 0 +} + +module.exports = { + hex, + splitLineToCamelCase, + compareVersion +} diff --git a/node_modules/wxml-to-canvas/src/widget.js b/node_modules/wxml-to-canvas/src/widget.js new file mode 100644 index 0000000..af3ccc2 --- /dev/null +++ b/node_modules/wxml-to-canvas/src/widget.js @@ -0,0 +1,81 @@ +const Block = require('widget-ui') +const {splitLineToCamelCase} = require('./utils') + +class Element extends Block { + constructor(prop) { + super(prop.style) + this.name = prop.name + this.attributes = prop.attributes + } +} + + +class Widget { + constructor(xom, style) { + this.xom = xom + this.style = style + + this.inheritProps = ['fontSize', 'lineHeight', 'textAlign', 'verticalAlign', 'color'] + } + + init() { + this.container = this.create(this.xom) + this.container.layout() + + this.inheritStyle(this.container) + return this.container + } + + // 继承父节点的样式 + inheritStyle(node) { + const parent = node.parent || null + const children = node.children || {} + const computedStyle = node.computedStyle + + if (parent) { + this.inheritProps.forEach(prop => { + computedStyle[prop] = computedStyle[prop] || parent.computedStyle[prop] + }) + } + + Object.values(children).forEach(child => { + this.inheritStyle(child) + }) + } + + create(node) { + let classNames = (node.attributes.class || '').split(' ') + classNames = classNames.map(item => splitLineToCamelCase(item.trim())) + const style = {} + classNames.forEach(item => { + Object.assign(style, this.style[item] || {}) + }) + + const args = {name: node.name, style} + + const attrs = Object.keys(node.attributes) + const attributes = {} + for (const attr of attrs) { + const value = node.attributes[attr] + const CamelAttr = splitLineToCamelCase(attr) + + if (value === '' || value === 'true') { + attributes[CamelAttr] = true + } else if (value === 'false') { + attributes[CamelAttr] = false + } else { + attributes[CamelAttr] = value + } + } + attributes.text = node.content + args.attributes = attributes + const element = new Element(args) + node.children.forEach(childNode => { + const childElement = this.create(childNode) + element.add(childElement) + }) + return element + } +} + +module.exports = {Widget} diff --git a/node_modules/wxml-to-canvas/src/xml-parser.js b/node_modules/wxml-to-canvas/src/xml-parser.js new file mode 100644 index 0000000..de7526c --- /dev/null +++ b/node_modules/wxml-to-canvas/src/xml-parser.js @@ -0,0 +1,164 @@ + +/** + * Module dependencies. + */ + + +/** + * Expose `parse`. + */ + + +/** + * Parse the given string of `xml`. + * + * @param {String} xml + * @return {Object} + * @api public + */ + +function parse(xml) { + xml = xml.trim() + + // strip comments + xml = xml.replace(//g, '') + + return document() + + /** + * XML document. + */ + + function document() { + return { + declaration: declaration(), + root: tag() + } + } + + /** + * Declaration. + */ + + function declaration() { + const m = match(/^<\?xml\s*/) + if (!m) return + + // tag + const node = { + attributes: {} + } + + // attributes + while (!(eos() || is('?>'))) { + const attr = attribute() + if (!attr) return node + node.attributes[attr.name] = attr.value + } + + match(/\?>\s*/) + + return node + } + + /** + * Tag. + */ + + function tag() { + const m = match(/^<([\w-:.]+)\s*/) + if (!m) return + + // name + const node = { + name: m[1], + attributes: {}, + children: [] + } + + // attributes + while (!(eos() || is('>') || is('?>') || is('/>'))) { + const attr = attribute() + if (!attr) return node + node.attributes[attr.name] = attr.value + } + + // self closing tag + if (match(/^\s*\/>\s*/)) { + return node + } + + match(/\??>\s*/) + + // content + node.content = content() + + // children + let child + while (child = tag()) { + node.children.push(child) + } + + // closing + match(/^<\/[\w-:.]+>\s*/) + + return node + } + + /** + * Text content. + */ + + function content() { + const m = match(/^([^<]*)/) + if (m) return m[1] + return '' + } + + /** + * Attribute. + */ + + function attribute() { + const m = match(/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/) + if (!m) return + return {name: m[1], value: strip(m[2])} + } + + /** + * Strip quotes from `val`. + */ + + function strip(val) { + return val.replace(/^['"]|['"]$/g, '') + } + + /** + * Match `re` and advance the string. + */ + + function match(re) { + const m = xml.match(re) + if (!m) return + xml = xml.slice(m[0].length) + return m + } + + /** + * End-of-source. + */ + + function eos() { + return xml.length == 0 + } + + /** + * Check for `prefix`. + */ + + function is(prefix) { + return xml.indexOf(prefix) == 0 + } +} + +module.exports = parse diff --git a/package-lock.json b/package-lock.json index 83cfb72..baff0ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,27 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@miniprogram-component-plus/video-swiper/-/video-swiper-1.0.1.tgz", "integrity": "sha512-1rlmsS3/TR0Zu0nZHwEwb9UCQWY/ofPv73zU56FLfZh72Xw+BcIzfohrDxrGs5QpoL4KCLl9G7UB5w+3ZRSZzQ==" + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "widget-ui": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/widget-ui/-/widget-ui-1.0.2.tgz", + "integrity": "sha512-gDXosr5mflJdMA1weU1A47aTsTFfMJhfA4EKgO5XFebY3eVklf80KD4GODfrjo8J2WQ+9YjL1Rd9UUmKIzhShw==", + "requires": { + "eventemitter3": "^4.0.0" + } + }, + "wxml-to-canvas": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/wxml-to-canvas/-/wxml-to-canvas-1.1.1.tgz", + "integrity": "sha512-3mDjHzujY/UgdCOXij/MnmwJYerVjwkyQHMBFBE8zh89DK7h7UTzoydWFqEBjIC0rfZM+AXl5kDh9hUcsNpSmg==", + "requires": { + "widget-ui": "^1.0.2" + } } } } diff --git a/package.json b/package.json index 8b6ff59..2ce1222 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "author": "", "license": "ISC", "dependencies": { - "@miniprogram-component-plus/video-swiper": "^1.0.1" + "@miniprogram-component-plus/video-swiper": "^1.0.1", + "wxml-to-canvas": "^1.1.1" } }