diff --git a/.gitignore b/.gitignore index 87b8260..b9921a6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /.git *.log project.private.config.json -project.config.json \ No newline at end of file +project.config.json +node_modules diff --git a/.vscode/settings.json b/.vscode/settings.json index a13afba..eeaca69 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,6 @@ "*.wxss": "css", "*.tpl": "html", "*.vue": "vue", - "*.wxml": "html" + "*.wxml": "wxml" } } \ No newline at end of file diff --git a/miniprogram_npm/widget-ui/index.js b/miniprogram_npm/widget-ui/index.js deleted file mode 100644 index 465c8a3..0000000 --- a/miniprogram_npm/widget-ui/index.js +++ /dev/null @@ -1,13 +0,0 @@ -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__(1744354687963, 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 deleted file mode 100644 index e8cfaaf..0000000 --- a/miniprogram_npm/wxml-to-canvas/index.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "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 deleted file mode 100644 index a0010ad..0000000 --- a/miniprogram_npm/wxml-to-canvas/index.wxml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/miniprogram_npm/wxml-to-canvas/index.wxss b/miniprogram_npm/wxml-to-canvas/index.wxss deleted file mode 100644 index e69de29..0000000 diff --git a/miniprogram_npm/wxml-to-canvas/utils.js b/miniprogram_npm/wxml-to-canvas/utils.js deleted file mode 100644 index c3cf7d7..0000000 --- a/miniprogram_npm/wxml-to-canvas/utils.js +++ /dev/null @@ -1,57 +0,0 @@ -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/.store/node_modules/widget-ui/package.json b/node_modules/.store/node_modules/widget-ui/package.json index a4bcb29..8cc504b 100644 --- a/node_modules/.store/node_modules/widget-ui/package.json +++ b/node_modules/.store/node_modules/widget-ui/package.json @@ -23,8 +23,5 @@ "typescript": "^3.6.4", "webpack": "^4.41.1", "webpack-cli": "^3.3.9" - }, - "__npminstall_done": true, - "_from": "widget-ui@1.0.2", - "_resolved": "https://registry.npmmirror.com/widget-ui/-/widget-ui-1.0.2.tgz" + } } diff --git a/node_modules/.store/widget-ui@1.0.2/node_modules/widget-ui/package.json b/node_modules/.store/widget-ui@1.0.2/node_modules/widget-ui/package.json index a4bcb29..8cc504b 100644 --- a/node_modules/.store/widget-ui@1.0.2/node_modules/widget-ui/package.json +++ b/node_modules/.store/widget-ui@1.0.2/node_modules/widget-ui/package.json @@ -23,8 +23,5 @@ "typescript": "^3.6.4", "webpack": "^4.41.1", "webpack-cli": "^3.3.9" - }, - "__npminstall_done": true, - "_from": "widget-ui@1.0.2", - "_resolved": "https://registry.npmmirror.com/widget-ui/-/widget-ui-1.0.2.tgz" + } } diff --git a/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/widget-ui/package.json b/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/widget-ui/package.json index a4bcb29..8cc504b 100644 --- a/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/widget-ui/package.json +++ b/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/widget-ui/package.json @@ -23,8 +23,5 @@ "typescript": "^3.6.4", "webpack": "^4.41.1", "webpack-cli": "^3.3.9" - }, - "__npminstall_done": true, - "_from": "widget-ui@1.0.2", - "_resolved": "https://registry.npmmirror.com/widget-ui/-/widget-ui-1.0.2.tgz" + } } diff --git a/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/wxml-to-canvas/package.json b/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/wxml-to-canvas/package.json index a6da88c..7b55de5 100644 --- a/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/wxml-to-canvas/package.json +++ b/node_modules/.store/wxml-to-canvas@1.1.1/node_modules/wxml-to-canvas/package.json @@ -59,8 +59,5 @@ }, "dependencies": { "widget-ui": "^1.0.2" - }, - "__npminstall_done": true, - "_from": "wxml-to-canvas@1.1.1", - "_resolved": "https://registry.npmmirror.com/wxml-to-canvas/-/wxml-to-canvas-1.1.1.tgz" + } } diff --git a/node_modules/widget-ui/babel.config.js b/node_modules/widget-ui/babel.config.js deleted file mode 100644 index 329c912..0000000 --- a/node_modules/widget-ui/babel.config.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - presets: [ - ["@babel/preset-env", { - targets: { - node: "current" - } - }] - ] -}; \ No newline at end of file diff --git a/node_modules/widget-ui/dist/element.d.ts b/node_modules/widget-ui/dist/element.d.ts deleted file mode 100644 index f20c809..0000000 --- a/node_modules/widget-ui/dist/element.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -declare type LayoutData = { - left: number; - top: number; - width: number; - height: number; -}; -declare type LayoutNode = { - id: number; - style: Object; - children: LayoutNode[]; - layout?: LayoutData; -}; -declare class Element { - static uuid(): number; - parent: Element | null; - id: number; - style: { - [key: string]: any; - }; - computedStyle: { - [key: string]: any; - }; - lastComputedStyle: { - [key: string]: any; - }; - children: { - [key: string]: Element; - }; - layoutBox: LayoutData; - constructor(style?: { - [key: string]: any; - }); - getAbsolutePosition(element: Element): any; - add(element: Element): void; - remove(element?: Element): void; - getNodeTree(): LayoutNode; - applyLayout(layoutNode: LayoutNode): void; - layout(): void; -} -export default Element; diff --git a/node_modules/widget-ui/dist/event.d.ts b/node_modules/widget-ui/dist/event.d.ts deleted file mode 100644 index 41c27bb..0000000 --- a/node_modules/widget-ui/dist/event.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default class EventEmitter { - emit(event: string, data?: any): void; - on(event: string, callback: any): void; - off(event: string, callback: any): void; -} diff --git a/node_modules/widget-ui/dist/index.js b/node_modules/widget-ui/dist/index.js deleted file mode 100644 index 476df65..0000000 --- a/node_modules/widget-ui/dist/index.js +++ /dev/null @@ -1 +0,0 @@ -!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){"use strict";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){"use strict";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 { - 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 deleted file mode 100644 index 6f625b8..0000000 --- a/node_modules/widget-ui/jest.config.js +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index a4bcb29..0000000 --- a/node_modules/widget-ui/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "widget-ui", - "version": "1.0.2", - "description": "", - "main": "dist/index.js", - "scripts": { - "test": "jest", - "build": "webpack" - }, - "author": "", - "license": "ISC", - "dependencies": { - "eventemitter3": "^4.0.0" - }, - "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" - }, - "__npminstall_done": true, - "_from": "widget-ui@1.0.2", - "_resolved": "https://registry.npmmirror.com/widget-ui/-/widget-ui-1.0.2.tgz" -} diff --git a/node_modules/widget-ui/src/css-layout.js b/node_modules/widget-ui/src/css-layout.js deleted file mode 100644 index dc91c7e..0000000 --- a/node_modules/widget-ui/src/css-layout.js +++ /dev/null @@ -1,1186 +0,0 @@ -/* 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 deleted file mode 100644 index 08dbd0e..0000000 --- a/node_modules/widget-ui/src/element.ts +++ /dev/null @@ -1,172 +0,0 @@ - -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 deleted file mode 100644 index 640ab61..0000000 --- a/node_modules/widget-ui/src/event.ts +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index 2205c63..0000000 --- a/node_modules/widget-ui/src/style.ts +++ /dev/null @@ -1,87 +0,0 @@ -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 deleted file mode 100644 index 1e0c6c3..0000000 --- a/node_modules/widget-ui/test/css-layout.test.ts +++ /dev/null @@ -1,183 +0,0 @@ - -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 deleted file mode 100644 index 9bd5d37..0000000 --- a/node_modules/widget-ui/tsconfig.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "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 deleted file mode 100644 index e115980..0000000 --- a/node_modules/widget-ui/tslint.json +++ /dev/null @@ -1,206 +0,0 @@ -{ - "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 deleted file mode 100644 index 908b376..0000000 --- a/node_modules/widget-ui/webpack.config.js +++ /dev/null @@ -1,25 +0,0 @@ -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 deleted file mode 100644 index c062b77..0000000 --- a/node_modules/wxml-to-canvas/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "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 deleted file mode 100644 index 6576a30..0000000 --- a/node_modules/wxml-to-canvas/.eslintrc.js +++ /dev/null @@ -1,99 +0,0 @@ -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 deleted file mode 100644 index 3617210..0000000 --- a/node_modules/wxml-to-canvas/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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 deleted file mode 100644 index 8ee64df..0000000 --- a/node_modules/wxml-to-canvas/README.md +++ /dev/null @@ -1,187 +0,0 @@ -# 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 deleted file mode 100644 index fb292c2..0000000 --- a/node_modules/wxml-to-canvas/gulpfile.js +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index 2a4f21e..0000000 --- a/node_modules/wxml-to-canvas/miniprogram_dist/index.js +++ /dev/null @@ -1,779 +0,0 @@ -(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 deleted file mode 100644 index e8cfaaf..0000000 --- a/node_modules/wxml-to-canvas/miniprogram_dist/index.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "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 deleted file mode 100644 index a0010ad..0000000 --- a/node_modules/wxml-to-canvas/miniprogram_dist/index.wxml +++ /dev/null @@ -1,2 +0,0 @@ - - \ 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 deleted file mode 100644 index e69de29..0000000 diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/utils.js b/node_modules/wxml-to-canvas/miniprogram_dist/utils.js deleted file mode 100644 index c3cf7d7..0000000 --- a/node_modules/wxml-to-canvas/miniprogram_dist/utils.js +++ /dev/null @@ -1,57 +0,0 @@ -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 deleted file mode 100644 index a6da88c..0000000 --- a/node_modules/wxml-to-canvas/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "wxml-to-canvas", - "version": "1.1.1", - "description": "", - "main": "miniprogram_dist/index.js", - "scripts": { - "dev": "gulp dev --develop", - "watch": "gulp watch --develop --watch", - "build": "gulp", - "dist": "npm run build", - "clean-dev": "gulp clean --develop", - "clean": "gulp clean", - "test": "jest --bail", - "test-debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --bail", - "coverage": "jest ./test/* --coverage --bail", - "lint": "eslint \"src/**/*.js\" --fix", - "lint-tools": "eslint \"tools/**/*.js\" --rule \"import/no-extraneous-dependencies: false\" --fix" - }, - "miniprogram": "miniprogram_dist", - "jest": { - "testEnvironment": "jsdom", - "testURL": "https://jest.test", - "collectCoverageFrom": [ - "src/**/*.js" - ], - "moduleDirectories": [ - "node_modules", - "src" - ] - }, - "repository": { - "type": "git", - "url": "" - }, - "author": "sanfordsun", - "license": "MIT", - "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" - }, - "dependencies": { - "widget-ui": "^1.0.2" - }, - "__npminstall_done": true, - "_from": "wxml-to-canvas@1.1.1", - "_resolved": "https://registry.npmmirror.com/wxml-to-canvas/-/wxml-to-canvas-1.1.1.tgz" -} diff --git a/node_modules/wxml-to-canvas/src/draw.js b/node_modules/wxml-to-canvas/src/draw.js deleted file mode 100644 index 42e69c4..0000000 --- a/node_modules/wxml-to-canvas/src/draw.js +++ /dev/null @@ -1,225 +0,0 @@ -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 deleted file mode 100644 index ffa8834..0000000 --- a/node_modules/wxml-to-canvas/src/index.js +++ /dev/null @@ -1,117 +0,0 @@ - -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 deleted file mode 100644 index e8cfaaf..0000000 --- a/node_modules/wxml-to-canvas/src/index.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "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 deleted file mode 100644 index a0010ad..0000000 --- a/node_modules/wxml-to-canvas/src/index.wxml +++ /dev/null @@ -1,2 +0,0 @@ - - \ 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 deleted file mode 100644 index e69de29..0000000 diff --git a/node_modules/wxml-to-canvas/src/utils.js b/node_modules/wxml-to-canvas/src/utils.js deleted file mode 100644 index c3cf7d7..0000000 --- a/node_modules/wxml-to-canvas/src/utils.js +++ /dev/null @@ -1,57 +0,0 @@ -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 deleted file mode 100644 index af3ccc2..0000000 --- a/node_modules/wxml-to-canvas/src/widget.js +++ /dev/null @@ -1,81 +0,0 @@ -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 deleted file mode 100644 index de7526c..0000000 --- a/node_modules/wxml-to-canvas/src/xml-parser.js +++ /dev/null @@ -1,164 +0,0 @@ - -/** - * 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 new file mode 100644 index 0000000..0dfa8db --- /dev/null +++ b/package-lock.json @@ -0,0 +1,22 @@ +{ + "name": "小程序 - 租房", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/.store/eventemitter3@4.0.7/node_modules/eventemitter3": { + "version": "4.0.7", + "extraneous": true, + "license": "MIT", + "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" + } + } + } +} diff --git a/package.json b/package.json index e040d32..0967ef4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1 @@ -{ - "dependencies": { - "widget-ui": "^1.0.2", - "wxml-to-canvas": "^1.1.1" - } -} +{} diff --git a/pages/brandApartmentDetail/brandApartmentDetail.js b/pages/brandApartmentDetail/brandApartmentDetail.js index a54bfad..b859e67 100644 --- a/pages/brandApartmentDetail/brandApartmentDetail.js +++ b/pages/brandApartmentDetail/brandApartmentDetail.js @@ -66,6 +66,8 @@ Page({ isShowVideo: true, // 是否显示 视频 + shareImage: "", // 分享图片链接 + }, timer: null, headHeight: 0, @@ -174,13 +176,20 @@ Page({ // 来自页面内转发按钮 if (res.from === 'button') var types = res.from === 'button' ? 'share_btn' : 'show'; - let that = this; - var title = that.data.data.title; - if (that.data.data.isquarantine) title = this.data.listTab.quarantineLists + '-' + that.data.data.title + // let that = this; + // var title = that.data.data.title; + // if (that.data.data.isquarantine) title = this.data.listTab.quarantineLists + '-' + that.data.data.title + + const data = this.data.data + + let title = ""; + if (data.sharetitle) title = '香港租房 | ' + data.sharetitle + else title = '香港租房 | ' + data.title return { title, - imageUrl: that.data.data.thumbnail, + // imageUrl: that.data.data.thumbnail, + imageUrl: this.data.shareImage || '', success: function (res) { miucms.share(app, types) }, @@ -188,13 +197,16 @@ Page({ }, onShareTimeline() { - let that = this; - var title = that.data.data.title; - if (that.data.data.isquarantine) title = this.data.listTab.quarantineLists + '-' + that.data.data.title + const data = this.data.data + let title = ""; + if (data.sharetitle) title = '香港租房 | ' + data.sharetitle + else title = '香港租房 | ' + data.title + + // if (that.data.data.isquarantine) title = this.data.listTab.quarantineLists + '-' + that.data.data.title return { title, - imageUrl: that.data.data.thumbnail, + imageUrl: this.data.shareImage || '', } }, @@ -294,16 +306,8 @@ Page({ isloding: false }) - this.widget = this.selectComponent('.widget') - console.log(this.widget); - setTimeout(() => { - this.setwidget() - }, 800) - if (data.withsameapartments > 0) this.getList() - // this.handleSwiperInit() - this.drawPoster() } }).catch(res => { @@ -321,302 +325,27 @@ Page({ }) }, - setwidget() { - wx.getImageInfo({ - src: "https://oss.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-T9pwkfHvqqsgFptxhXa6QWi2uePJ5Bg8cFLPIqoYV7MsLCmeW5lr_-kU8uRQ0NDI5", - success: res => { - console.log("res", res.path); + drawPoster() { + const user = app.globalData.user + const data = this.data.data + const roomList = this.data.roomList || [] + let title = `${ roomList.length > 1 ? '多房型' : '' }` - let wxml = ` - - - 肖荣豪 为你推荐 - + const price = Math.min(...roomList.map(item => item.price)); + title += ` HK$${ price }起` - - - - 香港 | 多房型 HK$5600起 - - - - ` - - - let style = { - placard: { - width: "210", - height: "158", - position: "relative", - // paddingTop: "3", - backgroundColor: "azure" - }, - placardBj: { - width: "210", - height: "155", - borderRadius: 10, - position: "absolute", - top: 3, - - }, - placardTag: { - position: "absolute", - top: 0, - right: 0, - width: 40, - height: 33, - }, - placardInfo: { - height: 22, - // borderRadius: "0 50px 50px 0", - position: "absolute", - top: 15, - left: 0, - backgroundColor: "#f2f2f2", - width: 156, - color: '#fff', - - // display: flex, - // alignItems: "center", - // fontSize: 10, - // padding-right: 10, - }, - text: { - // width: 80, - height: 60, - color: "#000000", - fontSize: 14, - }, - // position: { - // position: 'absolute', - // bottom: 0, - // left: 0, - // width: '210px', - // height: '26px', - // backgroundColor: 'rgba(0, 0, 0, 0.3)', - // color: '#fff', - // display: 'flex', - // alignItems: 'center', - // padding: '0 4px', - // fontSize: '11px', - // borderRadius: '0 0 10px 10px', - // }, - // positionIcon: { - // width: '10px', - // height: '14px', - // marginRight: '4px', - // }, - // positionText: { - // flex: 1, - // fontFamily: 'microsoft yahei', - // }, - // positionArrow: { - // width: '12px', - // height: '12px', - // } - } - - - console.log(this.widget); - const p1 = this.widget.renderToCanvas({ - wxml, - style - }) - console.log("p1", p1); - p1.then((res) => { - console.log('container', res) - this.container = res - }).catch(err => { - console.log("err", err); - }) - - const p2 = this.widget.canvasToTempFilePath() - p2.then(res => { - console.log("res.tempFilePath", res.tempFilePath); - this.setData({ - src: res.tempFilePath, - width: 100, - height: 100 - }) - }) - - } - }) - }, - - async drawPoster() { + const bj = data.attachment?.[0] || data.videos?.[0]?.thumbnail || data.attachment?.[0] return - - const canvas = wx.createOffscreenCanvas({ - type: '2d', - width: 210, - height: 168 - }); - const ctx = canvas.getContext('2d'); - - // 绘制圆角路径 - const radius = 10; - const width = 210; - const height = 168; - ctx.beginPath(); - ctx.moveTo(radius, 0); - ctx.lineTo(width - radius, 0); - ctx.quadraticCurveTo(width, 0, width, radius); - ctx.lineTo(width, height - radius); - ctx.quadraticCurveTo(width, height, width - radius, height); - ctx.lineTo(radius, height); - ctx.quadraticCurveTo(0, height, 0, height - radius); - ctx.lineTo(0, radius); - ctx.quadraticCurveTo(0, 0, radius, 0); - ctx.closePath(); - ctx.clip(); - // 绘制背景 - let bgImg = canvas.createImage(); - // 等待图片加载 - const backImg = "https://oss.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-T9pwkfHvqqsgFptxhXa6QWi2uePJ5Bg8cFLPIqoYV7MsLCmeW5lr_-kU8uRQ0NDI5" - await new Promise(resolve => { - bgImg.onload = resolve; - bgImg.src = backImg; // 要加载的图片 url - }) - console.log(11); - ctx.drawImage(bgImg, 0, 10, 210, 158); - // 绘制二维码 - let mycode = canvas.createImage(); - // 等待图片加载 - const promoImg = "https://app.gter.net/image/miniApp/HKRenting/high-quality-tag.png" - await new Promise(resolve => { - mycode.onload = resolve; - mycode.src = promoImg; // 要加载的图片 url - }) - - console.log(12); - - // 创建二维码圆形 - ctx.save(); - ctx.drawImage(mycode, 165, -0, 48, 40); - ctx.restore(); - - // ctx.arc(568, 524, 120, 0, 2 * Math.PI); - // ctx.clip(); - // ctx.fillStyle = "#FFF"; - // ctx.fill(); - // ctx.drawImage(mycode, 458, 414, 220, 220); - // ctx.restore(); - - const imgData = canvas.toDataURL(); - const time = new Date().getTime(); - const filePath = wx.env.USER_DATA_PATH + "/poster" + time + "share" + ".png"; - - const fs = wx.getFileSystemManager(); - console.log("imgData", imgData); - this.setData({ - imgData - }) - // wx.getImageInfo({ - // src: imgData, - // success(res) { - // console.log(res.width) - // console.log(res.height) - // } - // }) - // fs.writeFile({ - // filePath, - // data: imgData.replace(/^data:image\/\w+;base64,/, ""), - // encoding: 'base64', - // success: res => { - // console.log("filePath", filePath); - // wx.showShareImageMenu({ - // path: filePath, - // success: res => { - // console.log(res); - // } - // }) - // }, - // fail: err => { - // // 此处可能存在内存满了的情况 - // // 需要根据具体需求处理 - // console.log(err); - // } - // }); - // fs.close(); - - }, - - generateShareImage() { - - const screenWidth = this.data.screenWidth - console.log("screenWidth", screenWidth); - - // / 创建离屏 2D canvas 实例 - const canvas = wx.createOffscreenCanvas({ - type: '2d', - width: 300, - height: 150 - }) - // 获取 context。注意这里必须要与创建时的 type 一致 - const context = canvas.getContext('2d') - - // 创建一个图片 - const image = canvas.createImage() - // 等待图片加载 - new Promise(resolve => { - image.onload = resolve - image.src = '/img/apartment-bottom.png' // 要加载的图片 url - }) - - // 把图片画到离屏 canvas 上 - context.clearRect(0, 0, 300, 150) - context.drawImage(image, 0, 0, 300, 150) - - // 获取画完后的数据 - const imgData = context.getImageData(0, 0, 300, 150) - console.log("imgData", imgData); - - - // 获取视图层Canvas - const query = wx.createSelectorQuery(); - query.select('#displayCanvas') - .fields({ - node: true, - size: true + miucms.generatePoster({ + bj, + title, + type: 1, + }).then(res => { + this.setData({ + shareImage: res }) - .exec((res) => { - const displayCanvas = res[0].node; - const displayCtx = displayCanvas.getContext('2d'); - - // 绘制imgData到视图层Canvas - displayCtx.putImageData(imgData, 0, 0); - - // 将视图层Canvas内容转换为临时文件路径 - wx.canvasToTempFilePath({ - canvas: displayCanvas, - success: (res) => { - const imagePath = res.tempFilePath; - - // 更新页面数据,显示图片 - this.setData({ - imagePath: imagePath - }); - }, - fail: (err) => { - console.error('转换失败:', err); - } - }); - }); - - - // return - // wx.createSelectorQuery().select('#cvs1').node(res => { - // console.log('select canvas', res) - // const ctx1 = res.node.getContext('2d') - // res.node.width = screenWidth - // res.node.height = screenWidth - - // setInterval(() => { - // ctx1.drawImage(video, 0, 0, w * dpr, h * dpr); - // }, 1000 / 24) - // }).exec() - + console.log("shareImage", this.data.shareImage); + }) }, getList() { diff --git a/pages/brandApartmentDetail/brandApartmentDetail.json b/pages/brandApartmentDetail/brandApartmentDetail.json index 4492227..6e7642e 100644 --- a/pages/brandApartmentDetail/brandApartmentDetail.json +++ b/pages/brandApartmentDetail/brandApartmentDetail.json @@ -6,7 +6,6 @@ "go-login": "../../template/goLogin/goLogin", "report": "../../template/report/report", "head-swiper": "../../template/headSwiper/headSwiper", - "nearby-school": "/template/nearbySchool/nearbySchool", - "wxml-to-canvas": "wxml-to-canvas" + "nearby-school": "/template/nearbySchool/nearbySchool" } } \ No newline at end of file diff --git a/pages/brandApartmentDetail/brandApartmentDetail.less b/pages/brandApartmentDetail/brandApartmentDetail.less index 2db8359..b65dc3c 100644 --- a/pages/brandApartmentDetail/brandApartmentDetail.less +++ b/pages/brandApartmentDetail/brandApartmentDetail.less @@ -1264,77 +1264,4 @@ map .clickmap { .bottom-bar .bottom-bar-share::after { border: none; height: 0; -} - -.placard { - width: 210px; - height: 158px; - position: relative; - padding-top: 3px; - - .placard-bj { - width: 210px; - height: 155px; - border-radius: 10px; - } - - .placard-tag { - position: absolute; - top: 0; - right: 0; - width: 40px; - height: 33px; - } - - .placard-info { - height: 22px; - border-radius: 0 50px 50px 0; - position: absolute; - top: 15px; - left: 0; - background-color: rgba(242, 242, 242, 1); - display: flex; - align-items: center; - font-size: 10px; - padding-right: 10px; - - .avatar { - width: 20px; - height: 20px; - border-radius: 50%; - margin-left: 2px; - margin-right: 4px; - } - } - - .position { - position: absolute; - bottom: 0; - left: 0; - width: 210px; - height: 26px; - background-color: rgba(0, 0, 0, 0.3); - color: #fff; - display: flex; - align-items: center; - padding: 0 4px; - font-size: 11px; - border-radius: 0 0 10px 10px; - - .position-icon { - width: 10px; - height: 14px; - margin-right: 4px; - } - - .position-text { - flex: 1; - font-family: 'microsoft yahei'; - } - - .position-arrow { - width: 12px; - height: 12px; - } - } } \ No newline at end of file diff --git a/pages/brandApartmentDetail/brandApartmentDetail.wxml b/pages/brandApartmentDetail/brandApartmentDetail.wxml index aef36d5..fadd4cb 100644 --- a/pages/brandApartmentDetail/brandApartmentDetail.wxml +++ b/pages/brandApartmentDetail/brandApartmentDetail.wxml @@ -4,26 +4,6 @@ 公寓详情 - - - - - - - - 肖荣豪 为你推荐 - - - - - - 香港 | 多房型 HK$5600起 - - - - - - @@ -192,11 +172,11 @@ - + + @@ -241,7 +243,7 @@ 发布者的其他{{ info['intermediary'] == 1 ? '' : '认证' }}房源({{ attestationElseResource.length }}) - + diff --git a/pages/show/show1.less b/pages/show/show1.less index e69de29..a9a690e 100644 --- a/pages/show/show1.less +++ b/pages/show/show1.less @@ -0,0 +1,4 @@ +.shareImage { + width: 280px; + height: 224px; +} \ No newline at end of file diff --git a/pages/show/show1.wxss b/pages/show/show1.wxss index e69de29..87d4ab1 100644 --- a/pages/show/show1.wxss +++ b/pages/show/show1.wxss @@ -0,0 +1,4 @@ +.shareImage { + width: 280px; + height: 224px; +} diff --git a/utils/miucms.js b/utils/miucms.js index 87c68c4..1624083 100644 --- a/utils/miucms.js +++ b/utils/miucms.js @@ -1,40 +1,55 @@ -var initial_url = 'https://app.gter.net/tenement'; +var initial_url = "https://app.gter.net/tenement"; var app = null; function initial(self) { + const fs = wx.getFileSystemManager(); + console.log("getCurrentDate", getCurrentDate()); + fs.mkdir({ + // dirPath: `${wx.env.USER_DATA_PATH}/${getCurrentDate()}`, + dirPath: `${wx.env.USER_DATA_PATH}/2025-04-13`, + success(res) { + console.log("res", res); + }, + fail(err) { + console.log("err", err); + }, + }); + fs.close(); + app = self; getUserInfo(function (code) { - sendData(code) + sendData(code); self.globalData.code = code; }); + return true; } function sendData(code) { - let Authorization = wx.getStorageSync('Authorization') + let Authorization = wx.getStorageSync("Authorization"); if (!Authorization) { - Authorization = app.randomString(32) - wx.setStorageSync('Authorization', Authorization) - wx.setStorageSync('session', Authorization) + Authorization = app.randomString(32); + wx.setStorageSync("Authorization", Authorization); + wx.setStorageSync("session", Authorization); } wx.request({ url: initial_url, data: { - session: wx.getStorageSync('Authorization') || "", - Authorization: wx.getStorageSync('Authorization') || "", + session: wx.getStorageSync("Authorization") || "", + Authorization: wx.getStorageSync("Authorization") || "", code: code, - options: app.globalData.options || '', + options: app.globalData.options || "", }, - method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT + method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT header: { - 'content-type': 'application/json', - 'Accept': 'application/json, text/plain', - 'Cookie': 'miucms_session=' + wx.getStorageSync('Authorization'), - 'Authorization': wx.getStorageSync('Authorization') || '' + "content-type": "application/json", + Accept: "application/json, text/plain", + Cookie: "miucms_session=" + wx.getStorageSync("Authorization"), + Authorization: wx.getStorageSync("Authorization") || "", }, success: function (res) { - var data = typeof res.data == 'string' ? JSON.parse(res.data) : res.data; - bindingUser(data.user || {}) + var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data; + bindingUser(data.user || {}); // 将配置与用户session存于本地 // if (!data.session) { @@ -63,54 +78,55 @@ function sendData(code) { app.globalData.popwindow = data.popwindow; app.globalData.header = { - 'content-type': 'application/json', - 'Accept': 'application/json, text/plain', - 'Cookie': 'miucms_session=' + wx.getStorageSync('Authorization'), - 'Authorization': wx.getStorageSync('Authorization') || '' + "content-type": "application/json", + Accept: "application/json, text/plain", + Cookie: "miucms_session=" + wx.getStorageSync("Authorization"), + Authorization: wx.getStorageSync("Authorization") || "", }; // count() - app.globalData.offerkaipingadvertisement = data.popup || {} - const openAdTimer = wx.getStorageSync("openAdTimer") - if (openAdTimer && isToday(openAdTimer)) app.globalData.offerkaipingadvertisementState = true - + app.globalData.offerkaipingadvertisement = data.popup || {}; + const openAdTimer = wx.getStorageSync("openAdTimer"); + if (openAdTimer && isToday(openAdTimer)) app.globalData.offerkaipingadvertisementState = true; }, fail: function () { // fail }, complete: function () { // complete - useSocket() - } - }) + useSocket(); + }, + }); } function isToday(timestamp) { - const date = new Date(timestamp) - const today = new Date() + const date = new Date(timestamp); + const today = new Date(); - return date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === today.getDate() + return date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === today.getDate(); } // 发送未读消息数请求 function count() { return new Promise((resolve, reject) => { - request(app.globalData.baseURL + "/tenement/message/count").then(res => { - if (res.code == 200) { - app.globalData['unreadMessages'] = res.data.count - app.globalData['unreadMessagesState'] = true - } else { - wx.showModal({ - title: '提示', - content: res.message - }) - } - resolve(res) - }).catch(error => { - reject(error) - }) - }) + request(app.globalData.baseURL + "/tenement/message/count") + .then((res) => { + if (res.code == 200) { + app.globalData["unreadMessages"] = res.data.count; + app.globalData["unreadMessagesState"] = true; + } else { + wx.showModal({ + title: "提示", + content: res.message, + }); + } + resolve(res); + }) + .catch((error) => { + reject(error); + }); + }); } // 发送验证码 @@ -120,125 +136,128 @@ function verify() { // 验证验证码并注册 function register(o) { - var config = wx.getStorageSync('config') + var config = wx.getStorageSync("config"); var self = this; wx.request({ url: config.user.register, data: { - session: wx.getStorageSync('session'), - data: wx.getStorageSync('rawData'), + session: wx.getStorageSync("session"), + data: wx.getStorageSync("rawData"), uniqid: null, //上一步获取的ID code: null, //接收到的验证码 }, - method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT + method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT header: { - 'content-type': 'application/json', - 'Accept': 'application/json, text/plain' + "content-type": "application/json", + Accept: "application/json, text/plain", }, success: function (res) { - var data = typeof res.data == 'string' ? JSON.parse(res.data) : res.data; - console.log('登录/注册成功') - initial(initial_url, app) + var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data; + console.log("登录/注册成功"); + initial(initial_url, app); }, fail: function () { // fail }, complete: function () { // complete - } - }) + }, + }); } - //用户登录 function login() { - return new Promise((resolve, reject) => wx.login({ - success: resolve, - fail: reject - })) + return new Promise((resolve, reject) => + wx.login({ + success: resolve, + fail: reject, + }) + ); } //获取用户信息 function getUserInfo(o) { - login().then(res => { - var code = res.code; - o(code); - }).catch(res => { - console.log(res) - }) + login() + .then((res) => { + var code = res.code; + o(code); + }) + .catch((res) => { + console.log(res); + }); } function share(app, name) { if (!app.globalData.config.stat || !app.globalData.config.stat.share) { - return false + return false; } wx.request({ url: app.globalData.config.stat.share, data: { - page: name + page: name, }, - method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT + method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT header: app.globalData.header, success: function (res) {}, fail: function (res) {}, - }) + }); } function html2wxml(str, index, that) { var arr = []; - if (str.indexOf('') != -1) { + if (str.indexOf("") != -1) { // 有a标签 that.data.newFunction.text[index].push({ - text: str.substring(0, str.indexOf('')); - var text1 = rest.substring(1, rest.indexOf('')) + var href = rest.substring(href1, href1 + href2); + rest = rest.substring(rest.indexOf(">")); + var text1 = rest.substring(1, rest.indexOf("")); that.data.newFunction.text[index].push({ text: text1, - node: 'a', - href: href - }) - rest = rest.substring(rest.indexOf('') + 4) + node: "a", + href: href, + }); + rest = rest.substring(rest.indexOf("") + 4); if (rest.length > 0) { // a标签后还有字符串 - if (rest.indexOf('') != -1) { + if (rest.indexOf("") != -1) { // 还有A标签存在,再一次调用 - that.html2wxml(rest, index) + that.html2wxml(rest, index); } else { that.data.newFunction.text[index].push({ text: rest, - node: 'text', - }) + node: "text", + }); } } } else { that.data.newFunction.text[index] = [{ text: str, - node: 'text', - }] + node: "text", + }, ]; } } function change_data(that, newFunction) { - var arr = newFunction.split('\n'); + var arr = newFunction.split("\n"); var arr2 = []; for (var i = 0; i < arr.length; i++) { var str = arr[i]; that.data.newFunction.text[i] = []; - that.html2wxml(str, i) + that.html2wxml(str, i); } that.setData({ - newFunction: that.data.newFunction - }) + newFunction: that.data.newFunction, + }); } function copy(content, hintText) { @@ -248,20 +267,17 @@ function copy(content, hintText) { success: function (res) { wx.showToast({ icon: "none", - title: hintText || '复制成功!', - }) - resolve() + title: hintText || "复制成功!", + }); + resolve(); }, fail(err) { - reject(err) - } - }) - }) - + reject(err); + }, + }); + }); } - - //封装Request请求方法 function request(url, data = {}, ishint = true) { return new Promise((resolve, reject) => { @@ -269,30 +285,33 @@ function request(url, data = {}, ishint = true) { // reject() // return false // } - let Authorization = wx.getStorageSync('Authorization') + let Authorization = wx.getStorageSync("Authorization"); if (!Authorization) { - Authorization = app.randomString(32) - wx.setStorageSync('Authorization', Authorization) - wx.setStorageSync('session', Authorization) + Authorization = app.randomString(32); + wx.setStorageSync("Authorization", Authorization); + wx.setStorageSync("session", Authorization); } let sendData = Object.assign({ - session: wx.getStorageSync('session'), - }, app.globalData.options, data) + session: wx.getStorageSync("session"), + }, + app.globalData.options, + data + ); wx.request({ url: url, data: sendData, timeout: data.timeout || 60000, header: { - 'content-type': 'application/json', - 'Accept': 'application/json, text/plain', - 'Cookie': 'miucms_session=' + Authorization, - 'Authorization': Authorization || '' + "content-type": "application/json", + Accept: "application/json, text/plain", + Cookie: "miucms_session=" + Authorization, + Authorization: Authorization || "", }, - method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT + method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT success: function (res) { var json = res.data; - if (typeof json != 'object') { + if (typeof json != "object") { if (json != null) { json = json.replace("\ufeff", ""); try { @@ -301,118 +320,114 @@ function request(url, data = {}, ishint = true) { } catch (error) { if (ishint) { wx.showModal({ - title: '提示', - content: '请求失败' - }) + title: "提示", + content: "请求失败", + }); } } - } } var data = res.data; - resolve(data) + resolve(data); }, fail: function (msg) { wx.hideLoading(); if (ishint) { wx.showToast({ title: msg, - icon: 'none', + icon: "none", duration: 2000, - mask: true - }) + mask: true, + }); } - reject('fail') - } - }) - }) + reject("fail"); + }, + }); + }); } const wxget = function (url, data = {}) { - data = Object.assign({}, app.globalData.options, data) + data = Object.assign({}, app.globalData.options, data); return new Promise((resolve, reject) => { - var authorization = wx.getStorageSync('Authorization'); + var authorization = wx.getStorageSync("Authorization"); if (!authorization) { - authorization = app.randomString(32) - wx.setStorageSync('Authorization', authorization) - wx.setStorageSync('session', authorization) + authorization = app.randomString(32); + wx.setStorageSync("Authorization", authorization); + wx.setStorageSync("session", authorization); } wx.request({ url: url, data: data, header: { - 'Cookie': 'miucms_session=' + authorization, - Authorization: authorization + Cookie: "miucms_session=" + authorization, + Authorization: authorization, }, - method: 'GET', + method: "GET", success: (res) => { if (res.data.code == 200) { - resolve(res.data) + resolve(res.data); } else if (res.data.code == 401) { // 需要授权 app.globalData.user.uid = 0; wx.showToast({ - icon: 'none', - title: res.data.message - }) - reject(res) + icon: "none", + title: res.data.message, + }); + reject(res); } else { - wx.hideLoading() + wx.hideLoading(); wx.showModal({ - title: '提示', + title: "提示", content: res.message || res.data.message, - }) - reject(res.data) + }); + reject(res.data); } - }, fail(res) { wx.showModal({ - title: '提示', + title: "提示", content: res, - }) - reject(res) - } + }); + reject(res); + }, }); - }) - -} + }); +}; function closeAD(id) { - if (!app.globalData.config || !app.globalData.config.adv) return false + if (!app.globalData.config || !app.globalData.config.adv) return false; request(app.globalData.config.adv.close, { - advid: id - }).then(res => {}) + advid: id, + }).then((res) => {}); } function clickAD(id) { if (!app.globalData.config || !app.globalData.config.adv) { - return false + return false; } request(app.globalData.config.adv.click, { - advid: id - }).then(res => {}) + advid: id, + }).then((res) => {}); } function getTopTitle(that, app) { - let topTitle = app.globalData.topTitle + let topTitle = app.globalData.topTitle; if (topTitle) { that.setData({ topTitle: app.globalData.topTitle, miniProgram: app.globalData.miniProgram, - }) + }); } else { setTimeout(() => { - that.getTopTitle() - }, 300) + that.getTopTitle(); + }, 300); } - } function getTimeAgo(Time) { const now = new Date(); - let time = new Date(Time) + let time = new Date(Time); const diff = now - time; const seconds = Math.floor(diff / 1000); const minutes = Math.floor(seconds / 60); @@ -425,71 +440,70 @@ function getTimeAgo(Time) { else return Time; } - // 开启socket -let socketCount = 0 // 链接次数,判断失败 +let socketCount = 0; // 链接次数,判断失败 const useSocket = () => { if (app.globalData.isConnected) { - console.log("已经连接,不再重复连接") - return // 如果已经连接,则不再创建新的 socketTask + console.log("已经连接,不再重复连接"); + return; // 如果已经连接,则不再创建新的 socketTask } app.globalData.socketTask = wx.connectSocket({ - url: `wss://socket.gter.net/socket?token=${wx.getStorageSync('Authorization') || ''}`, + url: `wss://socket.gter.net/socket?token=${wx.getStorageSync("Authorization") || ""}`, success: function (res) { - app.globalData.isConnected = true // 连接成功,设置为 true + app.globalData.isConnected = true; // 连接成功,设置为 true }, fail: function (err) { - app.globalData.isConnected = false // 连接成功,设置为 true + app.globalData.isConnected = false; // 连接成功,设置为 true console.log(err, "err"); - } - }) + }, + }); app.globalData.socketTask.onOpen(function () { // 初始化发消息 - if (wx.getStorageSync('Authorization')) { + if (wx.getStorageSync("Authorization")) { let getAccountInfoSync = wx.getAccountInfoSync(); let dataToSend = { - type: 'bind', + type: "bind", data: { - token: wx.getStorageSync('Authorization') || '', - app: getAccountInfoSync.miniProgram.appId + token: wx.getStorageSync("Authorization") || "", + app: getAccountInfoSync.miniProgram.appId, // uid: user.uid || 0 - } - } + }, + }; app.globalData.socketTask.send({ data: JSON.stringify(dataToSend), - }) + }); } // 开始定时发 - setTimeout(() => timedTransmission(), 50000) - }) + setTimeout(() => timedTransmission(), 50000); + }); app.globalData.socketTask.onClose(function () { // console.log('socket关闭了', new Date()) - socketCount++ - if (socketCount > 3) return + socketCount++; + if (socketCount > 3) return; setTimeout(() => useSocket(), 3000); - app.globalData.isConnected = false // 连接关闭,重置为 false - }) -} + app.globalData.isConnected = false; // 连接关闭,重置为 false + }); +}; // 定时发送 const timedTransmission = () => { - if (app.globalData.socketTask.readyState != 1) return + if (app.globalData.socketTask.readyState != 1) return; var dataToSend = { - type: 'ping' - } + type: "ping", + }; app.globalData.socketTask.send({ data: JSON.stringify(dataToSend), - complete: () => setTimeout(() => timedTransmission(), 50000) - }) -} + complete: () => setTimeout(() => timedTransmission(), 50000), + }); +}; // 专门在初始化 获取筛选全局的值和传入的值 const updateProperty = (key, options, brandSelectionObj) => { - if (options[key] != undefined) return options[key] - else if (brandSelectionObj[key] != undefined) return brandSelectionObj[key] -} + if (options[key] != undefined) return options[key]; + else if (brandSelectionObj[key] != undefined) return brandSelectionObj[key]; +}; // 字符串转base64 function base64_encode(str) { @@ -529,16 +543,15 @@ function goPage(url) { wx.navigateTo({ url, fail: function (err) { - if (err.errMsg = "navigateTo:fail webview count limit exceed") { + if ((err.errMsg = "navigateTo:fail webview count limit exceed")) { wx.redirectTo({ url, - }) + }); } - } - }) + }, + }); } - function getTitleName(url) { const obj = { "pages/index/index": "首页", @@ -571,19 +584,19 @@ function getTitleName(url) { // 调用 统计接口 function statistics(obj) { - return + return; - let url = "" - let options = {} - let pages = null + let url = ""; + let options = {}; + let pages = null; if (obj.path) { - url = obj.path - options = obj.query || {} + url = obj.path; + options = obj.query || {}; } else { pages = getCurrentPages(); // 获取当前页面栈 const currentPage = pages[pages.length - 1]; // 当前页面对象 - url = currentPage.route - options = currentPage.options + url = currentPage.route; + options = currentPage.options; } // // 当页面显示时执行 @@ -592,7 +605,6 @@ function statistics(obj) { // const url = currentPage.route; // 当前页面url // const options = currentPage.options; // 当前页面url的参数 - const launchOptions = wx.getLaunchOptionsSync() || {}; // 构建带参数的URL @@ -609,12 +621,12 @@ function statistics(obj) { website: accountInfo.miniProgram.appId, hostname: accountInfo.miniProgram.appId, screen: `${windowInfo.windowWidth}x${windowInfo.windowHeight}`, - language: base.language || '', - os: deviceInfo.system || '', - platform: deviceInfo.platform || '', - device: deviceInfo.model || '', - session: wx.getStorageSync("xstatSession") || '', - scene: launchOptions.scene || '', + language: base.language || "", + os: deviceInfo.system || "", + platform: deviceInfo.platform || "", + device: deviceInfo.model || "", + session: wx.getStorageSync("xstatSession") || "", + scene: launchOptions.scene || "", }; wx.setStorageSync("xstatSystemInfo", systemInfo); } @@ -632,29 +644,29 @@ function statistics(obj) { try { wx.request({ - url: 'https://stat.gter.net/api/send', + url: "https://stat.gter.net/api/send", method: "POST", data: { payload, - type: obj.type || 'event', + type: obj.type || "event", }, timeout: 5000, header: { - 'Content-Type': 'application/json', - 'x-stat-token': base64_encode(JSON.stringify(systemInfo)), + "Content-Type": "application/json", + "x-stat-token": base64_encode(JSON.stringify(systemInfo)), }, success: (res) => { if (res.data.code == 200 && res.data.data && res.data.data.session && res.data.data.session != systemInfo.session) { wx.setStorageSync("xstatSession", res.data.data.session); wx.setStorageSync("xstatSystemInfo", { ...systemInfo, - session: res.data.data.session + session: res.data.data.session, }); } }, }); } catch (error) { - console.error('发送失败:', error); + console.error("发送失败:", error); } } @@ -675,8 +687,10 @@ function bindingUser(user = {}) { // 将一个JavaScript对象转换为路由参数的形式将键值对转换为key=value的形式 function objectToQueryString(obj = {}) { - const queryString = Object.keys(obj).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])).join('&'); - return queryString ? '?' + queryString : ''; + const queryString = Object.keys(obj) + .map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(obj[key])) + .join("&"); + return queryString ? "?" + queryString : ""; } // 返回上一页或者首页 @@ -684,13 +698,471 @@ function backOrIndex() { wx.navigateBack({ fail: function () { wx.redirectTo({ - url: '/pages/index/index', - }) + url: "/pages/index/index", + }); + }, + }); +} + +// 生成海报 type 1: 公寓 2:认证中介 3: 普通中介 4:个人房东 5:认证个人房源 6:招室友 7:其他 +function generatePoster(target) { + return + return new Promise(async (resolve, reject) => { + const user = getApp().globalData.user || {}; + // 修改画布创建方式 + const canvas = wx.createOffscreenCanvas({ + type: "2d", + width: 280 * 2, // 增加分辨率 + height: 224 * 2, // 增加分辨率 + }); + const ctx = canvas.getContext("2d"); + ctx.scale(2, 2); // 缩放绘图上下文 + const tempFilePath = await downloadPic(target.bj); + let bgImg = canvas.createImage(); + bgImg.src = tempFilePath; + await new Promise((resolve) => { + bgImg.onload = resolve; + }); + console.log("加载背景图片"); + + // 计算aspectFill模式参数 + const containerRatio = 280 / 219; // 容器宽高比 (280x219) + const imageRatio = bgImg.width / bgImg.height; + let drawWidth, + drawHeight, + offsetX = 0, + offsetY = 0; + + if (imageRatio > containerRatio) { + // 图片更宽,按高度缩放 + drawHeight = 219; + drawWidth = drawHeight * imageRatio; + offsetX = (280 - drawWidth) / 2; + } else { + // 图片更高,按宽度缩放 + drawWidth = 280; + drawHeight = drawWidth / imageRatio; + offsetY = (219 - drawHeight) / 2; } - }) + + // 绘制圆角背景(修改drawImage参数) + ctx.save(); + ctx.beginPath(); + ctx.moveTo(15, 4); + ctx.arcTo(280, 4, 280, 224, 15); + ctx.arcTo(280, 224, 0, 224, 15); + ctx.arcTo(0, 224, 0, 4, 15); + ctx.arcTo(0, 4, 280, 4, 15); + ctx.closePath(); + ctx.clip(); + // 计算源图片裁剪区域 + let srcX = 0, + srcY = 0, + srcWidth = bgImg.width, + srcHeight = bgImg.height; + + // 修正缩放逻辑 + if (imageRatio > containerRatio) { + // 图片更宽时,按容器高度缩放 + drawHeight = 219; + drawWidth = drawHeight * imageRatio; + offsetX = (280 - drawWidth) / 2; + + // 源图片裁剪:取中间宽度区域 + srcWidth = bgImg.height * containerRatio; + srcX = (bgImg.width - srcWidth) / 2; + } else { + // 图片更高时,按容器宽度缩放 + drawWidth = 280; + drawHeight = drawWidth / imageRatio; + offsetY = (219 - drawHeight) / 2; + + // 源图片裁剪:取中间高度区域 + srcHeight = bgImg.width / containerRatio; + srcY = (bgImg.height - srcHeight) / 2; + } + + // 修改后的drawImage调用 + ctx.drawImage( + bgImg, + srcX, + srcY, + srcWidth, // 改为计算后的裁剪宽度 + srcHeight, // 改为计算后的裁剪高度 + offsetX, + 4, + drawWidth, + drawHeight + ); + ctx.restore(); + console.log("绘制背景图片"); + + // 绘制右上角标签 + if (target.type == 1) { + let tagImg = canvas.createImage(); + await new Promise((resolve) => { + tagImg.onload = resolve; + tagImg.src = `https://app.gter.net/image/miniApp/HKRenting/high-quality-tag.png?${Date.now()}`; + }); + ctx.drawImage(tagImg, 215, 0, 65, 54); + } else if (target.type == 2 || target.type == 5) { + let tagImg = canvas.createImage(); + const objSrc = { + 2: "certification-intermediary-icon.png", + 5: "certification-listing-icon.png", + }; + await new Promise((resolve) => { + tagImg.onload = resolve; + tagImg.src = `https://app.gter.net/image/miniApp/HKRenting/${objSrc[target.type]}?${Date.now()}`; + }); + ctx.drawImage(tagImg, 215, 4, 50, 58); + } else if (target.type == 3 || target.type == 4 || target.type == 6) { + // 绘制红色价格标签 + ctx.save(); + const tagX = target.type == 6 ? 210 : 225; // 从右侧开始计算位置 + const tagY = 10; + const tagWidth = target.type == 6 ? 60 : 46; + const tagHeight = 23; + + const objBJ = { + 3: "#6fc16d", + 4: "#8080ff", + 6: "#8080ff", + }; + // 绘制圆角背景 + ctx.fillStyle = objBJ[target.type]; + ctx.beginPath(); + ctx.moveTo(tagX + 10, tagY); + ctx.arcTo(tagX + tagWidth, tagY, tagX + tagWidth, tagY + tagHeight, 10); + ctx.arcTo(tagX + tagWidth, tagY + tagHeight, tagX, tagY + tagHeight, 10); + ctx.arcTo(tagX, tagY + tagHeight, tagX, tagY, 10); + ctx.arcTo(tagX, tagY, tagX + tagWidth, tagY, 10); + ctx.closePath(); + ctx.fill(); + // 绘制文字(调整垂直居中) + ctx.fillStyle = "#FFFFFF"; + ctx.font = "bold 15px PingFang SC"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; // 确保基线设置为中间 + // Y坐标计算去掉+1偏移,直接使用精确中点 + const objName = { + 3: "中介", + 4: "房东", + 6: "招室友", + }; + ctx.fillText(objName[target.type], tagX + tagWidth / 2, tagY + tagHeight / 2); + ctx.restore(); + } + + console.log("绘制右上角标签"); + + let username = user.nickname || "匿名用户"; + + // 绘制用户信息区域 + // 先测量文本长度 + ctx.font = "14px PingFang SC"; + ctx.fillStyle = "#000"; + + let displayText = username + " 为你推荐"; + let textMetrics = ctx.measureText(displayText); + let textWidth = textMetrics.width; + + // 添加文本截断逻辑 + const MAX_TEXT_WIDTH = 165; // 最大允许文本宽度 + if (textWidth > MAX_TEXT_WIDTH) { + let limit = username.length; + // 逐步减少字符直到宽度合适 + while (textWidth > MAX_TEXT_WIDTH && limit > 0) { + limit--; + displayText = username.substring(0, limit) + "... 为你推荐"; + textMetrics = ctx.measureText(displayText); + textWidth = textMetrics.width; + } + } + + // 动态计算区域宽度(头像24 + 边距4 + 文本宽度 + 右边距10) + const infoWidth = 24 + 4 + textWidth + 10; + const startX = 0; + const startY = 24; + const radius = 16; + + ctx.fillStyle = "#f2f2f2"; + ctx.beginPath(); + ctx.moveTo(startX, startY); + ctx.lineTo(infoWidth - radius, startY); + ctx.arcTo(infoWidth, startY, infoWidth, startY + 28, radius); + ctx.lineTo(infoWidth, startY + 28 - radius); + ctx.arcTo(infoWidth, startY + 28, startX, startY + 28, radius); + ctx.lineTo(startX, startY + 28); + ctx.closePath(); + ctx.fill(); + + console.log("用户名好了"); + // 绘制头像 + let avatarImg = canvas.createImage(); + await new Promise((resolve) => { + avatarImg.onload = resolve; + const avatarUrl = user.avatar ? `${user.avatar}?${Date.now()}` : `https://app.gter.net/image/miniApp/HKRenting/defaultAvatar.png?${Date.now()}`; // 增加时间戳避免缓存 + avatarImg.src = avatarUrl; + }); + + console.log("加载头像"); + ctx.restore(); // 确保之前的裁剪状态被清除 + + ctx.save(); + ctx.beginPath(); + ctx.arc(14, 38, 12, 0, Math.PI * 2); + ctx.clip(); + ctx.drawImage(avatarImg, 2, 26, 24, 24); + ctx.restore(); + + // 绘制用户名 + ctx.fillStyle = "#000"; + ctx.font = "14px PingFang SC"; + // 修改最终文本绘制调用 + ctx.fillText(displayText, 30, 43); // 使用处理后的文本 + + // 绘制底部信息栏 + const gradient = ctx.createLinearGradient(0, 190, 0, 224); + gradient.addColorStop(0, "rgba(51, 51, 51, 0.2)"); + gradient.addColorStop(1, "rgba(51, 51, 51, 0.9)"); + ctx.fillStyle = gradient; + + ctx.beginPath(); + ctx.moveTo(0, 190); + ctx.arcTo(280, 190, 280, 224, 0); + ctx.arcTo(280, 224, 0, 224, 15); + ctx.arcTo(0, 224, 0, 190, 15); + ctx.closePath(); + ctx.fill(); + console.log("绘制位置图标"); + // 绘制位置图标 + let positionIcon = canvas.createImage(); + await new Promise((resolve) => { + positionIcon.onload = resolve; + positionIcon.src = `https://app.gter.net/image/miniApp/HKRenting/position-icon.svg?${Date.now()}`; + }); + ctx.drawImage(positionIcon, 9, 200, 10, 14); + + // 绘制位置文本 + ctx.fillStyle = "#fff"; + ctx.font = "15px microsoft yahei"; + ctx.fillText(`香港 | ${target.title}`, 25, 212); + + // 绘制箭头图标 + let arrowIcon = canvas.createImage(); + await new Promise((resolve) => { + arrowIcon.onload = resolve; + arrowIcon.src = `https://app.gter.net/image/miniApp/HKRenting/arrow-round-yellow.svg?${Date.now()}`; + }); + ctx.drawImage(arrowIcon, 255, 200, 16, 16); + console.log("绘制箭头图标"); + + // 修改最后保存图片的尺寸 + const imgData = canvas.toDataURL({ + width: 280, + height: 224, + destWidth: 280 * 2, // 输出双倍分辨率 + destHeight: 224 * 2, + }); + + const filePath = `${wx.env.USER_DATA_PATH}/${getCurrentDate()}/poster_share_${Date.now()}.png`; + console.log("filePath", filePath); + const fs = wx.getFileSystemManager(); + console.log("开始保存"); + + fs.writeFile({ + filePath, + data: imgData.replace(/^data:image\/\w+;base64,/, ""), + encoding: "base64", + success: (res) => { + console.log("生成成功",res); + resolve(filePath); + }, + fail: (err) => { + // 此处可能存在内存满了的情况 + // 需要根据具体需求处理 + console.log(err); + }, + }); + cleanupOldDateFolders(); + + fs.close(); + }); +} + +// 生成海报 没有图片 +function generatePosterNoImage(target) { + return new Promise(async (resolve, reject) => { + const user = getApp().globalData.user || {}; + const canvas = wx.createOffscreenCanvas({ + type: "2d", + width: 280 * 2, + height: 224 * 2, + }); + const ctx = canvas.getContext("2d"); + ctx.scale(2, 2); + + // 绘制白色背景 + ctx.fillStyle = "#FFFFFF"; + ctx.fillRect(0, 0, 280, 224); + + // 绘制用户信息区域 + ctx.font = "14px PingFang SC"; + ctx.fillStyle = "#555555"; + + // 绘制圆形头像 + const avatarImg = canvas.createImage(); + await new Promise((resolve) => { + avatarImg.onload = resolve; + const avatarUrl = user.avatar ? `${user.avatar}?${Date.now()}` : `https://app.gter.net/image/miniApp/HKRenting/defaultAvatar.png?${Date.now()}`; // 增加时间戳避免缓存 + avatarImg.src = avatarUrl; + }); + ctx.save(); + ctx.beginPath(); + ctx.arc(12, 12, 12, 0, Math.PI * 2); + ctx.clip(); + ctx.drawImage(avatarImg, 0, 0, 24, 24); + ctx.restore(); + + let username = user.nickname || "匿名用户"; + + // 绘制用户名 + let displayText = username + " 为你推荐"; + let textMetrics = ctx.measureText(displayText); + let textWidth = textMetrics.width; + + // 添加文本截断逻辑 + const MAX_TEXT_WIDTH = 240; // 最大允许文本宽度 + if (textWidth > MAX_TEXT_WIDTH) { + let limit = username.length; + // 逐步减少字符直到宽度合适 + while (textWidth > MAX_TEXT_WIDTH && limit > 0) { + limit--; + displayText = username.substring(0, limit) + "... 为你推荐"; + textMetrics = ctx.measureText(displayText); + textWidth = textMetrics.width; + } + } + ctx.fillText(displayText, 30, 18); // 使用处理后的文本 + // ctx.fillText(`${ user.nickname || "匿名用户" } 为你推荐`, 30, 18); + + // 绘制背景卡片 + const bgImg = canvas.createImage(); + await new Promise((resolve) => { + bgImg.onload = resolve; + bgImg.src = `https://app.gter.net/image/miniApp/HKRenting/share-default-bj.png?${Date.now()}`; + }); + ctx.save(); + ctx.beginPath(); + console.log("ctx", ctx); + // ctx.roundRect(0, 40, 280, 184, [10]); + // 手动绘制圆角路径替代roundRect + const x = 0, + y = 40, + width = 280, + height = 184, + radius = 10; + ctx.moveTo(x + radius, y); + ctx.arcTo(x + width, y, x + width, y + height, radius); + ctx.arcTo(x + width, y + height, x, y + height, radius); + ctx.arcTo(x, y + height, x, y, radius); + ctx.arcTo(x, y, x + width, y, radius); + ctx.closePath(); + ctx.clip(); + ctx.drawImage(bgImg, 0, 40, 280, 184); + ctx.restore(); + + // 绘制文字信息 + ctx.font = "16px PingFang SC"; + ctx.fillStyle = "#000000"; + + // 位置信息 + ctx.fillText(target.position, 44, 71); + + // 类型信息 + ctx.fillText(target.typeText, 44, 121); + + // 价格信息 + ctx.font = "20px PingFang SC"; + ctx.fillStyle = "#FA6B11"; + ctx.fillText(target.price, 44, 171); + ctx.font = "16px PingFang SC"; + ctx.fillStyle = "#000000"; + ctx.fillText("HK$/月", 44 + ctx.measureText(target.price).width + 12, 171); + + // 导出图片 + const imgData = canvas.toDataURL({ + destWidth: 280 * 2, + destHeight: 224 * 2, + }); + + const filePath = `${wx.env.USER_DATA_PATH}/${getCurrentDate()}/poster_share_${Date.now()}.png`; + console.log("filePath", filePath); + wx.getFileSystemManager().writeFile({ + filePath, + data: imgData.split(",")[1], + encoding: "base64", + success: () => resolve(filePath), + fail: reject, + }); + + cleanupOldDateFolders(); + }); +} + +// 下载图片 +function downloadPic(src) { + return new Promise(async (resolve, reject) => { + console.log(src); + wx.getImageInfo({ + src, + success(res) { + console.log(src); + resolve(res.path); + }, + fail(err) { + console.log("err", err); + }, + }); + }); +} + +function cleanupOldDateFolders() { + const fs = wx.getFileSystemManager(); + const currentDate = getCurrentDate(); + + fs.readdir({ + dirPath: wx.env.USER_DATA_PATH, + success(res) { + res.files.forEach((folder) => { + // 严格匹配YYYY-MM-DD格式的目录名(如:2023-12-31) + if (/^\d{4}-\d{2}-\d{2}$/.test(folder) && folder !== currentDate) { + const dirPath = `${wx.env.USER_DATA_PATH}/${folder}`; + fs.rmdir({ + dirPath, + recursive: true, + success: () => console.log("已清理目录:", dirPath), + fail: (err) => console.log("清理失败:", dirPath, err), + }); + } + }); + }, + }); +} + +function getCurrentDate() { + const date = new Date(); + const year = date.getFullYear(); + // getMonth() 返回值是 0(一月) 到 11(十二月) 之间的一个整数,所以要加 1 + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + return `${year}-${month}-${day}`; } module.exports = { + generatePosterNoImage, + generatePoster, initial: initial, share: share, change_data: change_data, @@ -711,23 +1183,23 @@ module.exports = { wx.request({ url: url, data: data, - method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT + method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT header: { - 'content-type': 'application/json', - 'Accept': 'application/json, text/plain', - 'Cookie': 'miucms_session=' + wx.getStorageSync('Authorization'), - 'Authorization': wx.getStorageSync('Authorization') || '' + "content-type": "application/json", + Accept: "application/json, text/plain", + Cookie: "miucms_session=" + wx.getStorageSync("Authorization"), + Authorization: wx.getStorageSync("Authorization") || "", }, success: function (res) { - typeof success == 'function' && success(res); + typeof success == "function" && success(res); }, fail: function () { - typeof fail == 'function' && fail(res); + typeof fail == "function" && fail(res); }, complete: function () { - typeof fail == 'function' && fail(res); - } - }) + typeof fail == "function" && fail(res); + }, + }); }, statistics, @@ -735,4 +1207,4 @@ module.exports = { objectToQueryString, gtergreenonionqrcode: "https://oss.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-d_pIqcXjqqsgFptxhcq_cQnrlcvd3DQYcBq_D-81qNDQyOQ~~", backOrIndex, -} \ No newline at end of file +}; \ No newline at end of file