1/** js sequence diagrams 2 * https://bramp.github.io/js-sequence-diagrams/ 3 * (c) 2012-2017 Andrew Brampton (bramp.net) 4 * Simplified BSD license. 5 */ 6/*global grammar _ */ 7 8function Diagram() { 9 this.title = undefined; 10 this.actors = []; 11 this.signals = []; 12} 13/* 14 * Return an existing actor with this alias, or creates a new one with alias and name. 15 */ 16Diagram.prototype.getActor = function(alias, name) { 17 alias = alias.trim(); 18 19 var i; 20 var actors = this.actors; 21 for (i in actors) { 22 if (actors[i].alias == alias) { 23 return actors[i]; 24 } 25 } 26 i = actors.push(new Diagram.Actor(alias, (name || alias), actors.length)); 27 return actors[ i - 1 ]; 28}; 29 30/* 31 * Parses the input as either a alias, or a "name as alias", and returns the corresponding actor. 32 */ 33Diagram.prototype.getActorWithAlias = function(input) { 34 input = input.trim(); 35 36 // We are lazy and do some of the parsing in javascript :(. TODO move into the .jison file. 37 var s = /([\s\S]+) as (\S+)$/im.exec(input); 38 var alias; 39 var name; 40 if (s) { 41 name = s[1].trim(); 42 alias = s[2].trim(); 43 } else { 44 name = alias = input; 45 } 46 return this.getActor(alias, name); 47}; 48 49Diagram.prototype.setTitle = function(title) { 50 this.title = title; 51}; 52 53Diagram.prototype.addSignal = function(signal) { 54 this.signals.push(signal); 55}; 56 57Diagram.Actor = function(alias, name, index) { 58 this.alias = alias; 59 this.name = name; 60 this.index = index; 61}; 62 63Diagram.Signal = function(actorA, signaltype, actorB, message) { 64 this.type = 'Signal'; 65 this.actorA = actorA; 66 this.actorB = actorB; 67 this.linetype = signaltype & 3; 68 this.arrowtype = (signaltype >> 2) & 3; 69 this.message = message; 70}; 71 72Diagram.Signal.prototype.isSelf = function() { 73 return this.actorA.index == this.actorB.index; 74}; 75 76Diagram.Note = function(actor, placement, message) { 77 this.type = 'Note'; 78 this.actor = actor; 79 this.placement = placement; 80 this.message = message; 81 82 if (this.hasManyActors() && actor[0] == actor[1]) { 83 throw new Error('Note should be over two different actors'); 84 } 85}; 86 87Diagram.Note.prototype.hasManyActors = function() { 88 return _.isArray(this.actor); 89}; 90 91Diagram.unescape = function(s) { 92 // Turn "\\n" into "\n" 93 return s.trim().replace(/^"(.*)"$/m, '$1').replace(/\\n/gm, '\n'); 94}; 95 96Diagram.LINETYPE = { 97 SOLID: 0, 98 DOTTED: 1 99}; 100 101Diagram.ARROWTYPE = { 102 FILLED: 0, 103 OPEN: 1 104}; 105 106Diagram.PLACEMENT = { 107 LEFTOF: 0, 108 RIGHTOF: 1, 109 OVER: 2 110}; 111 112// Some older browsers don't have getPrototypeOf, thus we polyfill it 113// https://github.com/bramp/js-sequence-diagrams/issues/57 114// https://github.com/zaach/jison/issues/194 115// Taken from http://ejohn.org/blog/objectgetprototypeof/ 116if (typeof Object.getPrototypeOf !== 'function') { 117 /* jshint -W103 */ 118 if (typeof 'test'.__proto__ === 'object') { 119 Object.getPrototypeOf = function(object) { 120 return object.__proto__; 121 }; 122 } else { 123 Object.getPrototypeOf = function(object) { 124 // May break if the constructor has been tampered with 125 return object.constructor.prototype; 126 }; 127 } 128 /* jshint +W103 */ 129} 130 131/** The following is included by preprocessor */ 132// #include "build/grammar.js" 133 134/** 135 * jison doesn't have a good exception, so we make one. 136 * This is brittle as it depends on jison internals 137 */ 138function ParseError(message, hash) { 139 _.extend(this, hash); 140 141 this.name = 'ParseError'; 142 this.message = (message || ''); 143} 144ParseError.prototype = new Error(); 145Diagram.ParseError = ParseError; 146 147Diagram.parse = function(input) { 148 // TODO jison v0.4.17 changed their API slightly, so parser is no longer defined: 149 150 // Create the object to track state and deal with errors 151 parser.yy = new Diagram(); 152 parser.yy.parseError = function(message, hash) { 153 throw new ParseError(message, hash); 154 }; 155 156 // Parse 157 var diagram = parser.parse(input); 158 159 // Then clean up the parseError key that a user won't care about 160 delete diagram.parseError; 161 return diagram; 162}; 163 164