├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── LICENSE
├── README.md
├── app.json
├── chrome-ext
├── README.md
├── manifest.json
└── src
│ ├── content.js
│ └── static
│ ├── images
│ ├── logo_128.png
│ ├── logo_16.png
│ ├── logo_32.png
│ └── logo_48.png
│ └── vendor
│ ├── css
│ ├── diagram-js-bpmn.css
│ ├── diagram-js-cmmn.css
│ └── diagram-js-dmn.css
│ └── js
│ ├── bpmn-viewer.production.min.js
│ ├── cmmn-viewer.production.min.js
│ ├── dmn-viewer.production.min.js
│ └── jquery-3.4.1.min.js
├── lerna.json
├── package-lock.json
├── package.json
├── probot-app
├── .env.example
├── .eslintrc
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app.yml
├── package-lock.json
├── package.json
├── src
│ ├── helper
│ │ ├── extractBpmnFileUrls.js
│ │ ├── index.js
│ │ └── templates.js
│ ├── index.js
│ ├── misc
│ │ └── loading.gif
│ └── process-urls
│ │ └── index.js
└── test
│ ├── fixtures
│ └── issue_comment.created.json
│ └── index.test.js
├── process.json
├── renovate.json
├── resources
├── basic.bpmn
├── complex.bpmn
├── complex.cmmn
├── conditions.bpmn
├── large.dmn
├── multiple-cases.cmmn
├── one-decision.dmn
├── screencast-1.gif
├── screencast-2.gif
├── screencast-3.gif
├── simple.bpmn
├── simple.cmmn
└── simple.dmn
└── userscript
├── .eslintrc
└── index.js
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | matrix:
12 | node-version: [ 16 ]
13 |
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v4
17 | - name: Use Node.js ${{ matrix.node-version }}
18 | uses: actions/setup-node@v3
19 | with:
20 | node-version: ${{ matrix.node-version }}
21 | - name: Cache Node.js modules
22 | uses: actions/cache@v3
23 | with:
24 | # npm cache files are stored in `~/.npm` on Linux/macOS
25 | path: ~/.npm
26 | key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
27 | restore-keys: |
28 | ${{ runner.OS }}-node-
29 | ${{ runner.OS }}-
30 | - name: Install depedencies
31 | run: npm install
32 | - name: Execute tests
33 | run: cd probot-app && npm test
34 | env:
35 | CI: true
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Niklas Kiefer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # github-bpmn
2 | Applications Collection: Render BPMN, CMMN and DMN files on GitHub
3 |
4 | Built at 2019 [Camunda](https://camunda.com/) Hackdays
5 |
6 | ## Outline
7 |
8 | * [User Script](userscript/): Tampermonkey Extension to Render BPMN | CMMN | DMN Files on GitHub
9 | * [Chrome Extension](chrome-ext/): User Script wrapped as Chrome Extension
10 | * [Render Bpmn App](probot-app/): GitHub Application for Rendering BPMN Files in Issues and Pull Requests
11 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "render-bpmn",
3 | "description": "Render BPMN, CMMN and DMN files on GitHub",
4 | "repository": "https://github.com/pinussilvestrus/github-bpmn",
5 | "logo": "https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/master/chrome-ext/src/static/images/logo_48.png",
6 | "keywords": [
7 | "probot",
8 | "github",
9 | "probot-app",
10 | "bpmn"
11 | ]
12 | }
--------------------------------------------------------------------------------
/chrome-ext/README.md:
--------------------------------------------------------------------------------
1 | # chrome-ext
2 |
3 | > A chrome extension that renders BPMN, CMMN and DMN files on GitHub on hover
4 |
5 | ## Setup
6 |
7 | Open the [Extensions view](https://support.google.com/chrome_webstore/answer/2664769?hl=en) in Chrome and click on `Load unpacked`, locate the repository and select the `chrome-ext` folder.
8 |
9 | Preview BPMN, CMMN and DMN files directly via tooltip.
10 |
11 | 
12 |
13 | Furthermore, preview them on the file details page.
14 |
15 | 
--------------------------------------------------------------------------------
/chrome-ext/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "BPMN on Hover",
3 | "version": "0.0.1",
4 | "description": "Renders BPMN files on hover.",
5 | "manifest_version": 2,
6 | "icons": {
7 | "16": "src/static/images/logo_16.png",
8 | "32": "src/static/images/logo_32.png",
9 | "48": "src/static/images/logo_48.png",
10 | "128": "src/static/images/logo_128.png"
11 | },
12 | "content_scripts": [
13 | {
14 | "matches": [
15 | "https://github.com/*/*"
16 | ],
17 | "js": ["src/static/vendor/js/bpmn-viewer.production.min.js", "src/static/vendor/js/cmmn-viewer.production.min.js", "src/static/vendor/js/dmn-viewer.production.min.js", "src/static/vendor/js/jquery-3.4.1.min.js" ,"src/content.js"]
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/chrome-ext/src/content.js:
--------------------------------------------------------------------------------
1 |
2 | const thumb_selector = '.content a';
3 |
4 | // returns source url for GitHub
5 | function getSrc(src) {
6 | let splitSrc = src.split('/');
7 | let notAllowed = ['blob', 'https:', 'http:', 'github.com'];
8 |
9 | splitSrc = splitSrc.filter(function(word) {
10 | if (!notAllowed.includes(word))
11 | return word;
12 | });
13 |
14 | let user = splitSrc.reverse().pop();
15 | let repo = splitSrc.pop();
16 | let ref = splitSrc.pop();
17 |
18 | return `https://api.github.com/repos/${user}/${repo}/contents/${splitSrc.reverse().join('/').replace('#','')}?ref=${ref}`;
19 | }
20 |
21 | // returns the viewer depending on the viewer type
22 | function returnViewer(type) {
23 | switch (type) {
24 | case 'bpmn':
25 | return new BpmnJS({
26 | container: $('#js-canvas')
27 | });
28 | case 'cmmn':
29 | return new CmmnJS({
30 | container: $('#js-canvas')
31 | });
32 | case 'dmn':
33 | return new DmnJS({
34 | container: $('#js-canvas')
35 | });
36 | default:
37 | return;
38 | }
39 | }
40 |
41 | // exports and appends an SVG for any viewer
42 | function exportSVG(viewer, posX, posY, ele) {
43 |
44 | return new Promise((resolve, reject) => {
45 | viewer.saveSVG(function(err, svg) {
46 |
47 | if (err) reject();
48 |
49 | ele.append(`
${svg}
`);
50 |
51 | $('.svg')
52 | .css('position', 'fixed')
53 | .css('bottom', (window.innerHeight - posY) * 0.5)
54 | .css('left', posX + 25)
55 | .css('z-index', 9999)
56 | .css('background-color', 'white')
57 | .css('height', '50%')
58 | .css('width', '50%')
59 | .css('box-shadow', '0px 0px 20px 5px rgba(0,0,0,1)');
60 |
61 | $('.svg svg')
62 | .attr('width', '100%')
63 | .attr('height', '100%');
64 |
65 | resolve();
66 | });
67 | })
68 |
69 | }
70 |
71 | // shows BPMN, CMMN and DMN (DRD) diagrams
72 | function showDiagram(e) {
73 | let sourceUrl = this.href || e.href;
74 | let viewerType = null;
75 |
76 | // to which parent element the svg will be appended
77 | let ele = $('.file-wrap');
78 | if (e.href)
79 | ele = $('body');
80 |
81 | if (sourceUrl.includes('.bpmn')) {
82 | viewerType = 'bpmn';
83 | } else if (sourceUrl.includes('.cmmn')) {
84 | viewerType = 'cmmn';
85 | } else if (sourceUrl.includes('.dmn')) {
86 | viewerType = 'dmn';
87 | } else {
88 | return;
89 | }
90 |
91 | var loc = getSrc(sourceUrl);
92 |
93 | $('body').append('');
94 | $('.js-canvas-parent').css('visibility', 'hidden');
95 |
96 | var viewer = returnViewer(viewerType);
97 |
98 | // ajax call to request content from github usercontent
99 | return new Promise((resolve, reject) => {
100 | $.ajax(loc, {
101 | dataType: 'json'
102 | }).done(function(json) {
103 | let xml = b64DecodeUnicode(json.content);
104 |
105 | viewer.importXML(xml, async function(err) {
106 |
107 | if (viewerType == 'dmn') {
108 | var activeView = viewer.getActiveView();
109 | // apply initial logic in DRD view
110 | if (activeView.type === 'drd') {
111 | var activeEditor = viewer.getActiveViewer();
112 |
113 | // access active editor components
114 | var canvas = activeEditor.get('canvas');
115 |
116 | // zoom to fit full viewport
117 | canvas.zoom('fit-viewport');
118 |
119 | await exportSVG(activeEditor, e.clientX, e.clientY, ele);
120 | }
121 | } else {
122 | (err) ? console.error(err): viewer.get('canvas').zoom('fit-viewport');
123 |
124 | await exportSVG(viewer, e.clientX, e.clientY, ele);
125 |
126 | resolve();
127 | }
128 | });
129 | });
130 | });
131 | }
132 |
133 | // removes diagram from drom
134 | function hideDiagram(e) {
135 | $('.svg').remove();
136 | $('.js-canvas-parent').remove();
137 | }
138 |
139 | function addRenderButton() {
140 | if ($('.final-path').length &&
141 | $('.final-path').text().includes('.bpmn') ||
142 | $('.final-path').text().includes('.cmmn') ||
143 | $('.final-path').text().includes('.dmn')
144 | ) {
145 | $('.Box-header .BtnGroup').append('Render');
146 | }
147 | $('a#render-diagram').on('click', openDiagram);
148 | }
149 |
150 | // opens the diagram in a new window
151 | async function openDiagram() {
152 | await showDiagram(this);
153 |
154 | var w = window.open();
155 | var html = $('.svg').html();
156 | $(w.document.body).html(html);
157 | }
158 |
159 | /**
160 | * Active calls
161 | */
162 |
163 | // add the render button in case of a site refresh
164 | addRenderButton();
165 | $('body').on('mouseenter', thumb_selector, showDiagram);
166 | $('body').on('mouseleave', thumb_selector, hideDiagram);
167 |
168 | // listens to node remove event in DOM, as GitHub dynamically changes the view within the a repository
169 | $('body').on('DOMNodeRemoved', async function(event) {
170 | if (typeof event.target.className == 'string' && event.target.className.includes('container-lg')) {
171 | await Sleep(500);
172 |
173 | addRenderButton();
174 | }
175 | });
176 |
177 | /**
178 | * Helper functions
179 | */
180 |
181 | function b64DecodeUnicode(str) {
182 | // Going backwards: from bytestream, to percent-encoding, to original string.
183 | return decodeURIComponent(atob(str).split('').map(function(c) {
184 | return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
185 | }).join(''));
186 | }
187 |
188 | function Sleep(milliseconds) {
189 | return new Promise(resolve => setTimeout(resolve, milliseconds));
190 | }
--------------------------------------------------------------------------------
/chrome-ext/src/static/images/logo_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/chrome-ext/src/static/images/logo_128.png
--------------------------------------------------------------------------------
/chrome-ext/src/static/images/logo_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/chrome-ext/src/static/images/logo_16.png
--------------------------------------------------------------------------------
/chrome-ext/src/static/images/logo_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/chrome-ext/src/static/images/logo_32.png
--------------------------------------------------------------------------------
/chrome-ext/src/static/images/logo_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/chrome-ext/src/static/images/logo_48.png
--------------------------------------------------------------------------------
/chrome-ext/src/static/vendor/css/diagram-js-bpmn.css:
--------------------------------------------------------------------------------
1 | /**
2 | * outline styles
3 | */
4 |
5 | .djs-outline {
6 | fill: none;
7 | visibility: hidden;
8 | }
9 |
10 | .djs-element.hover .djs-outline,
11 | .djs-element.selected .djs-outline {
12 | visibility: visible;
13 | shape-rendering: crispEdges;
14 | stroke-dasharray: 3,3;
15 | }
16 |
17 | .djs-element.selected .djs-outline {
18 | stroke: #8888FF;
19 | stroke-width: 1px;
20 | }
21 |
22 | .djs-element.hover .djs-outline {
23 | stroke: #FF8888;
24 | stroke-width: 1px;
25 | }
26 |
27 | .djs-shape.connect-ok .djs-visual > :nth-child(1) {
28 | fill: #DCFECC /* light-green */ !important;
29 | }
30 |
31 | .djs-shape.connect-not-ok .djs-visual > :nth-child(1),
32 | .djs-shape.drop-not-ok .djs-visual > :nth-child(1) {
33 | fill: #f9dee5 /* light-red */ !important;
34 | }
35 |
36 | .djs-shape.new-parent .djs-visual > :nth-child(1) {
37 | fill: #F7F9FF !important;
38 | }
39 |
40 | svg.drop-not-ok {
41 | background: #f9dee5 /* light-red */ !important;
42 | }
43 |
44 | svg.new-parent {
45 | background: #F7F9FF /* light-blue */ !important;
46 | }
47 |
48 | .djs-connection.connect-ok .djs-visual > :nth-child(1),
49 | .djs-connection.drop-ok .djs-visual > :nth-child(1) {
50 | stroke: #90DD5F /* light-green */ !important;
51 | }
52 |
53 | .djs-connection.connect-not-ok .djs-visual > :nth-child(1),
54 | .djs-connection.drop-not-ok .djs-visual > :nth-child(1) {
55 | stroke: #E56283 /* light-red */ !important;
56 | }
57 |
58 | .drop-not-ok,
59 | .connect-not-ok {
60 | cursor: not-allowed;
61 | }
62 |
63 | .djs-element.attach-ok .djs-visual > :nth-child(1) {
64 | stroke-width: 5px !important;
65 | stroke: rgba(255, 116, 0, 0.7) !important;
66 | }
67 |
68 | .djs-frame.connect-not-ok .djs-visual > :nth-child(1),
69 | .djs-frame.drop-not-ok .djs-visual > :nth-child(1) {
70 | stroke-width: 3px !important;
71 | stroke: #E56283 /* light-red */ !important;
72 | fill: none !important;
73 | }
74 |
75 | /**
76 | * Selection box style
77 | *
78 | */
79 | .djs-lasso-overlay {
80 | fill: rgb(255, 116, 0);
81 | fill-opacity: 0.1;
82 |
83 | stroke-dasharray: 5 1 3 1;
84 | stroke: rgb(255, 116, 0);
85 |
86 | shape-rendering: crispEdges;
87 | pointer-events: none;
88 | }
89 |
90 | /**
91 | * Resize styles
92 | */
93 | .djs-resize-overlay {
94 | fill: none;
95 |
96 | stroke-dasharray: 5 1 3 1;
97 | stroke: rgb(255, 116, 0);
98 |
99 | pointer-events: none;
100 | }
101 |
102 | .djs-resizer-hit {
103 | fill: none;
104 | pointer-events: all;
105 | }
106 |
107 | .djs-resizer-visual {
108 | fill: white;
109 | stroke-width: 1px;
110 | stroke: black;
111 | shape-rendering: crispEdges;
112 | stroke-opacity: 0.2;
113 | }
114 |
115 | .djs-cursor-resize-nwse,
116 | .djs-resizer-nw,
117 | .djs-resizer-se {
118 | cursor: nwse-resize;
119 | }
120 |
121 | .djs-cursor-resize-nesw,
122 | .djs-resizer-ne,
123 | .djs-resizer-sw {
124 | cursor: nesw-resize;
125 | }
126 |
127 | .djs-shape.djs-resizing > .djs-outline {
128 | visibility: hidden !important;
129 | }
130 |
131 | .djs-shape.djs-resizing > .djs-resizer {
132 | visibility: hidden;
133 | }
134 |
135 | .djs-dragger > .djs-resizer {
136 | visibility: hidden;
137 | }
138 |
139 | /**
140 | * drag styles
141 | */
142 | .djs-dragger * {
143 | fill: none !important;
144 | stroke: rgb(255, 116, 0) !important;
145 | }
146 |
147 | .djs-dragger tspan,
148 | .djs-dragger text {
149 | fill: rgb(255, 116, 0) !important;
150 | stroke: none !important;
151 | }
152 |
153 | marker.djs-dragger circle,
154 | marker.djs-dragger path,
155 | marker.djs-dragger polygon,
156 | marker.djs-dragger polyline,
157 | marker.djs-dragger rect {
158 | fill: rgb(255, 116, 0) !important;
159 | stroke: none !important;
160 | }
161 |
162 | marker.djs-dragger text,
163 | marker.djs-dragger tspan {
164 | fill: none !important;
165 | stroke: rgb(255, 116, 0) !important;
166 | }
167 |
168 | .djs-dragging {
169 | opacity: 0.3;
170 | }
171 |
172 | .djs-dragging,
173 | .djs-dragging > * {
174 | pointer-events: none !important;
175 | }
176 |
177 | .djs-dragging .djs-context-pad,
178 | .djs-dragging .djs-outline {
179 | display: none !important;
180 | }
181 |
182 | /**
183 | * no pointer events for visual
184 | */
185 | .djs-visual,
186 | .djs-outline {
187 | pointer-events: none;
188 | }
189 |
190 | .djs-element.attach-ok .djs-hit {
191 | stroke-width: 60px !important;
192 | }
193 |
194 | /**
195 | * all pointer events for hit shape
196 | */
197 | .djs-element > .djs-hit-all {
198 | pointer-events: all;
199 | }
200 |
201 | .djs-element > .djs-hit-stroke,
202 | .djs-element > .djs-hit-click-stroke {
203 | pointer-events: stroke;
204 | }
205 |
206 | /**
207 | * all pointer events for hit shape
208 | */
209 | .djs-drag-active .djs-element > .djs-hit-click-stroke {
210 | pointer-events: all;
211 | }
212 |
213 | /**
214 | * shape / connection basic styles
215 | */
216 | .djs-connection .djs-visual {
217 | stroke-width: 2px;
218 | fill: none;
219 | }
220 |
221 | .djs-cursor-grab {
222 | cursor: -webkit-grab;
223 | cursor: -moz-grab;
224 | cursor: grab;
225 | }
226 |
227 | .djs-cursor-grabbing {
228 | cursor: -webkit-grabbing;
229 | cursor: -moz-grabbing;
230 | cursor: grabbing;
231 | }
232 |
233 | .djs-cursor-crosshair {
234 | cursor: crosshair;
235 | }
236 |
237 | .djs-cursor-move {
238 | cursor: move;
239 | }
240 |
241 | .djs-cursor-resize-ns {
242 | cursor: ns-resize;
243 | }
244 |
245 | .djs-cursor-resize-ew {
246 | cursor: ew-resize;
247 | }
248 |
249 |
250 | /**
251 | * snapping
252 | */
253 | .djs-snap-line {
254 | stroke: rgb(255, 195, 66);
255 | stroke: rgba(255, 195, 66, 0.50);
256 | stroke-linecap: round;
257 | stroke-width: 2px;
258 | pointer-events: none;
259 | }
260 |
261 | /**
262 | * snapping
263 | */
264 | .djs-crosshair {
265 | stroke: #555;
266 | stroke-linecap: round;
267 | stroke-width: 1px;
268 | pointer-events: none;
269 | shape-rendering: crispEdges;
270 | stroke-dasharray: 5, 5;
271 | }
272 |
273 | /**
274 | * palette
275 | */
276 |
277 | .djs-palette {
278 | position: absolute;
279 | left: 20px;
280 | top: 20px;
281 |
282 | box-sizing: border-box;
283 | width: 48px;
284 | }
285 |
286 | .djs-palette .separator {
287 | margin: 0 5px;
288 | padding-top: 5px;
289 |
290 | border: none;
291 | border-bottom: solid 1px #DDD;
292 |
293 | clear: both;
294 | }
295 |
296 | .djs-palette .entry:before {
297 | vertical-align: text-bottom;
298 | }
299 |
300 | .djs-palette .djs-palette-toggle {
301 | cursor: pointer;
302 | }
303 |
304 | .djs-palette .entry,
305 | .djs-palette .djs-palette-toggle {
306 | color: #333;
307 | font-size: 30px;
308 |
309 | text-align: center;
310 | }
311 |
312 | .djs-palette .entry {
313 | float: left;
314 | }
315 |
316 | .djs-palette .entry img {
317 | max-width: 100%;
318 | }
319 |
320 | .djs-palette .djs-palette-entries:after {
321 | content: '';
322 | display: table;
323 | clear: both;
324 | }
325 |
326 | .djs-palette .djs-palette-toggle:hover {
327 | background: #666;
328 | }
329 |
330 | .djs-palette .entry:hover {
331 | color: rgb(255, 116, 0);
332 | }
333 |
334 | .djs-palette .highlighted-entry {
335 | color: rgb(255, 116, 0) !important;
336 | }
337 |
338 | .djs-palette .entry,
339 | .djs-palette .djs-palette-toggle {
340 | width: 46px;
341 | height: 46px;
342 | line-height: 46px;
343 | cursor: default;
344 | }
345 |
346 | /**
347 | * Palette open / two-column layout is controlled via
348 | * classes on the palette. Events to hook into palette
349 | * changed life-cycle are available in addition.
350 | */
351 | .djs-palette.two-column.open {
352 | width: 94px;
353 | }
354 |
355 | .djs-palette:not(.open) .djs-palette-entries {
356 | display: none;
357 | }
358 |
359 | .djs-palette:not(.open) {
360 | overflow: hidden;
361 | }
362 |
363 | .djs-palette.open .djs-palette-toggle {
364 | display: none;
365 | }
366 |
367 | /**
368 | * context-pad
369 | */
370 | .djs-overlay-context-pad {
371 | width: 72px;
372 | }
373 |
374 | .djs-context-pad {
375 | position: absolute;
376 | display: none;
377 | pointer-events: none;
378 | }
379 |
380 | .djs-context-pad .entry {
381 | width: 22px;
382 | height: 22px;
383 | text-align: center;
384 | display: inline-block;
385 | font-size: 22px;
386 | margin: 0 2px 2px 0;
387 |
388 | border-radius: 3px;
389 |
390 | cursor: default;
391 |
392 | background-color: #FEFEFE;
393 | box-shadow: 0 0 2px 1px #FEFEFE;
394 | pointer-events: all;
395 | }
396 |
397 | .djs-context-pad .entry:before {
398 | vertical-align: top;
399 | }
400 |
401 | .djs-context-pad .entry:hover {
402 | background: rgb(255, 252, 176);
403 | }
404 |
405 | .djs-context-pad.open {
406 | display: block;
407 | }
408 |
409 | /**
410 | * popup styles
411 | */
412 | .djs-popup .entry {
413 | line-height: 20px;
414 | white-space: nowrap;
415 | cursor: default;
416 | }
417 |
418 | /* larger font for prefixed icons */
419 | .djs-popup .entry:before {
420 | vertical-align: middle;
421 | font-size: 20px;
422 | }
423 |
424 | .djs-popup .entry > span {
425 | vertical-align: middle;
426 | font-size: 14px;
427 | }
428 |
429 | .djs-popup .entry:hover,
430 | .djs-popup .entry.active:hover {
431 | background: rgb(255, 252, 176);
432 | }
433 |
434 | .djs-popup .entry.disabled {
435 | background: inherit;
436 | }
437 |
438 | .djs-popup .djs-popup-header .entry {
439 | display: inline-block;
440 | padding: 2px 3px 2px 3px;
441 |
442 | border: solid 1px transparent;
443 | border-radius: 3px;
444 | }
445 |
446 | .djs-popup .djs-popup-header .entry.active {
447 | color: rgb(255, 116, 0);
448 | border: solid 1px rgb(255, 116, 0);
449 | background-color: #F6F6F6;
450 | }
451 |
452 | .djs-popup-body .entry {
453 | padding: 4px 10px 4px 5px;
454 | }
455 |
456 | .djs-popup-body .entry > span {
457 | margin-left: 5px;
458 | }
459 |
460 | .djs-popup-body {
461 | background-color: #FEFEFE;
462 | }
463 |
464 | .djs-popup-header {
465 | border-bottom: 1px solid #DDD;
466 | }
467 |
468 | .djs-popup-header .entry {
469 | margin: 1px;
470 | margin-left: 3px;
471 | }
472 |
473 | .djs-popup-header .entry:last-child {
474 | margin-right: 3px;
475 | }
476 |
477 | /**
478 | * popup / palette styles
479 | */
480 | .djs-popup, .djs-palette {
481 | background: #FAFAFA;
482 | border: solid 1px #CCC;
483 | border-radius: 2px;
484 | }
485 |
486 | /**
487 | * touch
488 | */
489 |
490 | .djs-shape,
491 | .djs-connection {
492 | touch-action: none;
493 | }
494 |
495 | .djs-segment-dragger,
496 | .djs-bendpoint {
497 | display: none;
498 | }
499 |
500 | /**
501 | * bendpoints
502 | */
503 | .djs-segment-dragger .djs-visual {
504 | fill: rgba(255, 255, 121, 0.2);
505 | stroke-width: 1px;
506 | stroke-opacity: 1;
507 | stroke: rgba(255, 255, 121, 0.3);
508 | }
509 |
510 | .djs-bendpoint .djs-visual {
511 | fill: rgba(255, 255, 121, 0.8);
512 | stroke-width: 1px;
513 | stroke-opacity: 0.5;
514 | stroke: black;
515 | }
516 |
517 | .djs-segment-dragger:hover,
518 | .djs-bendpoints.hover .djs-segment-dragger,
519 | .djs-bendpoints.selected .djs-segment-dragger,
520 | .djs-bendpoint:hover,
521 | .djs-bendpoints.hover .djs-bendpoint,
522 | .djs-bendpoints.selected .djs-bendpoint {
523 | display: block;
524 | }
525 |
526 | .djs-drag-active .djs-bendpoints * {
527 | display: none;
528 | }
529 |
530 | .djs-bendpoints:not(.hover) .floating {
531 | display: none;
532 | }
533 |
534 | .djs-segment-dragger:hover .djs-visual,
535 | .djs-segment-dragger.djs-dragging .djs-visual,
536 | .djs-bendpoint:hover .djs-visual,
537 | .djs-bendpoint.floating .djs-visual {
538 | fill: yellow;
539 | stroke-opacity: 0.5;
540 | stroke: black;
541 | }
542 |
543 | .djs-bendpoint.floating .djs-hit {
544 | pointer-events: none;
545 | }
546 |
547 | .djs-segment-dragger .djs-hit,
548 | .djs-bendpoint .djs-hit {
549 | pointer-events: all;
550 | fill: none;
551 | }
552 |
553 | .djs-segment-dragger.horizontal .djs-hit {
554 | cursor: ns-resize;
555 | }
556 |
557 | .djs-segment-dragger.vertical .djs-hit {
558 | cursor: ew-resize;
559 | }
560 |
561 | .djs-segment-dragger.djs-dragging .djs-hit {
562 | pointer-events: none;
563 | }
564 |
565 | .djs-updating,
566 | .djs-updating > * {
567 | pointer-events: none !important;
568 | }
569 |
570 | .djs-updating .djs-context-pad,
571 | .djs-updating .djs-outline,
572 | .djs-updating .djs-bendpoint,
573 | .connect-ok .djs-bendpoint,
574 | .connect-not-ok .djs-bendpoint,
575 | .drop-ok .djs-bendpoint,
576 | .drop-not-ok .djs-bendpoint {
577 | display: none !important;
578 | }
579 |
580 | .djs-segment-dragger.djs-dragging,
581 | .djs-bendpoint.djs-dragging {
582 | display: block;
583 | opacity: 1.0;
584 | }
585 |
586 | .djs-segment-dragger.djs-dragging .djs-visual,
587 | .djs-bendpoint.djs-dragging .djs-visual {
588 | fill: yellow;
589 | stroke-opacity: 0.5;
590 | }
591 |
592 |
593 | /**
594 | * tooltips
595 | */
596 | .djs-tooltip-error {
597 | font-size: 11px;
598 | line-height: 18px;
599 | text-align: left;
600 |
601 | padding: 5px;
602 |
603 | opacity: 0.7;
604 | }
605 |
606 | .djs-tooltip-error > * {
607 | width: 160px;
608 |
609 | background: rgb(252, 236, 240);
610 | color: rgb(158, 76, 76);
611 | padding: 3px 7px;
612 | border-radius: 5px;
613 | border-left: solid 5px rgb(174, 73, 73);
614 | }
615 |
616 | .djs-tooltip-error:hover {
617 | opacity: 1;
618 | }
619 |
620 |
621 | /**
622 | * search pad
623 | */
624 | .djs-search-container {
625 | position: absolute;
626 | top: 20px;
627 | left: 0;
628 | right: 0;
629 | margin-left: auto;
630 | margin-right: auto;
631 |
632 | width: 25%;
633 | min-width: 300px;
634 | max-width: 400px;
635 | z-index: 10;
636 |
637 | font-size: 1.05em;
638 | opacity: 0.9;
639 | background: #FAFAFA;
640 | border: solid 1px #CCC;
641 | border-radius: 2px;
642 | }
643 |
644 | .djs-search-container:not(.open) {
645 | display: none;
646 | }
647 |
648 | .djs-search-input input {
649 | font-size: 1.05em;
650 | width: 100%;
651 | padding: 6px 10px;
652 | border: 1px solid #ccc;
653 | }
654 |
655 | .djs-search-input input:focus {
656 | outline: none;
657 | border-color: #52B415;
658 | }
659 |
660 | .djs-search-results {
661 | position: relative;
662 | overflow-y: auto;
663 | max-height: 200px;
664 | }
665 |
666 | .djs-search-results:hover {
667 | /*background: #fffdd7;*/
668 | cursor: pointer;
669 | }
670 |
671 | .djs-search-result {
672 | width: 100%;
673 | padding: 6px 10px;
674 | background: white;
675 | border-bottom: solid 1px #AAA;
676 | border-radius: 1px;
677 | }
678 |
679 | .djs-search-highlight {
680 | color: black;
681 | }
682 |
683 | .djs-search-result-primary {
684 | margin: 0 0 10px;
685 | }
686 |
687 | .djs-search-result-secondary {
688 | font-family: monospace;
689 | margin: 0;
690 | }
691 |
692 | .djs-search-result:hover {
693 | background: #fdffd6;
694 | }
695 |
696 | .djs-search-result-selected {
697 | background: #fffcb0;
698 | }
699 |
700 | .djs-search-result-selected:hover {
701 | background: #f7f388;
702 | }
703 |
704 | .djs-search-overlay {
705 | background: yellow;
706 | opacity: 0.3;
707 | }
708 |
709 | /**
710 | * hidden styles
711 | */
712 | .djs-element-hidden,
713 | .djs-element-hidden .djs-hit,
714 | .djs-element-hidden .djs-outline,
715 | .djs-label-hidden .djs-label {
716 | display: none !important;
717 | }
718 |
--------------------------------------------------------------------------------
/chrome-ext/src/static/vendor/css/diagram-js-cmmn.css:
--------------------------------------------------------------------------------
1 | /**
2 | * outline styles
3 | */
4 |
5 | .djs-outline {
6 | fill: none;
7 | visibility: hidden;
8 | }
9 |
10 | .djs-element.hover .djs-outline,
11 | .djs-element.selected .djs-outline {
12 | visibility: visible;
13 | shape-rendering: crispEdges;
14 | stroke-dasharray: 3,3;
15 | }
16 |
17 | .djs-element.selected .djs-outline {
18 | stroke: #8888FF;
19 | stroke-width: 1px;
20 | }
21 |
22 | .djs-element.hover .djs-outline {
23 | stroke: #FF8888;
24 | stroke-width: 1px;
25 | }
26 |
27 | .djs-shape.connect-ok .djs-visual > :nth-child(1) {
28 | fill: #DCFECC /* light-green */ !important;
29 | }
30 |
31 | .djs-shape.connect-not-ok .djs-visual > :nth-child(1),
32 | .djs-shape.drop-not-ok .djs-visual > :nth-child(1) {
33 | fill: #f9dee5 /* light-red */ !important;
34 | }
35 |
36 | .djs-shape.new-parent .djs-visual > :nth-child(1) {
37 | fill: #F7F9FF !important;
38 | }
39 |
40 | svg.drop-not-ok {
41 | background: #f9dee5 /* light-red */ !important;
42 | }
43 |
44 | svg.new-parent {
45 | background: #F7F9FF /* light-blue */ !important;
46 | }
47 |
48 | .djs-connection.connect-ok .djs-visual > :nth-child(1),
49 | .djs-connection.drop-ok .djs-visual > :nth-child(1) {
50 | stroke: #90DD5F /* light-green */ !important;
51 | }
52 |
53 | .djs-connection.connect-not-ok .djs-visual > :nth-child(1),
54 | .djs-connection.drop-not-ok .djs-visual > :nth-child(1) {
55 | stroke: #E56283 /* light-red */ !important;
56 | }
57 |
58 | .drop-not-ok,
59 | .connect-not-ok {
60 | cursor: not-allowed;
61 | }
62 |
63 | .djs-element.attach-ok .djs-visual > :nth-child(1) {
64 | stroke-width: 5px !important;
65 | stroke: rgba(255, 116, 0, 0.7) !important;
66 | }
67 |
68 | .djs-frame.connect-not-ok .djs-visual > :nth-child(1),
69 | .djs-frame.drop-not-ok .djs-visual > :nth-child(1) {
70 | stroke-width: 3px !important;
71 | stroke: #E56283 /* light-red */ !important;
72 | fill: none !important;
73 | }
74 |
75 | /**
76 | * Selection box style
77 | *
78 | */
79 | .djs-lasso-overlay {
80 | fill: rgb(255, 116, 0);
81 | fill-opacity: 0.1;
82 |
83 | stroke-dasharray: 5 1 3 1;
84 | stroke: rgb(255, 116, 0);
85 |
86 | shape-rendering: crispEdges;
87 | pointer-events: none;
88 | }
89 |
90 | /**
91 | * Resize styles
92 | */
93 | .djs-resize-overlay {
94 | fill: none;
95 |
96 | stroke-dasharray: 5 1 3 1;
97 | stroke: rgb(255, 116, 0);
98 |
99 | pointer-events: none;
100 | }
101 |
102 | .djs-resizer-hit {
103 | fill: none;
104 | pointer-events: all;
105 | }
106 |
107 | .djs-resizer-visual {
108 | fill: white;
109 | stroke-width: 1px;
110 | stroke: black;
111 | shape-rendering: crispEdges;
112 | stroke-opacity: 0.2;
113 | }
114 |
115 | .djs-cursor-resize-nwse,
116 | .djs-resizer-nw,
117 | .djs-resizer-se {
118 | cursor: nwse-resize;
119 | }
120 |
121 | .djs-cursor-resize-nesw,
122 | .djs-resizer-ne,
123 | .djs-resizer-sw {
124 | cursor: nesw-resize;
125 | }
126 |
127 | .djs-shape.djs-resizing > .djs-outline {
128 | visibility: hidden !important;
129 | }
130 |
131 | .djs-shape.djs-resizing > .djs-resizer {
132 | visibility: hidden;
133 | }
134 |
135 | .djs-dragger > .djs-resizer {
136 | visibility: hidden;
137 | }
138 |
139 | /**
140 | * drag styles
141 | */
142 | .djs-dragger * {
143 | fill: none !important;
144 | stroke: rgb(255, 116, 0) !important;
145 | }
146 |
147 | .djs-dragger tspan,
148 | .djs-dragger text {
149 | fill: rgb(255, 116, 0) !important;
150 | stroke: none !important;
151 | }
152 |
153 | marker.djs-dragger circle,
154 | marker.djs-dragger path,
155 | marker.djs-dragger polygon,
156 | marker.djs-dragger polyline,
157 | marker.djs-dragger rect {
158 | fill: rgb(255, 116, 0) !important;
159 | stroke: none !important;
160 | }
161 |
162 | marker.djs-dragger text,
163 | marker.djs-dragger tspan {
164 | fill: none !important;
165 | stroke: rgb(255, 116, 0) !important;
166 | }
167 |
168 | .djs-dragging {
169 | opacity: 0.3;
170 | }
171 |
172 | .djs-dragging,
173 | .djs-dragging > * {
174 | pointer-events: none !important;
175 | }
176 |
177 | .djs-dragging .djs-context-pad,
178 | .djs-dragging .djs-outline {
179 | display: none !important;
180 | }
181 |
182 | /**
183 | * no pointer events for visual
184 | */
185 | .djs-visual,
186 | .djs-outline {
187 | pointer-events: none;
188 | }
189 |
190 | .djs-element.attach-ok .djs-hit {
191 | stroke-width: 60px !important;
192 | }
193 |
194 | /**
195 | * all pointer events for hit shape
196 | */
197 | .djs-shape .djs-hit {
198 | pointer-events: all;
199 | }
200 |
201 | .djs-connection .djs-hit {
202 | pointer-events: stroke;
203 | }
204 |
205 | .djs-frame .djs-hit {
206 | pointer-events: stroke;
207 | }
208 |
209 | /**
210 | * shape / connection basic styles
211 | */
212 | .djs-connection .djs-visual {
213 | stroke-width: 2px;
214 | fill: none;
215 | }
216 |
217 | .djs-cursor-grab {
218 | cursor: -webkit-grab;
219 | cursor: -moz-grab;
220 | cursor: grab;
221 | }
222 |
223 | .djs-cursor-grabbing {
224 | cursor: -webkit-grabbing;
225 | cursor: -moz-grabbing;
226 | cursor: grabbing;
227 | }
228 |
229 | .djs-cursor-crosshair {
230 | cursor: crosshair;
231 | }
232 |
233 | .djs-cursor-move {
234 | cursor: move;
235 | }
236 |
237 | .djs-cursor-resize-ns {
238 | cursor: ns-resize;
239 | }
240 |
241 | .djs-cursor-resize-ew {
242 | cursor: ew-resize;
243 | }
244 |
245 |
246 | /**
247 | * snapping
248 | */
249 | .djs-snap-line {
250 | stroke: rgb(255, 195, 66);
251 | stroke: rgba(255, 195, 66, 0.50);
252 | stroke-linecap: round;
253 | stroke-width: 2px;
254 | pointer-events: none;
255 | }
256 |
257 | /**
258 | * snapping
259 | */
260 | .djs-crosshair {
261 | stroke: #555;
262 | stroke-linecap: round;
263 | stroke-width: 1px;
264 | pointer-events: none;
265 | shape-rendering: crispEdges;
266 | stroke-dasharray: 5, 5;
267 | }
268 |
269 | /**
270 | * palette
271 | */
272 |
273 | .djs-palette {
274 | position: absolute;
275 | left: 20px;
276 | top: 20px;
277 |
278 | box-sizing: border-box;
279 | width: 48px;
280 | }
281 |
282 | .djs-palette .separator {
283 | margin: 0 5px;
284 | padding-top: 5px;
285 |
286 | border: none;
287 | border-bottom: solid 1px #DDD;
288 |
289 | clear: both;
290 | }
291 |
292 | .djs-palette .entry:before {
293 | vertical-align: text-bottom;
294 | }
295 |
296 | .djs-palette .djs-palette-toggle {
297 | cursor: pointer;
298 | }
299 |
300 | .djs-palette .entry,
301 | .djs-palette .djs-palette-toggle {
302 | color: #333;
303 | font-size: 30px;
304 |
305 | text-align: center;
306 | }
307 |
308 | .djs-palette .entry {
309 | float: left;
310 | }
311 |
312 | .djs-palette .entry img {
313 | max-width: 100%;
314 | }
315 |
316 | .djs-palette .djs-palette-entries:after {
317 | content: '';
318 | display: table;
319 | clear: both;
320 | }
321 |
322 | .djs-palette .djs-palette-toggle:hover {
323 | background: #666;
324 | }
325 |
326 | .djs-palette .entry:hover {
327 | color: rgb(255, 116, 0);
328 | }
329 |
330 | .djs-palette .highlighted-entry {
331 | color: rgb(255, 116, 0) !important;
332 | }
333 |
334 | .djs-palette .entry,
335 | .djs-palette .djs-palette-toggle {
336 | width: 46px;
337 | height: 46px;
338 | line-height: 46px;
339 | cursor: default;
340 | }
341 |
342 | /**
343 | * Palette open / two-column layout is controlled via
344 | * classes on the palette. Events to hook into palette
345 | * changed life-cycle are available in addition.
346 | */
347 | .djs-palette.two-column.open {
348 | width: 94px;
349 | }
350 |
351 | .djs-palette:not(.open) .djs-palette-entries {
352 | display: none;
353 | }
354 |
355 | .djs-palette:not(.open) {
356 | overflow: hidden;
357 | }
358 |
359 | .djs-palette.open .djs-palette-toggle {
360 | display: none;
361 | }
362 |
363 | /**
364 | * context-pad
365 | */
366 | .djs-overlay-context-pad {
367 | width: 72px;
368 | }
369 |
370 | .djs-context-pad {
371 | position: absolute;
372 | display: none;
373 | pointer-events: none;
374 | }
375 |
376 | .djs-context-pad .entry {
377 | width: 22px;
378 | height: 22px;
379 | text-align: center;
380 | display: inline-block;
381 | font-size: 22px;
382 | margin: 0 2px 2px 0;
383 |
384 | border-radius: 3px;
385 |
386 | cursor: default;
387 |
388 | background-color: #FEFEFE;
389 | box-shadow: 0 0 2px 1px #FEFEFE;
390 | pointer-events: all;
391 | }
392 |
393 | .djs-context-pad .entry:before {
394 | vertical-align: top;
395 | }
396 |
397 | .djs-context-pad .entry:hover {
398 | background: rgb(255, 252, 176);
399 | }
400 |
401 | .djs-context-pad.open {
402 | display: block;
403 | }
404 |
405 | /**
406 | * popup styles
407 | */
408 | .djs-popup .entry {
409 | line-height: 20px;
410 | white-space: nowrap;
411 | cursor: default;
412 | }
413 |
414 | /* larger font for prefixed icons */
415 | .djs-popup .entry:before {
416 | vertical-align: middle;
417 | font-size: 20px;
418 | }
419 |
420 | .djs-popup .entry > span {
421 | vertical-align: middle;
422 | font-size: 14px;
423 | }
424 |
425 | .djs-popup .entry:hover,
426 | .djs-popup .entry.active:hover {
427 | background: rgb(255, 252, 176);
428 | }
429 |
430 | .djs-popup .entry.disabled {
431 | background: inherit;
432 | }
433 |
434 | .djs-popup .djs-popup-header .entry {
435 | display: inline-block;
436 | padding: 2px 3px 2px 3px;
437 |
438 | border: solid 1px transparent;
439 | border-radius: 3px;
440 | }
441 |
442 | .djs-popup .djs-popup-header .entry.active {
443 | color: rgb(255, 116, 0);
444 | border: solid 1px rgb(255, 116, 0);
445 | background-color: #F6F6F6;
446 | }
447 |
448 | .djs-popup-body .entry {
449 | padding: 4px 10px 4px 5px;
450 | }
451 |
452 | .djs-popup-body .entry > span {
453 | margin-left: 5px;
454 | }
455 |
456 | .djs-popup-body {
457 | background-color: #FEFEFE;
458 | }
459 |
460 | .djs-popup-header {
461 | border-bottom: 1px solid #DDD;
462 | }
463 |
464 | .djs-popup-header .entry {
465 | margin: 1px;
466 | margin-left: 3px;
467 | }
468 |
469 | .djs-popup-header .entry:last-child {
470 | margin-right: 3px;
471 | }
472 |
473 | /**
474 | * popup / palette styles
475 | */
476 | .djs-popup, .djs-palette {
477 | background: #FAFAFA;
478 | border: solid 1px #CCC;
479 | border-radius: 2px;
480 | }
481 |
482 | /**
483 | * touch
484 | */
485 |
486 | .djs-shape,
487 | .djs-connection {
488 | touch-action: none;
489 | }
490 |
491 | .djs-segment-dragger,
492 | .djs-bendpoint {
493 | display: none;
494 | }
495 |
496 | /**
497 | * bendpoints
498 | */
499 | .djs-segment-dragger .djs-visual {
500 | fill: rgba(255, 255, 121, 0.2);
501 | stroke-width: 1px;
502 | stroke-opacity: 1;
503 | stroke: rgba(255, 255, 121, 0.3);
504 | }
505 |
506 | .djs-bendpoint .djs-visual {
507 | fill: rgba(255, 255, 121, 0.8);
508 | stroke-width: 1px;
509 | stroke-opacity: 0.5;
510 | stroke: black;
511 | }
512 |
513 | .djs-segment-dragger:hover,
514 | .djs-bendpoints.hover .djs-segment-dragger,
515 | .djs-bendpoints.selected .djs-segment-dragger,
516 | .djs-bendpoint:hover,
517 | .djs-bendpoints.hover .djs-bendpoint,
518 | .djs-bendpoints.selected .djs-bendpoint {
519 | display: block;
520 | }
521 |
522 | .djs-drag-active .djs-bendpoints * {
523 | display: none;
524 | }
525 |
526 | .djs-bendpoints:not(.hover) .floating {
527 | display: none;
528 | }
529 |
530 | .djs-segment-dragger:hover .djs-visual,
531 | .djs-segment-dragger.djs-dragging .djs-visual,
532 | .djs-bendpoint:hover .djs-visual,
533 | .djs-bendpoint.floating .djs-visual {
534 | fill: yellow;
535 | stroke-opacity: 0.5;
536 | stroke: black;
537 | }
538 |
539 | .djs-bendpoint.floating .djs-hit {
540 | pointer-events: none;
541 | }
542 |
543 | .djs-segment-dragger .djs-hit,
544 | .djs-bendpoint .djs-hit {
545 | pointer-events: all;
546 | fill: none;
547 | }
548 |
549 | .djs-segment-dragger.horizontal .djs-hit {
550 | cursor: ns-resize;
551 | }
552 |
553 | .djs-segment-dragger.vertical .djs-hit {
554 | cursor: ew-resize;
555 | }
556 |
557 | .djs-segment-dragger.djs-dragging .djs-hit {
558 | pointer-events: none;
559 | }
560 |
561 | .djs-updating,
562 | .djs-updating > * {
563 | pointer-events: none !important;
564 | }
565 |
566 | .djs-updating .djs-context-pad,
567 | .djs-updating .djs-outline,
568 | .djs-updating .djs-bendpoint,
569 | .connect-ok .djs-bendpoint,
570 | .connect-not-ok .djs-bendpoint,
571 | .drop-ok .djs-bendpoint,
572 | .drop-not-ok .djs-bendpoint {
573 | display: none !important;
574 | }
575 |
576 | .djs-segment-dragger.djs-dragging,
577 | .djs-bendpoint.djs-dragging {
578 | display: block;
579 | opacity: 1.0;
580 | }
581 |
582 | .djs-segment-dragger.djs-dragging .djs-visual,
583 | .djs-bendpoint.djs-dragging .djs-visual {
584 | fill: yellow;
585 | stroke-opacity: 0.5;
586 | }
587 |
588 |
589 | /**
590 | * tooltips
591 | */
592 | .djs-tooltip-error {
593 | font-size: 11px;
594 | line-height: 18px;
595 | text-align: left;
596 |
597 | padding: 5px;
598 |
599 | opacity: 0.7;
600 | }
601 |
602 | .djs-tooltip-error > * {
603 | width: 160px;
604 |
605 | background: rgb(252, 236, 240);
606 | color: rgb(158, 76, 76);
607 | padding: 3px 7px;
608 | border-radius: 5px;
609 | border-left: solid 5px rgb(174, 73, 73);
610 | }
611 |
612 | .djs-tooltip-error:hover {
613 | opacity: 1;
614 | }
615 |
616 |
617 | /**
618 | * search pad
619 | */
620 | .djs-search-container {
621 | position: absolute;
622 | top: 20px;
623 | left: 0;
624 | right: 0;
625 | margin-left: auto;
626 | margin-right: auto;
627 |
628 | width: 25%;
629 | min-width: 300px;
630 | max-width: 400px;
631 | z-index: 10;
632 |
633 | font-size: 1.05em;
634 | opacity: 0.9;
635 | background: #FAFAFA;
636 | border: solid 1px #CCC;
637 | border-radius: 2px;
638 | }
639 |
640 | .djs-search-container:not(.open) {
641 | display: none;
642 | }
643 |
644 | .djs-search-input input {
645 | font-size: 1.05em;
646 | width: 100%;
647 | padding: 6px 10px;
648 | border: 1px solid #ccc;
649 | }
650 |
651 | .djs-search-input input:focus {
652 | outline: none;
653 | border-color: #52B415;
654 | }
655 |
656 | .djs-search-results {
657 | position: relative;
658 | overflow-y: auto;
659 | max-height: 200px;
660 | }
661 |
662 | .djs-search-results:hover {
663 | /*background: #fffdd7;*/
664 | cursor: pointer;
665 | }
666 |
667 | .djs-search-result {
668 | width: 100%;
669 | padding: 6px 10px;
670 | background: white;
671 | border-bottom: solid 1px #AAA;
672 | border-radius: 1px;
673 | }
674 |
675 | .djs-search-highlight {
676 | color: black;
677 | }
678 |
679 | .djs-search-result-primary {
680 | margin: 0 0 10px;
681 | }
682 |
683 | .djs-search-result-secondary {
684 | font-family: monospace;
685 | margin: 0;
686 | }
687 |
688 | .djs-search-result:hover {
689 | background: #fdffd6;
690 | }
691 |
692 | .djs-search-result-selected {
693 | background: #fffcb0;
694 | }
695 |
696 | .djs-search-result-selected:hover {
697 | background: #f7f388;
698 | }
699 |
700 | .djs-search-overlay {
701 | background: yellow;
702 | opacity: 0.3;
703 | }
704 |
705 | /**
706 | * hidden styles
707 | */
708 | .djs-element-hidden,
709 | .djs-element-hidden .djs-hit,
710 | .djs-element-hidden .djs-outline,
711 | .djs-label-hidden .djs-label {
712 | display: none !important;
713 | }
714 |
--------------------------------------------------------------------------------
/chrome-ext/src/static/vendor/css/diagram-js-dmn.css:
--------------------------------------------------------------------------------
1 | /**
2 | * outline styles
3 | */
4 |
5 | .djs-outline {
6 | fill: none;
7 | visibility: hidden;
8 | }
9 |
10 | .djs-element.hover .djs-outline,
11 | .djs-element.selected .djs-outline {
12 | visibility: visible;
13 | shape-rendering: crispEdges;
14 | stroke-dasharray: 3,3;
15 | }
16 |
17 | .djs-element.selected .djs-outline {
18 | stroke: #8888FF;
19 | stroke-width: 1px;
20 | }
21 |
22 | .djs-element.hover .djs-outline {
23 | stroke: #FF8888;
24 | stroke-width: 1px;
25 | }
26 |
27 | .djs-shape.connect-ok .djs-visual > :nth-child(1) {
28 | fill: #DCFECC /* light-green */ !important;
29 | }
30 |
31 | .djs-shape.connect-not-ok .djs-visual > :nth-child(1),
32 | .djs-shape.drop-not-ok .djs-visual > :nth-child(1) {
33 | fill: #f9dee5 /* light-red */ !important;
34 | }
35 |
36 | .djs-shape.new-parent .djs-visual > :nth-child(1) {
37 | fill: #F7F9FF !important;
38 | }
39 |
40 | svg.drop-not-ok {
41 | background: #f9dee5 /* light-red */ !important;
42 | }
43 |
44 | svg.new-parent {
45 | background: #F7F9FF /* light-blue */ !important;
46 | }
47 |
48 | .djs-connection.connect-ok .djs-visual > :nth-child(1),
49 | .djs-connection.drop-ok .djs-visual > :nth-child(1) {
50 | stroke: #90DD5F /* light-green */ !important;
51 | }
52 |
53 | .djs-connection.connect-not-ok .djs-visual > :nth-child(1),
54 | .djs-connection.drop-not-ok .djs-visual > :nth-child(1) {
55 | stroke: #E56283 /* light-red */ !important;
56 | }
57 |
58 | .drop-not-ok,
59 | .connect-not-ok {
60 | cursor: not-allowed;
61 | }
62 |
63 | .djs-element.attach-ok .djs-visual > :nth-child(1) {
64 | stroke-width: 5px !important;
65 | stroke: rgba(255, 116, 0, 0.7) !important;
66 | }
67 |
68 | .djs-frame.connect-not-ok .djs-visual > :nth-child(1),
69 | .djs-frame.drop-not-ok .djs-visual > :nth-child(1) {
70 | stroke-width: 3px !important;
71 | stroke: #E56283 /* light-red */ !important;
72 | fill: none !important;
73 | }
74 |
75 | /**
76 | * Selection box style
77 | *
78 | */
79 | .djs-lasso-overlay {
80 | fill: rgb(255, 116, 0);
81 | fill-opacity: 0.1;
82 |
83 | stroke-dasharray: 5 1 3 1;
84 | stroke: rgb(255, 116, 0);
85 |
86 | shape-rendering: crispEdges;
87 | pointer-events: none;
88 | }
89 |
90 | /**
91 | * Resize styles
92 | */
93 | .djs-resize-overlay {
94 | fill: none;
95 |
96 | stroke-dasharray: 5 1 3 1;
97 | stroke: rgb(255, 116, 0);
98 |
99 | pointer-events: none;
100 | }
101 |
102 | .djs-resizer-hit {
103 | fill: none;
104 | pointer-events: all;
105 | }
106 |
107 | .djs-resizer-visual {
108 | fill: white;
109 | stroke-width: 1px;
110 | stroke: black;
111 | shape-rendering: crispEdges;
112 | stroke-opacity: 0.2;
113 | }
114 |
115 | .djs-cursor-resize-nwse,
116 | .djs-resizer-nw,
117 | .djs-resizer-se {
118 | cursor: nwse-resize;
119 | }
120 |
121 | .djs-cursor-resize-nesw,
122 | .djs-resizer-ne,
123 | .djs-resizer-sw {
124 | cursor: nesw-resize;
125 | }
126 |
127 | .djs-shape.djs-resizing > .djs-outline {
128 | visibility: hidden !important;
129 | }
130 |
131 | .djs-shape.djs-resizing > .djs-resizer {
132 | visibility: hidden;
133 | }
134 |
135 | .djs-dragger > .djs-resizer {
136 | visibility: hidden;
137 | }
138 |
139 | /**
140 | * drag styles
141 | */
142 | .djs-dragger * {
143 | fill: none !important;
144 | stroke: rgb(255, 116, 0) !important;
145 | }
146 |
147 | .djs-dragger tspan,
148 | .djs-dragger text {
149 | fill: rgb(255, 116, 0) !important;
150 | stroke: none !important;
151 | }
152 |
153 | marker.djs-dragger circle,
154 | marker.djs-dragger path,
155 | marker.djs-dragger polygon,
156 | marker.djs-dragger polyline,
157 | marker.djs-dragger rect {
158 | fill: rgb(255, 116, 0) !important;
159 | stroke: none !important;
160 | }
161 |
162 | marker.djs-dragger text,
163 | marker.djs-dragger tspan {
164 | fill: none !important;
165 | stroke: rgb(255, 116, 0) !important;
166 | }
167 |
168 | .djs-dragging {
169 | opacity: 0.3;
170 | }
171 |
172 | .djs-dragging,
173 | .djs-dragging > * {
174 | pointer-events: none !important;
175 | }
176 |
177 | .djs-dragging .djs-context-pad,
178 | .djs-dragging .djs-outline {
179 | display: none !important;
180 | }
181 |
182 | /**
183 | * no pointer events for visual
184 | */
185 | .djs-visual,
186 | .djs-outline {
187 | pointer-events: none;
188 | }
189 |
190 | .djs-element.attach-ok .djs-hit {
191 | stroke-width: 60px !important;
192 | }
193 |
194 | /**
195 | * all pointer events for hit shape
196 | */
197 | .djs-shape .djs-hit {
198 | pointer-events: all;
199 | }
200 |
201 | .djs-connection .djs-hit {
202 | pointer-events: stroke;
203 | }
204 |
205 | .djs-frame .djs-hit {
206 | pointer-events: stroke;
207 | }
208 |
209 | /**
210 | * shape / connection basic styles
211 | */
212 | .djs-connection .djs-visual {
213 | stroke-width: 2px;
214 | fill: none;
215 | }
216 |
217 | .djs-cursor-grab {
218 | cursor: -webkit-grab;
219 | cursor: -moz-grab;
220 | cursor: grab;
221 | }
222 |
223 | .djs-cursor-grabbing {
224 | cursor: -webkit-grabbing;
225 | cursor: -moz-grabbing;
226 | cursor: grabbing;
227 | }
228 |
229 | .djs-cursor-crosshair {
230 | cursor: crosshair;
231 | }
232 |
233 | .djs-cursor-move {
234 | cursor: move;
235 | }
236 |
237 | .djs-cursor-resize-ns {
238 | cursor: ns-resize;
239 | }
240 |
241 | .djs-cursor-resize-ew {
242 | cursor: ew-resize;
243 | }
244 |
245 |
246 | /**
247 | * snapping
248 | */
249 | .djs-snap-line {
250 | stroke: rgb(255, 195, 66);
251 | stroke: rgba(255, 195, 66, 0.50);
252 | stroke-linecap: round;
253 | stroke-width: 2px;
254 | pointer-events: none;
255 | }
256 |
257 | /**
258 | * snapping
259 | */
260 | .djs-crosshair {
261 | stroke: #555;
262 | stroke-linecap: round;
263 | stroke-width: 1px;
264 | pointer-events: none;
265 | shape-rendering: crispEdges;
266 | stroke-dasharray: 5, 5;
267 | }
268 |
269 | /**
270 | * palette
271 | */
272 |
273 | .djs-palette {
274 | position: absolute;
275 | left: 20px;
276 | top: 20px;
277 |
278 | box-sizing: border-box;
279 | width: 48px;
280 | }
281 |
282 | .djs-palette .separator {
283 | margin: 0 5px;
284 | padding-top: 5px;
285 |
286 | border: none;
287 | border-bottom: solid 1px #DDD;
288 |
289 | clear: both;
290 | }
291 |
292 | .djs-palette .entry:before {
293 | vertical-align: text-bottom;
294 | }
295 |
296 | .djs-palette .djs-palette-toggle {
297 | cursor: pointer;
298 | }
299 |
300 | .djs-palette .entry,
301 | .djs-palette .djs-palette-toggle {
302 | color: #333;
303 | font-size: 30px;
304 |
305 | text-align: center;
306 | }
307 |
308 | .djs-palette .entry {
309 | float: left;
310 | }
311 |
312 | .djs-palette .entry img {
313 | max-width: 100%;
314 | }
315 |
316 | .djs-palette .djs-palette-entries:after {
317 | content: '';
318 | display: table;
319 | clear: both;
320 | }
321 |
322 | .djs-palette .djs-palette-toggle:hover {
323 | background: #666;
324 | }
325 |
326 | .djs-palette .entry:hover {
327 | color: rgb(255, 116, 0);
328 | }
329 |
330 | .djs-palette .highlighted-entry {
331 | color: rgb(255, 116, 0) !important;
332 | }
333 |
334 | .djs-palette .entry,
335 | .djs-palette .djs-palette-toggle {
336 | width: 46px;
337 | height: 46px;
338 | line-height: 46px;
339 | cursor: default;
340 | }
341 |
342 | /**
343 | * Palette open / two-column layout is controlled via
344 | * classes on the palette. Events to hook into palette
345 | * changed life-cycle are available in addition.
346 | */
347 | .djs-palette.two-column.open {
348 | width: 94px;
349 | }
350 |
351 | .djs-palette:not(.open) .djs-palette-entries {
352 | display: none;
353 | }
354 |
355 | .djs-palette:not(.open) {
356 | overflow: hidden;
357 | }
358 |
359 | .djs-palette.open .djs-palette-toggle {
360 | display: none;
361 | }
362 |
363 | /**
364 | * context-pad
365 | */
366 | .djs-overlay-context-pad {
367 | width: 72px;
368 | }
369 |
370 | .djs-context-pad {
371 | position: absolute;
372 | display: none;
373 | pointer-events: none;
374 | }
375 |
376 | .djs-context-pad .entry {
377 | width: 22px;
378 | height: 22px;
379 | text-align: center;
380 | display: inline-block;
381 | font-size: 22px;
382 | margin: 0 2px 2px 0;
383 |
384 | border-radius: 3px;
385 |
386 | cursor: default;
387 |
388 | background-color: #FEFEFE;
389 | box-shadow: 0 0 2px 1px #FEFEFE;
390 | pointer-events: all;
391 | }
392 |
393 | .djs-context-pad .entry:before {
394 | vertical-align: top;
395 | }
396 |
397 | .djs-context-pad .entry:hover {
398 | background: rgb(255, 252, 176);
399 | }
400 |
401 | .djs-context-pad.open {
402 | display: block;
403 | }
404 |
405 | /**
406 | * popup styles
407 | */
408 | .djs-popup .entry {
409 | line-height: 20px;
410 | white-space: nowrap;
411 | cursor: default;
412 | }
413 |
414 | /* larger font for prefixed icons */
415 | .djs-popup .entry:before {
416 | vertical-align: middle;
417 | font-size: 20px;
418 | }
419 |
420 | .djs-popup .entry > span {
421 | vertical-align: middle;
422 | font-size: 14px;
423 | }
424 |
425 | .djs-popup .entry:hover,
426 | .djs-popup .entry.active:hover {
427 | background: rgb(255, 252, 176);
428 | }
429 |
430 | .djs-popup .entry.disabled {
431 | background: inherit;
432 | }
433 |
434 | .djs-popup .djs-popup-header .entry {
435 | display: inline-block;
436 | padding: 2px 3px 2px 3px;
437 |
438 | border: solid 1px transparent;
439 | border-radius: 3px;
440 | }
441 |
442 | .djs-popup .djs-popup-header .entry.active {
443 | color: rgb(255, 116, 0);
444 | border: solid 1px rgb(255, 116, 0);
445 | background-color: #F6F6F6;
446 | }
447 |
448 | .djs-popup-body .entry {
449 | padding: 4px 10px 4px 5px;
450 | }
451 |
452 | .djs-popup-body .entry > span {
453 | margin-left: 5px;
454 | }
455 |
456 | .djs-popup-body {
457 | background-color: #FEFEFE;
458 | }
459 |
460 | .djs-popup-header {
461 | border-bottom: 1px solid #DDD;
462 | }
463 |
464 | .djs-popup-header .entry {
465 | margin: 1px;
466 | margin-left: 3px;
467 | }
468 |
469 | .djs-popup-header .entry:last-child {
470 | margin-right: 3px;
471 | }
472 |
473 | /**
474 | * popup / palette styles
475 | */
476 | .djs-popup, .djs-palette {
477 | background: #FAFAFA;
478 | border: solid 1px #CCC;
479 | border-radius: 2px;
480 | }
481 |
482 | /**
483 | * touch
484 | */
485 |
486 | .djs-shape,
487 | .djs-connection {
488 | touch-action: none;
489 | }
490 |
491 | .djs-segment-dragger,
492 | .djs-bendpoint {
493 | display: none;
494 | }
495 |
496 | /**
497 | * bendpoints
498 | */
499 | .djs-segment-dragger .djs-visual {
500 | fill: rgba(255, 255, 121, 0.2);
501 | stroke-width: 1px;
502 | stroke-opacity: 1;
503 | stroke: rgba(255, 255, 121, 0.3);
504 | }
505 |
506 | .djs-bendpoint .djs-visual {
507 | fill: rgba(255, 255, 121, 0.8);
508 | stroke-width: 1px;
509 | stroke-opacity: 0.5;
510 | stroke: black;
511 | }
512 |
513 | .djs-segment-dragger:hover,
514 | .djs-bendpoints.hover .djs-segment-dragger,
515 | .djs-bendpoints.selected .djs-segment-dragger,
516 | .djs-bendpoint:hover,
517 | .djs-bendpoints.hover .djs-bendpoint,
518 | .djs-bendpoints.selected .djs-bendpoint {
519 | display: block;
520 | }
521 |
522 | .djs-drag-active .djs-bendpoints * {
523 | display: none;
524 | }
525 |
526 | .djs-bendpoints:not(.hover) .floating {
527 | display: none;
528 | }
529 |
530 | .djs-segment-dragger:hover .djs-visual,
531 | .djs-segment-dragger.djs-dragging .djs-visual,
532 | .djs-bendpoint:hover .djs-visual,
533 | .djs-bendpoint.floating .djs-visual {
534 | fill: yellow;
535 | stroke-opacity: 0.5;
536 | stroke: black;
537 | }
538 |
539 | .djs-bendpoint.floating .djs-hit {
540 | pointer-events: none;
541 | }
542 |
543 | .djs-segment-dragger .djs-hit,
544 | .djs-bendpoint .djs-hit {
545 | pointer-events: all;
546 | fill: none;
547 | }
548 |
549 | .djs-segment-dragger.horizontal .djs-hit {
550 | cursor: ns-resize;
551 | }
552 |
553 | .djs-segment-dragger.vertical .djs-hit {
554 | cursor: ew-resize;
555 | }
556 |
557 | .djs-segment-dragger.djs-dragging .djs-hit {
558 | pointer-events: none;
559 | }
560 |
561 | .djs-updating,
562 | .djs-updating > * {
563 | pointer-events: none !important;
564 | }
565 |
566 | .djs-updating .djs-context-pad,
567 | .djs-updating .djs-outline,
568 | .djs-updating .djs-bendpoint,
569 | .connect-ok .djs-bendpoint,
570 | .connect-not-ok .djs-bendpoint,
571 | .drop-ok .djs-bendpoint,
572 | .drop-not-ok .djs-bendpoint {
573 | display: none !important;
574 | }
575 |
576 | .djs-segment-dragger.djs-dragging,
577 | .djs-bendpoint.djs-dragging {
578 | display: block;
579 | opacity: 1.0;
580 | }
581 |
582 | .djs-segment-dragger.djs-dragging .djs-visual,
583 | .djs-bendpoint.djs-dragging .djs-visual {
584 | fill: yellow;
585 | stroke-opacity: 0.5;
586 | }
587 |
588 |
589 | /**
590 | * tooltips
591 | */
592 | .djs-tooltip-error {
593 | font-size: 11px;
594 | line-height: 18px;
595 | text-align: left;
596 |
597 | padding: 5px;
598 |
599 | opacity: 0.7;
600 | }
601 |
602 | .djs-tooltip-error > * {
603 | width: 160px;
604 |
605 | background: rgb(252, 236, 240);
606 | color: rgb(158, 76, 76);
607 | padding: 3px 7px;
608 | border-radius: 5px;
609 | border-left: solid 5px rgb(174, 73, 73);
610 | }
611 |
612 | .djs-tooltip-error:hover {
613 | opacity: 1;
614 | }
615 |
616 |
617 | /**
618 | * search pad
619 | */
620 | .djs-search-container {
621 | position: absolute;
622 | top: 20px;
623 | left: 0;
624 | right: 0;
625 | margin-left: auto;
626 | margin-right: auto;
627 |
628 | width: 25%;
629 | min-width: 300px;
630 | max-width: 400px;
631 | z-index: 10;
632 |
633 | font-size: 1.05em;
634 | opacity: 0.9;
635 | background: #FAFAFA;
636 | border: solid 1px #CCC;
637 | border-radius: 2px;
638 | }
639 |
640 | .djs-search-container:not(.open) {
641 | display: none;
642 | }
643 |
644 | .djs-search-input input {
645 | font-size: 1.05em;
646 | width: 100%;
647 | padding: 6px 10px;
648 | border: 1px solid #ccc;
649 | }
650 |
651 | .djs-search-input input:focus {
652 | outline: none;
653 | border-color: #52B415;
654 | }
655 |
656 | .djs-search-results {
657 | position: relative;
658 | overflow-y: auto;
659 | max-height: 200px;
660 | }
661 |
662 | .djs-search-results:hover {
663 | /*background: #fffdd7;*/
664 | cursor: pointer;
665 | }
666 |
667 | .djs-search-result {
668 | width: 100%;
669 | padding: 6px 10px;
670 | background: white;
671 | border-bottom: solid 1px #AAA;
672 | border-radius: 1px;
673 | }
674 |
675 | .djs-search-highlight {
676 | color: black;
677 | }
678 |
679 | .djs-search-result-primary {
680 | margin: 0 0 10px;
681 | }
682 |
683 | .djs-search-result-secondary {
684 | font-family: monospace;
685 | margin: 0;
686 | }
687 |
688 | .djs-search-result:hover {
689 | background: #fdffd6;
690 | }
691 |
692 | .djs-search-result-selected {
693 | background: #fffcb0;
694 | }
695 |
696 | .djs-search-result-selected:hover {
697 | background: #f7f388;
698 | }
699 |
700 | .djs-search-overlay {
701 | background: yellow;
702 | opacity: 0.3;
703 | }
704 |
705 | /**
706 | * hidden styles
707 | */
708 | .djs-element-hidden,
709 | .djs-element-hidden .djs-hit,
710 | .djs-element-hidden .djs-outline,
711 | .djs-label-hidden .djs-label {
712 | display: none !important;
713 | }
714 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | "probot-app"
4 | ],
5 | "version": "1.5.1"
6 | }
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "root",
3 | "private": true,
4 | "devDependencies": {
5 | "lerna": "^8.0.0"
6 | },
7 | "scripts": {
8 | "postinstall": "lerna exec -- npm i",
9 | "release": "lerna publish",
10 | "start": "cd probot-app && npm run start"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/probot-app/.env.example:
--------------------------------------------------------------------------------
1 | # The ID of your GitHub App
2 | APP_ID=
3 | WEBHOOK_SECRET=development
4 |
5 | # Use `trace` to get verbose logging or `info` to show less
6 | LOG_LEVEL=debug
7 |
8 | # Go to https://smee.io/new set this to the URL that you are redirected to.
9 | WEBHOOK_PROXY_URL=
10 |
--------------------------------------------------------------------------------
/probot-app/.eslintrc:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "extends": [
4 | "plugin:bpmn-io/node"
5 | ],
6 | "rules": {
7 | "no-useless-catch": 0
8 | }
9 | }
--------------------------------------------------------------------------------
/probot-app/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | *.txt
64 | *.png
65 |
--------------------------------------------------------------------------------
/probot-app/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | education, socio-economic status, nationality, personal appearance, race,
10 | religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at niklas.kiefer@camunda.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 |
--------------------------------------------------------------------------------
/probot-app/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing
2 |
3 | [fork]: /fork
4 | [pr]: /compare
5 | [style]: https://github.com/bpmn-io/eslint-plugin-bpmn-io
6 | [code-of-conduct]: CODE_OF_CONDUCT.md
7 |
8 | Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
9 |
10 | Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms.
11 |
12 | ## Issues and PRs
13 |
14 | If you have suggestions for how this project could be improved, or want to report a bug, open an issue! We'd love all and any contributions. If you have questions, too, we'd love to hear them.
15 |
16 | We'd also love PRs. If you're thinking of a large PR, we advise opening up an issue first to talk about it, though! Look at the links below if you're not sure how to open a PR.
17 |
18 | ## Submitting a pull request
19 |
20 | 1. [Fork][fork] and clone the repository.
21 | 1. Configure and install the dependencies: `npm install`.
22 | 1. Make sure the tests pass on your machine: `npm test`, note: these tests also apply the linter, so there's no need to lint separately.
23 | 1. Create a new branch: `git checkout -b my-branch-name`.
24 | 1. Make your change, add tests, and make sure the tests still pass.
25 | 1. Push to your fork and [submit a pull request][pr].
26 | 1. Pat your self on the back and wait for your pull request to be reviewed and merged.
27 |
28 | Here are a few things you can do that will increase the likelihood of your pull request being accepted:
29 |
30 | - Follow the [style guide][style] which is using standard. Any linting errors should be shown when running `npm test`.
31 | - Write and update tests.
32 | - Keep your changes as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
33 | - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
34 |
35 | Work in Progress pull requests are also welcome to get feedback early on, or if there is something blocked you.
36 |
37 | ## Resources
38 |
39 | - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
40 | - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
41 | - [GitHub Help](https://help.github.com)
42 |
--------------------------------------------------------------------------------
/probot-app/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Niklas Kiefer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/probot-app/README.md:
--------------------------------------------------------------------------------
1 | > Note: Currently it's not possible to upload `.bpmn` files via drag and drop on GitHub. Attaching a `.txt` extension at the end can be a workaround.
2 |
3 | # render-bpmn
4 |
5 | 
6 |
7 | A GitHub App built with [Probot](https://github.com/probot/probot) that automatically renders BPMN files on GitHub Issues and Pull Requests.
8 |
9 | 
10 |
11 | ## Setup
12 |
13 | The application is connected to GitHub as a [GitHub app](https://developer.github.com/apps/). Get started by creating a GitHub app, either via the development setup or using [manual configuration steps](#manual-steps) as documented below.
14 |
15 |
16 | ### Automatic Development Setup
17 |
18 | Checkout, install and run the application in development mode as shown below:
19 |
20 | ```bash
21 | git clone git@github.com:pinussilvestrus/github-bpmn.git
22 | cd probot-app
23 | npm install
24 | npm run dev
25 | ```
26 |
27 | Access the application on [`localhost:3000`](http://localhost:3000). [Probot](https://probot.github.io/), the app framework used by the render-bpmn application, helps you to create your GitHub app. Give your app a unique name and remember it.
28 |
29 | Once the setup completes probot writes the basic app configuration to the `probot-app/.env` file. Go to your app page on GitHub, fetch client ID and client secret and add these properties to the `.env` file as `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET`, respectively.
30 |
31 | __Note:__ on additional start after registering could be needed work properly, causing registering delays to the smee.io proxy.
32 |
33 | ### Manual Steps
34 |
35 | [Create your GitHub app](https://github.com/settings/apps/new) and configure it according to the [provided app mainfest](../probot-app/app.yml).
36 |
37 | Create a `.env` file with the required configuration variables as provided by GitHub. Use the [provided example](../probot-app/.env.example) as a starting point.
38 |
39 | ## Deploy
40 |
41 | Tryout the Heroku Deploy Button below and [follow the setup instructions](https://probot.github.io/docs/deployment/#heroku).
42 |
43 | [](https://heroku.com/deploy?template=https://github.com/pinussilvestrus/github-bpmn)
44 |
45 | Also feel free to have a look at [the other deployment options](https://probot.github.io/docs/deployment/).
46 |
47 |
48 | ## Contributing
49 |
50 | If you have suggestions for how probot could be improved, or want to report a bug, open an issue! We'd love all and any contributions.
51 |
52 | For more, check out the [Contributing Guide](CONTRIBUTING.md).
53 |
54 | ## License
55 |
56 | [MIT](LICENSE) © 2019 Niklas Kiefer
57 |
58 | Contains parts ([bpmn-to-image](https://github.com/bpmn-io/bpmn-to-image)) released under the [bpmn.io license](http://bpmn.io/license).
59 |
--------------------------------------------------------------------------------
/probot-app/app.yml:
--------------------------------------------------------------------------------
1 | # This is a GitHub App Manifest. These settings will be used by default when
2 | # initially configuring your GitHub App.
3 | #
4 | # NOTE: changing this file will not update your GitHub App settings.
5 | # You must visit github.com/settings/apps/your-app-name to edit them.
6 | #
7 | # Read more about configuring your GitHub App:
8 | # https://probot.github.io/docs/development/#configuring-a-github-app
9 | #
10 | # Read more about GitHub App Manifests:
11 | # https://developer.github.com/apps/building-github-apps/creating-github-apps-from-a-manifest/
12 |
13 | # The list of events the GitHub App subscribes to.
14 | # Uncomment the event names below to enable them.
15 | default_events:
16 | # - content_reference
17 | # - check_run
18 | # - check_suite
19 | # - commit_comment
20 | # - create
21 | # - delete
22 | # - deployment
23 | # - deployment_status
24 | # - fork
25 | # - gollum
26 | - issue_comment
27 | - issues
28 | # - label
29 | # - milestone
30 | # - member
31 | # - membership
32 | # - org_block
33 | # - organization
34 | # - page_build
35 | # - project
36 | # - project_card
37 | # - project_column
38 | # - public
39 | - pull_request
40 | # - pull_request_review
41 | # - pull_request_review_comment
42 | # - push
43 | # - release
44 | # - repository
45 | # - repository_import
46 | # - status
47 | # - team
48 | # - team_add
49 | # - watch
50 |
51 | # The set of permissions needed by the GitHub App. The format of the object uses
52 | # the permission name for the key (for example, issues) and the access type for
53 | # the value (for example, write).
54 | # Valid values are `read`, `write`, and `none`
55 | default_permissions:
56 | # Repository creation, deletion, settings, teams, and collaborators.
57 | # https://developer.github.com/v3/apps/permissions/#permission-on-administration
58 | # administration: read
59 |
60 | # Checks on code.
61 | # https://developer.github.com/v3/apps/permissions/#permission-on-checks
62 | # checks: read
63 |
64 | # Repository contents, commits, branches, downloads, releases, and merges.
65 | # https://developer.github.com/v3/apps/permissions/#permission-on-contents
66 | # contents: write
67 |
68 | # Deployments and deployment statuses.
69 | # https://developer.github.com/v3/apps/permissions/#permission-on-deployments
70 | # deployments: read
71 |
72 | # Issues and related comments, assignees, labels, and milestones.
73 | # https://developer.github.com/v3/apps/permissions/#permission-on-issues
74 | issues: write
75 |
76 | # Search repositories, list collaborators, and access repository metadata.
77 | # https://developer.github.com/v3/apps/permissions/#metadata-permissions
78 | metadata: read
79 |
80 | # Retrieve Pages statuses, configuration, and builds, as well as create new builds.
81 | # https://developer.github.com/v3/apps/permissions/#permission-on-pages
82 | # pages: read
83 |
84 | # Pull requests and related comments, assignees, labels, milestones, and merges.
85 | # https://developer.github.com/v3/apps/permissions/#permission-on-pull-requests
86 | pull_requests: write
87 |
88 | # Manage the post-receive hooks for a repository.
89 | # https://developer.github.com/v3/apps/permissions/#permission-on-repository-hooks
90 | # repository_hooks: read
91 |
92 | # Manage repository projects, columns, and cards.
93 | # https://developer.github.com/v3/apps/permissions/#permission-on-repository-projects
94 | # repository_projects: read
95 |
96 | # Retrieve security vulnerability alerts.
97 | # https://developer.github.com/v4/object/repositoryvulnerabilityalert/
98 | # vulnerability_alerts: read
99 |
100 | # Commit statuses.
101 | # https://developer.github.com/v3/apps/permissions/#permission-on-statuses
102 | # statuses: read
103 |
104 | # Organization members and teams.
105 | # https://developer.github.com/v3/apps/permissions/#permission-on-members
106 | # members: read
107 |
108 | # View and manage users blocked by the organization.
109 | # https://developer.github.com/v3/apps/permissions/#permission-on-organization-user-blocking
110 | # organization_user_blocking: read
111 |
112 | # Manage organization projects, columns, and cards.
113 | # https://developer.github.com/v3/apps/permissions/#permission-on-organization-projects
114 | # organization_projects: read
115 |
116 | # Manage team discussions and related comments.
117 | # https://developer.github.com/v3/apps/permissions/#permission-on-team-discussions
118 | # team_discussions: read
119 |
120 | # Manage the post-receive hooks for an organization.
121 | # https://developer.github.com/v3/apps/permissions/#permission-on-organization-hooks
122 | # organization_hooks: read
123 |
124 | # Get notified of, and update, content references.
125 | # https://developer.github.com/v3/apps/permissions/
126 | # organization_administration: read
127 |
128 |
129 | # The name of the GitHub App. Defaults to the name specified in package.json
130 | # name: My Probot App
131 |
132 | # The homepage of your GitHub App.
133 | # url: https://example.com/
134 |
135 | # A description of the GitHub App.
136 | # description: A description of my awesome app
137 |
138 | # Set to true when your GitHub App is available to the public or false when it is only accessible to the owner of the app.
139 | # Default: true
140 | # public: false
141 |
--------------------------------------------------------------------------------
/probot-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "render-bpmn",
3 | "version": "1.5.1",
4 | "description": "Hackdays Project: Render BPMN, CMMN and DMN files on GitHub",
5 | "author": "Niklas Kiefer ",
6 | "license": "MIT",
7 | "repository": "https://github.com/pinussilvestrus/github-bpmn.git",
8 | "homepage": "https://github.com/pinussilvestrus/github-bpmn/probot-app",
9 | "bugs": "https://github.com/pinussilvestrus/github-bpmn/issues",
10 | "keywords": [
11 | "probot",
12 | "github",
13 | "probot-app",
14 | "bpmn"
15 | ],
16 | "scripts": {
17 | "all": "run-s test",
18 | "dev": "nodemon",
19 | "start": "probot run ./src/index.js",
20 | "lint": "eslint .",
21 | "test": "jest && npm run lint",
22 | "test:watch": "jest --watch --notify --notifyMode=change --coverage"
23 | },
24 | "dependencies": {
25 | "bpmn-to-image": "^0.9.0",
26 | "imgur": "^1.0.2",
27 | "probot": "^12.3.3",
28 | "request": "^2.88.2",
29 | "request-promise": "^4.2.6"
30 | },
31 | "devDependencies": {
32 | "eslint": "^8.54.0",
33 | "eslint-plugin-bpmn-io": "^1.0.0",
34 | "jest": "^29.7.0",
35 | "nock": "^13.4.0",
36 | "nodemon": "^3.0.1",
37 | "npm-run-all": "^4.1.5",
38 | "smee-client": "^1.2.3"
39 | },
40 | "engines": {
41 | "node": ">= 8.3.0"
42 | },
43 | "standard": {
44 | "env": [
45 | "jest"
46 | ]
47 | },
48 | "nodemonConfig": {
49 | "exec": "npm start",
50 | "watch": [
51 | ".env",
52 | "."
53 | ]
54 | },
55 | "jest": {
56 | "testEnvironment": "node"
57 | },
58 | "gitHead": "50f909f9b5bae34547c2cf8dd3f5c9a636186474"
59 | }
60 |
--------------------------------------------------------------------------------
/probot-app/src/helper/extractBpmnFileUrls.js:
--------------------------------------------------------------------------------
1 | // const regex = new RegExp("/\[.*\]\((https:\/\/|http:\/\/).*\)/g");
2 | const regex = /\[.+\]\((https:\/\/|http:\/\/).*(\.bpmn|\.txt|\.xml)\)/g;
3 |
4 | function resolveUrl(occurrence) {
5 | return occurrence.substring(
6 | occurrence.lastIndexOf('(') + 1,
7 | occurrence.lastIndexOf(')')
8 | );
9 | }
10 |
11 | /**
12 | * Find all urls and return in the form of
13 | * { from: , to: , url: , raw: }
14 | * @param {String} content
15 | *
16 | * @return Array
17 | */
18 | module.exports = function(content) {
19 |
20 | if (!content) {
21 | return;
22 | }
23 |
24 | let result, occurrences = [];
25 |
26 | while ((result = regex.exec(content)) !== null) {
27 |
28 | const occurrence = result[0],
29 | index = result.index,
30 | url = resolveUrl(occurrence);
31 |
32 | // do not include already rendered diagrams
33 | if (content.includes(`data-original=${url}`)) {
34 | continue;
35 | }
36 |
37 | occurrences.push({
38 | raw: occurrence,
39 | from: index,
40 | to: index + occurrence.length,
41 | url: url
42 | });
43 | }
44 |
45 | return occurrences;
46 | };
--------------------------------------------------------------------------------
/probot-app/src/helper/index.js:
--------------------------------------------------------------------------------
1 | const extractBpmnFileUrls = require('./extractBpmnFileUrls');
2 |
3 | const templates = require('./templates');
4 |
5 | module.exports = {
6 | extractBpmnFileUrls,
7 | templates
8 | };
--------------------------------------------------------------------------------
/probot-app/src/helper/templates.js:
--------------------------------------------------------------------------------
1 | function renderDiagramTmpl(options) {
2 |
3 | const {
4 | uploadedUrl,
5 | url
6 | } = options;
7 |
8 | return `
`;
9 | }
10 |
11 | function renderSpinnerTmpl(options) {
12 |
13 | const {
14 | url
15 | } = options;
16 |
17 |
18 | return `
19 | 
20 | `;
21 | }
22 |
23 | module.exports = {
24 | renderDiagramTmpl,
25 | renderSpinnerTmpl
26 | };
--------------------------------------------------------------------------------
/probot-app/src/index.js:
--------------------------------------------------------------------------------
1 | const {
2 | extractBpmnFileUrls,
3 | templates
4 | } = require('./helper');
5 |
6 | const processUrls = require('./process-urls');
7 |
8 | let log;
9 |
10 | /**
11 | * Generates String which contains necessary information about the current
12 | * processed comment | issue | pull_request
13 | *
14 | * @param {Comment} options.comment
15 | * @param {Issue} options.issue
16 | * @param {PullRequest} options.pull_request
17 | * @param {Repository} options.repository
18 | *
19 | * @return {String}
20 | */
21 | function getContextString(options) {
22 |
23 | const {
24 | comment,
25 | issue,
26 | pull_request,
27 | repository
28 | } = options;
29 |
30 | return JSON.stringify({
31 | repository: repository.full_name,
32 | issue: comment ? comment.issue_url : (issue || {}).url,
33 | pull_request: (pull_request || {}).url,
34 | comment: (comment || {}).id
35 | });
36 |
37 | }
38 |
39 | function cleanupSpinners(options) {
40 |
41 | const {
42 | urls,
43 | body
44 | } = options;
45 |
46 | urls.forEach(u => {
47 | body.replace(templates.renderSpinnerTmpl({ url: u.url }), '');
48 | });
49 | }
50 |
51 | /**
52 | * Patches a comment or issue or pull request content.
53 | *
54 | * @param {String} options.body
55 | * @param {Array} options.urls
56 | * @param {Comment} options.comment
57 | * @param {GithubApiClient} options.github
58 | * @param {Issue} options.issue
59 | * @param {PullRequest} options.pull_request
60 | * @param {Repository} options.repository
61 | * @param {Function} options.templateFn
62 | *
63 | * @return {Promise}
64 | */
65 | async function updateComment(options) {
66 |
67 | let {
68 | body,
69 | urls
70 | } = options;
71 |
72 | const {
73 | comment,
74 | github,
75 | issue,
76 | pull_request,
77 | repository,
78 | templateFn
79 | } = options;
80 |
81 | urls.forEach(u => {
82 | const {
83 | url
84 | } = u;
85 |
86 | // updated 'to' idx
87 | const to = u.to = body.indexOf(url) + url.length;
88 |
89 | const tag = templateFn(u);
90 |
91 | body = body.slice(0, to + 1) + tag + body.slice(to + 1);
92 |
93 | });
94 |
95 | cleanupSpinners({ urls, body });
96 |
97 | // TODO: refactor me to a better fit pattern
98 | if (comment) {
99 | await github.issues.updateComment({
100 | owner: repository.owner.login,
101 | repo: repository.name,
102 | comment_id: comment.id,
103 | body: body
104 | });
105 | } else if (issue) {
106 |
107 | await github.issues.update({
108 | owner: repository.owner.login,
109 | repo: repository.name,
110 | issue_number: issue.number,
111 | body: body
112 | });
113 | } else {
114 |
115 | await github.pullRequests.update({
116 | owner: repository.owner.login,
117 | repo: repository.name,
118 | pull_number: pull_request.number,
119 | body: body
120 | });
121 | }
122 |
123 |
124 | }
125 |
126 | /**
127 | * Adds a loading spinner for every url occurence
128 | * @param {*} options
129 | *
130 | * @return {Promise}
131 | */
132 | async function addLoadingSpinners(options) {
133 |
134 | await updateComment({
135 | ...options,
136 | templateFn: templates.renderSpinnerTmpl
137 | });
138 |
139 | }
140 |
141 | /**
142 | * Renders all attached bpmn file urls to actual diagram
143 | *
144 | * @param {*} context
145 | *
146 | * @return {Promise}
147 | */
148 | async function renderDiagrams(context) {
149 |
150 | const {
151 | octokit: github,
152 | payload
153 | } = context;
154 |
155 | const {
156 | comment,
157 | issue,
158 | pull_request,
159 | repository
160 | } = payload;
161 |
162 | let {
163 | body
164 | } = comment || issue || pull_request;
165 |
166 | const contextString = getContextString({ comment, issue, pull_request, repository });
167 |
168 | if (!body) {
169 | return;
170 | }
171 |
172 | // check whether comment contains uploaded bpmn file
173 | const urls = extractBpmnFileUrls(body);
174 |
175 | if (!urls || !urls.length) {
176 | return;
177 | }
178 |
179 | log.info(`Processing of Created Comment started, ${contextString}`);
180 |
181 | await addLoadingSpinners({
182 | body,
183 | comment,
184 | github,
185 | issue,
186 | pull_request,
187 | repository,
188 | urls
189 | });
190 |
191 | log.info(`Added Loading Spinners, ${contextString}`);
192 |
193 | await processUrls(urls);
194 |
195 | await updateComment({
196 | body,
197 | comment,
198 | github,
199 | issue,
200 | pull_request,
201 | repository,
202 | templateFn: templates.renderDiagramTmpl,
203 | urls
204 | });
205 |
206 | log.info(`Comment updated with Rendered Diagrams, ${contextString}`);
207 |
208 | // TODO: cleanup imgur files afterwards?
209 | }
210 |
211 | /**
212 | * Probot App entry point
213 | * @param {import('probot').Application} app
214 | */
215 | module.exports = app => {
216 |
217 | log = app.log;
218 |
219 | app.on([
220 | 'issue_comment.created',
221 | 'issue_comment.edited',
222 | 'issues.opened',
223 | 'issues.edited',
224 | 'pull_request.opened',
225 | 'pull_request.edited'
226 | ], renderDiagrams);
227 | };
228 |
--------------------------------------------------------------------------------
/probot-app/src/misc/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/probot-app/src/misc/loading.gif
--------------------------------------------------------------------------------
/probot-app/src/process-urls/index.js:
--------------------------------------------------------------------------------
1 | const rp = require('request-promise');
2 |
3 | const fs = require('fs');
4 |
5 | const imgur = require('imgur');
6 |
7 | const {
8 | promisify
9 | } = require('util');
10 |
11 | const {
12 | convertAll
13 | } = require('bpmn-to-image');
14 |
15 | const writeFileAsync = promisify(fs.writeFile);
16 |
17 | const deleteFileAsync = promisify(fs.unlink);
18 |
19 | /**
20 | * Processes all url occurrences by
21 | * - Fetching the url's content
22 | * - Saving file content to disk
23 | * - Render bpmn content to image
24 | * - Upload to imgur file space
25 | *
26 | * @param {Array} urls
27 | *
28 | * @return {Promise}
29 | */
30 | module.exports = async function processUrls(urls) {
31 |
32 | await Promise.all(urls.map(async (u, idx) => {
33 |
34 | const {
35 | url
36 | } = u;
37 |
38 | if (!url) {
39 | return;
40 | }
41 |
42 | // fetch file content
43 | const content = await rp(url);
44 |
45 | // save to temp file
46 | const tmpFile = `${__dirname}/../diagram.${idx}.txt`,
47 | tmpImgFile = `diagram.${idx}.png`;
48 |
49 | await writeFileAsync(tmpFile, content);
50 |
51 | // generate + upload image
52 | let response;
53 |
54 | try {
55 | await convertAll([
56 | {
57 | input: tmpFile,
58 | outputs: [ tmpImgFile ]
59 | }
60 | ]);
61 |
62 | // TODO: way to simply display raw image on GitHub markdown?
63 | response = await imgur.uploadFile(tmpImgFile);
64 |
65 | } catch (error) {
66 |
67 | // TODO: better error handling
68 | return;
69 | }
70 |
71 | if (!response || !response.data.link) {
72 |
73 | return;
74 | }
75 |
76 | // cleanup
77 | deleteFileAsync(tmpFile);
78 | deleteFileAsync(tmpImgFile);
79 |
80 | Object.assign(u, {
81 | uploadedUrl: response.data.link
82 | });
83 |
84 | }));
85 | };
--------------------------------------------------------------------------------
/probot-app/test/fixtures/issue_comment.created.json:
--------------------------------------------------------------------------------
1 | {
2 | "action": "created",
3 | "issue": {
4 | "number": 1,
5 | "user": {
6 | "login": "pinussilvestrus"
7 | }
8 | },
9 | "comment": {
10 | "id": 1,
11 | "body": "[diagram_copypaste.bpmn.txt](https://github.com/pinussilvestrus/github-bpmn/files/3504544/diagram_copypaste.bpmn.txt)"
12 | },
13 | "repository": {
14 | "name": "github-bpmn",
15 | "owner": {
16 | "login": "pinussilvestrus"
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/probot-app/test/index.test.js:
--------------------------------------------------------------------------------
1 | /* global jest, expect, describe, test, beforeEach */
2 |
3 | const nock = require('nock');
4 |
5 | const { Probot } = require('probot');
6 |
7 | jest.mock('bpmn-to-image');
8 | jest.mock('imgur');
9 |
10 | const renderBpmnApp = require('../src');
11 |
12 | const payload = require('./fixtures/issue_comment.created');
13 |
14 | const xml = `
15 |
16 |
17 |
18 | SequenceFlow_0xbi38e
19 |
20 |
21 |
22 | SequenceFlow_0wetfnk
23 |
24 |
25 |
26 | SequenceFlow_087tlq4
27 | SequenceFlow_0wetfnk
28 |
29 |
30 |
31 | SequenceFlow_0xbi38e
32 | SequenceFlow_0t7oahk
33 |
34 |
35 | SequenceFlow_0t7oahk
36 | SequenceFlow_087tlq4
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | `;
78 |
79 | nock.disableNetConnect();
80 |
81 | describe('render-bpmn', () => {
82 | let probot;
83 |
84 | // load probot
85 | beforeEach(() => {
86 | probot = new Probot({ id: 123, githubToken: 'test' });
87 | probot.load(renderBpmnApp);
88 | });
89 |
90 | // mock requests
91 | beforeEach(() => {
92 |
93 | nock.enableNetConnect();
94 |
95 | nock('https://api.github.com')
96 | .post('/app/installations/2/access_tokens')
97 | .reply(200, { token: 'test' });
98 |
99 | nock('https://github.com')
100 | .get('/pinussilvestrus/github-bpmn/files/3504544/diagram_copypaste.bpmn.txt')
101 | .reply(200, xml);
102 |
103 | nock('https://api.imgur.com')
104 | .post('/3/image')
105 | .reply(200, {
106 | data: {
107 | link: 'foo'
108 | }
109 | });
110 |
111 | });
112 |
113 | test('update comment after created', async () => {
114 |
115 | nock('https://api.github.com')
116 | .patch(
117 | '/repos/pinussilvestrus/github-bpmn/issues/comments/1', (body) => {
118 |
119 | // then, update #1 loading spinner
120 | expect(body).not.toBeUndefined();
121 | expect(body.body).toContain(
122 | ''
123 | );
124 |
125 | nock('https://api.github.com')
126 | .patch(
127 | '/repos/pinussilvestrus/github-bpmn/issues/comments/1', (body) => {
128 |
129 | // then, update #2 rendered diagram
130 | expect(body).not.toBeUndefined();
131 | expect(body.body).toContain(
132 | '
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/resources/complex.cmmn:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | complete
36 |
37 |
38 |
39 |
40 | complete
41 |
42 |
43 |
44 |
45 |
46 | complete
47 |
48 |
49 |
50 |
51 | complete
52 |
53 |
54 |
55 |
56 | complete
57 |
58 |
59 |
60 |
61 | complete
62 |
63 |
64 |
65 |
66 | complete
67 |
68 |
69 |
70 |
71 | complete
72 |
73 |
74 |
75 |
76 |
77 |
79 |
80 |
81 |
82 |
83 |
84 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | complete
97 |
98 |
99 |
100 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
110 |
111 |
112 |
113 |
114 |
115 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
130 |
131 |
133 |
134 |
135 |
136 |
137 |
139 |
140 |
141 |
142 |
143 |
145 |
146 |
147 |
148 |
149 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
--------------------------------------------------------------------------------
/resources/conditions.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SequenceFlow_1
6 | SequenceFlow_3
7 | SequenceFlow_4
8 |
9 |
10 | bar}]]>
11 |
12 |
13 | SequenceFlow_2
14 | SequenceFlow_4
15 |
16 |
17 | SequenceFlow_1
18 | SequenceFlow_2
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | SequenceFlow_3
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/resources/large.dmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | status
7 |
8 |
9 |
10 | sum
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | = 1000]]>
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/resources/multiple-cases.cmmn:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/resources/one-decision.dmn:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | season
16 |
17 |
18 |
19 |
20 | guestCount
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 8]]>
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 10]]>
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | = 10]]>
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/resources/screencast-1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/resources/screencast-1.gif
--------------------------------------------------------------------------------
/resources/screencast-2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/resources/screencast-2.gif
--------------------------------------------------------------------------------
/resources/screencast-3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinussilvestrus/github-bpmn/071e645aa18b327b401b709ac704832c48037a2f/resources/screencast-3.gif
--------------------------------------------------------------------------------
/resources/simple.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SequenceFlow_3
6 | SequenceFlow_2
7 |
8 | SequenceFlow_1
9 |
10 |
11 | SequenceFlow_1
12 |
13 |
14 |
15 |
16 | SequenceFlow_2
17 |
18 |
19 |
20 | SequenceFlow_3
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/resources/simple.cmmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | occur
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/resources/simple.dmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | status
8 |
9 |
10 |
11 |
12 | sum
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | = 1000]]>
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/userscript/.eslintrc:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "extends": [
4 | "plugin:bpmn-io/es6"
5 | ],
6 | "rules": {
7 | "no-useless-catch": 0
8 | }
9 | }
--------------------------------------------------------------------------------
/userscript/index.js:
--------------------------------------------------------------------------------
1 | /* global $, BpmnJS, CmmnJS, window, atob, Promise, DmnJS */
2 |
3 | // ==UserScript==
4 | // @name BPMN on hover
5 | // @namespace https://github.com/pinussilvestrus/github-bpmn
6 | // @version 0.1.0
7 | // @description On hover over a bpmn file it will display it
8 | // @author Langleu
9 | // @match https://github.com/*
10 | // @require https://code.jquery.com/jquery-3.4.1.min.js
11 | // @require https://unpkg.com/bpmn-js@5.0.0/dist/bpmn-viewer.production.min.js
12 | // @require https://unpkg.com/cmmn-js@0.19.2/dist/cmmn-viewer.production.min.js
13 | // @require https://unpkg.com/dmn-js@7.0.0/dist/dmn-viewer.production.min.js
14 | // @resource https://unpkg.com/bpmn-js@5.0.0/dist/assets/diagram-js.css
15 | // @resource https://unpkg.com/cmmn-js@0.19.2/dist/assets/diagram-js.css
16 | // @resource https://unpkg.com/dmn-js@7.0.0/dist/assets/diagram-js.css
17 | // @grant none
18 | // ==/UserScript==
19 |
20 | const thumb_selector = '.content a';
21 |
22 | // returns source url for GitHub
23 | function getSrc(src) {
24 | let splitSrc = src.split('/');
25 | let notAllowed = ['blob', 'https:', 'http:', 'github.com'];
26 |
27 | splitSrc = splitSrc.filter(function(word) {
28 | if (!notAllowed.includes(word))
29 | return word;
30 | });
31 |
32 | let user = splitSrc.reverse().pop();
33 | let repo = splitSrc.pop();
34 | let ref = splitSrc.pop();
35 |
36 | return `https://api.github.com/repos/${user}/${repo}/contents/${splitSrc.reverse().join('/').replace('#','')}?ref=${ref}`;
37 | }
38 |
39 | // returns the viewer depending on the viewer type
40 | function returnViewer(type) {
41 | switch (type) {
42 | case 'bpmn':
43 | return new BpmnJS({
44 | container: $('#js-canvas')
45 | });
46 | case 'cmmn':
47 | return new CmmnJS({
48 | container: $('#js-canvas')
49 | });
50 | case 'dmn':
51 | return new DmnJS({
52 | container: $('#js-canvas')
53 | });
54 | default:
55 | return;
56 | }
57 | }
58 |
59 | // exports and appends an SVG for any viewer
60 | function exportSVG(viewer, posX, posY, ele) {
61 |
62 | return new Promise((resolve, reject) => {
63 | viewer.saveSVG(function(err, svg) {
64 |
65 | if (err) reject();
66 |
67 | ele.append(` ${svg}
`);
68 |
69 | $('.svg')
70 | .css('position', 'fixed')
71 | .css('bottom', (window.innerHeight - posY) * 0.5)
72 | .css('left', posX + 25)
73 | .css('z-index', 9999)
74 | .css('background-color', 'white')
75 | .css('height', '50%')
76 | .css('width', '50%')
77 | .css('box-shadow', '0px 0px 20px 5px rgba(0,0,0,1)');
78 |
79 | $('.svg svg')
80 | .attr('width', '100%')
81 | .attr('height', '100%');
82 |
83 | resolve();
84 | });
85 | })
86 |
87 | }
88 |
89 | // shows BPMN, CMMN and DMN (DRD) diagrams
90 | function showDiagram(e) {
91 | let sourceUrl = this.href || e.href;
92 | let viewerType = null;
93 |
94 | // to which parent element the svg will be appended
95 | let ele = $('.file-wrap');
96 | if (e.href)
97 | ele = $('body');
98 |
99 | if (sourceUrl.includes('.bpmn')) {
100 | viewerType = 'bpmn';
101 | } else if (sourceUrl.includes('.cmmn')) {
102 | viewerType = 'cmmn';
103 | } else if (sourceUrl.includes('.dmn')) {
104 | viewerType = 'dmn';
105 | } else {
106 | return;
107 | }
108 |
109 | var loc = getSrc(sourceUrl);
110 |
111 | $('body').append('');
112 | $('.js-canvas-parent').css('visibility', 'hidden');
113 |
114 | var viewer = returnViewer(viewerType);
115 |
116 | // ajax call to request content from github usercontent
117 | return new Promise((resolve, reject) => {
118 | $.ajax(loc, {
119 | dataType: 'json'
120 | }).done(function(json) {
121 | let xml = b64DecodeUnicode(json.content);
122 |
123 | viewer.importXML(xml, async function(err) {
124 |
125 | if (viewerType == 'dmn') {
126 | var activeView = viewer.getActiveView();
127 | // apply initial logic in DRD view
128 | if (activeView.type === 'drd') {
129 | var activeEditor = viewer.getActiveViewer();
130 |
131 | // access active editor components
132 | var canvas = activeEditor.get('canvas');
133 |
134 | // zoom to fit full viewport
135 | canvas.zoom('fit-viewport');
136 |
137 | await exportSVG(activeEditor, e.clientX, e.clientY, ele);
138 | }
139 | } else {
140 | (err) ? console.error(err): viewer.get('canvas').zoom('fit-viewport');
141 |
142 | await exportSVG(viewer, e.clientX, e.clientY, ele);
143 |
144 | resolve();
145 | }
146 | });
147 | });
148 | });
149 | }
150 |
151 | // removes diagram from drom
152 | function hideDiagram(e) {
153 | $('.svg').remove();
154 | $('.js-canvas-parent').remove();
155 | }
156 |
157 | function addRenderButton() {
158 | if ($('.final-path').length &&
159 | $('.final-path').text().includes('.bpmn') ||
160 | $('.final-path').text().includes('.cmmn') ||
161 | $('.final-path').text().includes('.dmn')
162 | ) {
163 | $('.Box-header .BtnGroup').append('Render');
164 | }
165 | $('a#render-diagram').on('click', openDiagram);
166 | }
167 |
168 | // opens the diagram in a new window
169 | async function openDiagram() {
170 | await showDiagram(this);
171 |
172 | var w = window.open();
173 | var html = $('.svg').html();
174 | $(w.document.body).html(html);
175 | }
176 |
177 | /**
178 | * Active calls
179 | */
180 |
181 | // add the render button in case of a site refresh
182 | addRenderButton();
183 | $('body').on('mouseenter', thumb_selector, showDiagram);
184 | $('body').on('mouseleave', thumb_selector, hideDiagram);
185 |
186 | // listens to node remove event in DOM, as GitHub dynamically changes the view within the a repository
187 | $('body').on('DOMNodeRemoved', async function(event) {
188 | if (typeof event.target.className == 'string' && event.target.className.includes('container-lg')) {
189 | await Sleep(500);
190 |
191 | addRenderButton();
192 | }
193 | });
194 |
195 | /**
196 | * Helper functions
197 | */
198 |
199 | function b64DecodeUnicode(str) {
200 | // Going backwards: from bytestream, to percent-encoding, to original string.
201 | return decodeURIComponent(atob(str).split('').map(function(c) {
202 | return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
203 | }).join(''));
204 | }
205 |
206 | function Sleep(milliseconds) {
207 | return new Promise(resolve => setTimeout(resolve, milliseconds));
208 | }
--------------------------------------------------------------------------------