From ec2443336602f41c850fc551a2bac12fc6956af9 Mon Sep 17 00:00:00 2001 From: David Evans Date: Sat, 3 Feb 2018 12:45:48 +0000 Subject: [PATCH] Fix reference box render glitches [#33] --- lib/sequence-diagram.js | 81 ++++++++++++++----- lib/sequence-diagram.min.js | 2 +- scripts/sequence/Renderer.js | 4 + scripts/sequence/components/BaseComponent.js | 1 + scripts/sequence/components/Block.js | 15 +++- scripts/sequence/test-images/Reference.svg | 4 +- .../test-images/ReferenceLayering.svg | 8 ++ scripts/sequence/test-images/list.js | 1 + scripts/sequence/themes/BaseTheme.js | 15 ++++ scripts/sequence/themes/Basic.js | 2 +- scripts/sequence/themes/Chunky.js | 2 +- scripts/sequence/themes/Monospace.js | 2 +- scripts/sequence/themes/Sketch.js | 40 +++++---- 13 files changed, 134 insertions(+), 43 deletions(-) create mode 100644 scripts/sequence/test-images/ReferenceLayering.svg diff --git a/lib/sequence-diagram.js b/lib/sequence-diagram.js index a0eb779..dfc0239 100644 --- a/lib/sequence-diagram.js +++ b/lib/sequence-diagram.js @@ -3936,6 +3936,7 @@ define('sequence/components/BaseComponent',[],() => { render(/*stage, { topY, primaryY, + fillLayer, blockLayer, shapeLayer, labelLayer, @@ -4149,12 +4150,23 @@ define('sequence/components/Block',[ const agentInfoL = env.agentInfos.get(left); const agentInfoR = env.agentInfos.get(right); - blockInfo.hold.appendChild(config.boxRenderer({ + let shapes = config.boxRenderer({ x: agentInfoL.x, y: blockInfo.startY, width: agentInfoR.x - agentInfoL.x, height: env.primaryY - blockInfo.startY, - })); + }); + if(!shapes.shape) { + shapes = {shape: shapes}; + } + + blockInfo.hold.appendChild(shapes.shape); + if(shapes.fill) { + env.fillLayer.appendChild(shapes.fill); + } + if(shapes.mask) { + env.maskLayer.appendChild(shapes.mask); + } return env.primaryY + config.margin.bottom + env.theme.actionMargin; } @@ -5686,6 +5698,7 @@ define('sequence/Renderer',[ 'maskUnits': 'userSpaceOnUse', }); this.maskReveal = svg.make('rect', {'fill': '#FFFFFF'}); + this.backgroundFills = svg.make('g'); this.agentLines = svg.make('g', { 'mask': 'url(#' + this.namespace + 'LineMask)', }); @@ -5695,6 +5708,7 @@ define('sequence/Renderer',[ this.base.appendChild(this.buildMetadata()); this.base.appendChild(this.themeDefs); this.base.appendChild(this.defs); + this.base.appendChild(this.backgroundFills); this.base.appendChild(this.agentLines); this.base.appendChild(this.blocks); this.base.appendChild(this.actionShapes); @@ -5900,6 +5914,7 @@ define('sequence/Renderer',[ const env = { topY, primaryY: topY + topShift, + fillLayer: this.backgroundFills, blockLayer: this.blocks, shapeLayer: this.actionShapes, labelLayer: this.actionLabels, @@ -6034,6 +6049,7 @@ define('sequence/Renderer',[ this.currentHighlight = -1; svg.empty(this.defs); svg.empty(this.mask); + svg.empty(this.backgroundFills); svg.empty(this.agentLines); svg.empty(this.blocks); svg.empty(this.actionShapes); @@ -6611,6 +6627,21 @@ define('sequence/themes/BaseTheme',[ }, attrs)); }; + BaseTheme.renderRef = (options, position) => { + return { + shape: SVGShapes.renderBox(Object.assign({}, options, { + 'fill': 'none', + }), position), + mask: SVGShapes.renderBox(Object.assign({}, options, { + 'fill': '#000000', + 'stroke': 'none', + }), position), + fill: SVGShapes.renderBox(Object.assign({}, options, { + 'stroke': 'none', + }), position), + }; + }; + BaseTheme.WavePattern = class WavePattern { constructor(width, height) { if(Array.isArray(height)) { @@ -7063,7 +7094,7 @@ define('sequence/themes/Basic',[ top: 0, bottom: 0, }, - boxRenderer: SVGShapes.renderBox.bind(null, { + boxRenderer: BaseTheme.renderRef.bind(null, { 'fill': '#FFFFFF', 'stroke': '#000000', 'stroke-width': 1.5, @@ -7451,7 +7482,7 @@ define('sequence/themes/Monospace',[ top: 0, bottom: 0, }, - boxRenderer: SVGShapes.renderBox.bind(null, { + boxRenderer: BaseTheme.renderRef.bind(null, { 'fill': '#FFFFFF', 'stroke': '#000000', 'stroke-width': 2, @@ -7839,7 +7870,7 @@ define('sequence/themes/Chunky',[ top: 0, bottom: 0, }, - boxRenderer: SVGShapes.renderBox.bind(null, { + boxRenderer: BaseTheme.renderRef.bind(null, { 'fill': '#FFFFFF', 'stroke': '#000000', 'stroke-width': 4, @@ -8969,7 +9000,7 @@ define('sequence/themes/Sketch',[ return shape; } - renderBox({x, y, width, height}, {fill = null, thick = false} = {}) { + boxNodes({x, y, width, height}) { const lT = this.lineNodes( {x, y}, {x: x + width, y}, @@ -8991,12 +9022,14 @@ define('sequence/themes/Sketch',[ {var1: 0, var2: 0.3, move: false} ); - const shape = svg.make('path', Object.assign({ - 'd': lT.nodes + lR.nodes + lB.nodes + lL.nodes, + return lT.nodes + lR.nodes + lB.nodes + lL.nodes; + } + + renderBox(position, {fill = null, thick = false} = {}) { + return svg.make('path', Object.assign({ + 'd': this.boxNodes(position), 'fill': fill || '#FFFFFF', }, thick ? PENCIL.thick : PENCIL.normal)); - - return shape; } renderNote({x, y, width, height}) { @@ -9235,18 +9268,26 @@ define('sequence/themes/Sketch',[ }, PENCIL.normal)); } - renderRefBlock({x, y, width, height}) { - return this.renderBox( - {x, y, width, height}, - {fill: '#FFFFFF', thick: true} - ); + renderRefBlock(position) { + const nodes = this.boxNodes(position); + return { + shape: svg.make('path', Object.assign({ + 'd': nodes, + 'fill': 'none', + }, PENCIL.thick)), + mask: svg.make('path', { + 'd': nodes, + 'fill': '#000000', + }), + fill: svg.make('path', { + 'd': nodes, + 'fill': '#FFFFFF', + }), + }; } - renderBlock({x, y, width, height}) { - return this.renderBox( - {x, y, width, height}, - {fill: 'none', thick: true} - ); + renderBlock(position) { + return this.renderBox(position, {fill: 'none', thick: true}); } renderTag({x, y, width, height}) { diff --git a/lib/sequence-diagram.min.js b/lib/sequence-diagram.min.js index 78c4527..ad74b03 100644 --- a/lib/sequence-diagram.min.js +++ b/lib/sequence-diagram.min.js @@ -1 +1 @@ -!function(){var e,t,n;!function(r){function s(e,t){return x.call(e,t)}function i(e,t){var n,r,s,i,a,o,l,h,d,g,c,u=t&&t.split("/"),p=b.map,m=p&&p["*"]||{};if(e){for(a=(e=e.split("/")).length-1,b.nodeIdCompat&&w.test(e[a])&&(e[a]=e[a].replace(w,"")),"."===e[0].charAt(0)&&u&&(e=u.slice(0,u.length-1).concat(e)),d=0;d0&&(e.splice(d-1,2),d-=2)}e=e.join("/")}if((u||m)&&p){for(d=(n=e.split("/")).length;d>0;d-=1){if(r=n.slice(0,d).join("/"),u)for(g=u.length;g>0;g-=1)if((s=p[u.slice(0,g).join("/")])&&(s=s[r])){i=s,o=d;break}if(i)break;!l&&m&&m[r]&&(l=m[r],h=d)}!i&&l&&(i=l,o=h),i&&(n.splice(0,o,i),e=n.join("/"))}return e}function a(e,t){return function(){var n=k.call(arguments,0);return"string"!=typeof n[0]&&1===n.length&&n.push(null),c.apply(r,n.concat([e,t]))}}function o(e){return function(t){m[e]=t}}function l(e){if(s(f,e)){var t=f[e];delete f[e],y[e]=!0,g.apply(r,t)}if(!s(m,e)&&!s(y,e))throw new Error("No "+e);return m[e]}function h(e){var t,n=e?e.indexOf("!"):-1;return n>-1&&(t=e.substring(0,n),e=e.substring(n+1,e.length)),[t,e]}function d(e){return e?h(e):[]}var g,c,u,p,m={},f={},b={},y={},x=Object.prototype.hasOwnProperty,k=[].slice,w=/\.js$/;u=function(e,t){var n,r=h(e),s=r[0],a=t[1];return e=r[1],s&&(n=l(s=i(s,a))),s?e=n&&n.normalize?n.normalize(e,function(e){return function(t){return i(t,e)}}(a)):i(e,a):(s=(r=h(e=i(e,a)))[0],e=r[1],s&&(n=l(s))),{f:s?s+"!"+e:e,n:e,pr:s,p:n}},p={require:function(e){return a(e)},exports:function(e){var t=m[e];return void 0!==t?t:m[e]={}},module:function(e){return{id:e,uri:"",exports:m[e],config:function(e){return function(){return b&&b.config&&b.config[e]||{}}}(e)}}},g=function(e,t,n,i){var h,g,c,b,x,k,w,A=[],v=typeof n;if(i=i||e,k=d(i),"undefined"===v||"function"===v){for(t=!t.length&&n.length?["require","exports","module"]:t,x=0;x{"use strict";return class{constructor(){this.listeners=new Map,this.forwards=new Set}addEventListener(e,t){const n=this.listeners.get(e);n?n.push(t):this.listeners.set(e,[t])}removeEventListener(e,t){const n=this.listeners.get(e);if(!n)return;const r=n.indexOf(t);-1!==r&&n.splice(r,1)}countEventListeners(e){return(this.listeners.get(e)||[]).length}removeAllEventListeners(e){e?this.listeners.delete(e):this.listeners.clear()}addEventForwarding(e){this.forwards.add(e)}removeEventForwarding(e){this.forwards.delete(e)}removeAllEventForwardings(){this.forwards.clear()}trigger(e,t=[]){(this.listeners.get(e)||[]).forEach(e=>e.apply(null,t)),this.forwards.forEach(n=>n.trigger(e,t))}}}),n("core/ArrayUtilities",[],()=>{"use strict";function e(e,t,n=null){if(null===n)return e.indexOf(t);for(let r=0;r=e.length)return void s.push(r.slice());const i=e[n];if(!Array.isArray(i))return r.push(i),t(e,n+1,r,s),void r.pop();for(let a=0;a{n.push(...t(e))}),n}}}),n("sequence/CodeMirrorMode",["core/ArrayUtilities"],e=>{"use strict";function t(e,t){return e.v===t.v&&e.prefix===t.prefix&&e.suffix===t.suffix&&e.q===t.q}function n(t,n,r){let s=r.suggest;return Array.isArray(s)||(s=[s]),e.flatMap(s,e=>!0===e?[function(e,t){return Object.keys(t.then).length>0?{v:e,suffix:" ",q:!1}:{v:e,suffix:"\n",q:!1}}(n,r)]:"object"==typeof e?e.known?t["known"+e.known]||[]:[e]:"string"==typeof e&&e?[{v:e,q:""===n}]:[])}function r(r,s){const i=[],a=e.last(s);return Object.keys(a.then).forEach(o=>{let l=a.then[o];"number"==typeof l&&(l=s[s.length-l-1]),e.mergeSets(i,n(r,o,l),t)}),i}function s(n,r,s,{suggest:i,override:a}){let o=null;"object"==typeof i&&i.known&&(o=i.known),r.type&&o!==r.type&&(a&&(r.type=a),e.mergeSets(n["known"+r.type],[{v:r.value,suffix:" ",q:!0}],t),r.type="",r.value=""),o&&(r.type=o,r.value&&(r.value+=s.s),r.value+=s.v)}function i(t,n,i){const a={type:"",value:""};let l=i;const h=[l];return t.line.forEach((n,i)=>{i===t.line.length-1&&(t.completions=r(t,h));const d=n.q?"":n.v;let g=l.then[d];void 0===g?(g=l.then[""],t.isVar=!0):t.isVar=n.q,"number"==typeof g?h.length-=g:h.push(g||o),l=e.last(h),s(t,a,n,l)}),n&&s(t,a,null,{}),t.nextCompletions=r(t,h),t.valid=Boolean(l.then["\n"])||0===Object.keys(l.then).length,l.type}function a(e){const t=e.baseToken||{};return{value:t.v||"",quoted:t.q||!1}}const o={type:"error line-error",then:{"":0}},l=(()=>{function e(e,t){return{type:"string",suggest:t,then:Object.assign({"":0},e)}}function t(e){return{type:"variable",suggest:{known:"Agent"},then:Object.assign({},e,{"":0,",":{type:"operator",suggest:!0,then:{"":1}}})}}function n(e){return{type:"keyword",suggest:[e+" of ",e+": "],then:{of:{type:"keyword",suggest:!0,then:{"":d}},":":{type:"operator",suggest:!0,then:{"":a}},"":d}}}function r(e,t){const n={type:"operator",suggest:!0,then:{"+":o,"-":o,"*":o,"!":o,"":e}};return{"+":{type:"operator",suggest:!0,then:{"+":o,"-":o,"*":n,"!":o,"":e}},"-":{type:"operator",suggest:!0,then:{"+":o,"-":o,"*":n,"!":{type:"operator",then:{"+":o,"-":o,"*":o,"!":o,"":e}},"":e}},"*":{type:"operator",suggest:!0,then:Object.assign({"+":n,"-":n,"*":o,"!":o,"":e},t)},"!":n,"":e}}const s={type:"",suggest:"\n",then:{}},i={type:"",then:{}},a=e({"\n":s}),l={type:"variable",suggest:{known:"Agent"},then:{"":0,"\n":s,",":{type:"operator",suggest:!0,then:{"":1}},as:{type:"keyword",suggest:!0,then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,",":{type:"operator",suggest:!0,then:{"":3}},"\n":s}}}}}},h={type:"operator",suggest:!0,then:{"":a,"\n":i}},d=t({":":h}),g={type:"variable",suggest:{known:"Agent"},then:{"":0,",":{type:"operator",suggest:!0,then:{"":d}},":":o}},c={type:"variable",suggest:{known:"Agent"},then:{"":0,",":o,":":h}},u={type:"variable",suggest:{known:"Agent"},then:{"":0,":":{type:"operator",suggest:!0,then:{"":a,"\n":i}},"\n":s}},p={":":{type:"operator",suggest:!0,then:{"":e({as:{type:"keyword",suggest:!0,then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,"\n":s}}}}})}}},m={type:"keyword",suggest:!0,then:Object.assign({over:{type:"keyword",suggest:!0,then:{"":t(p)}}},p)},f={"\n":s,":":{type:"operator",suggest:!0,then:{"":a,"\n":i}},with:{type:"keyword",suggest:["with height "],then:{height:{type:"keyword",suggest:!0,then:{"":{type:"number",suggest:["6 ","30 "],then:{"\n":s,":":{type:"operator",suggest:!0,then:{"":a,"\n":i}}}}}}}}},b={title:{type:"keyword",suggest:!0,then:{"":a}},theme:{type:"keyword",suggest:!0,then:{"":{type:"string",suggest:{global:"themes",suffix:"\n"},then:{"":0,"\n":s}}}},headers:{type:"keyword",suggest:!0,then:{none:{type:"keyword",suggest:!0,then:{}},cross:{type:"keyword",suggest:!0,then:{}},box:{type:"keyword",suggest:!0,then:{}},fade:{type:"keyword",suggest:!0,then:{}},bar:{type:"keyword",suggest:!0,then:{}}}},terminators:{type:"keyword",suggest:!0,then:{none:{type:"keyword",suggest:!0,then:{}},cross:{type:"keyword",suggest:!0,then:{}},box:{type:"keyword",suggest:!0,then:{}},fade:{type:"keyword",suggest:!0,then:{}},bar:{type:"keyword",suggest:!0,then:{}}}},divider:{type:"keyword",suggest:!0,then:Object.assign({line:{type:"keyword",suggest:!0,then:f},space:{type:"keyword",suggest:!0,then:f},delay:{type:"keyword",suggest:!0,then:f},tear:{type:"keyword",suggest:!0,then:f}},f)},define:{type:"keyword",suggest:!0,then:{"":l,as:o}},begin:{type:"keyword",suggest:!0,then:{"":l,reference:m,as:o}},end:{type:"keyword",suggest:!0,then:{"":l,as:o,"\n":s}},if:{type:"keyword",suggest:!0,then:{"":a,":":{type:"operator",suggest:!0,then:{"":a}},"\n":s}},else:{type:"keyword",suggest:["else\n","else if: "],then:{if:{type:"keyword",suggest:"if: ",then:{"":a,":":{type:"operator",suggest:!0,then:{"":a}}}},"\n":s}},repeat:{type:"keyword",suggest:!0,then:{"":a,":":{type:"operator",suggest:!0,then:{"":a}},"\n":s}},note:{type:"keyword",suggest:!0,then:{over:{type:"keyword",suggest:!0,then:{"":d}},left:n("left"),right:n("right"),between:{type:"keyword",suggest:!0,then:{"":g}}}},state:{type:"keyword",suggest:"state over ",then:{over:{type:"keyword",suggest:!0,then:{"":c}}}},text:{type:"keyword",suggest:!0,then:{left:n("left"),right:n("right")}},autolabel:{type:"keyword",suggest:!0,then:{off:{type:"keyword",suggest:!0,then:{}},"":e({"\n":s},[{v:"