├── package.json ├── .gitignore ├── icons └── trelloexport_128.png ├── xlsx ├── Trello Resources.xlsx └── Trello Development.xlsx ├── lib ├── zebra │ ├── css │ │ ├── flat │ │ │ ├── error.png │ │ │ ├── question.png │ │ │ ├── warning.png │ │ │ ├── confirmation.png │ │ │ ├── information.png │ │ │ ├── icons.txt │ │ │ ├── index.html │ │ │ └── zebra_dialog.css │ │ ├── default │ │ │ ├── error.png │ │ │ ├── warning.png │ │ │ ├── preloader.gif │ │ │ ├── question.png │ │ │ ├── confirmation.png │ │ │ ├── information.png │ │ │ ├── index.html │ │ │ └── zebra_dialog.css │ │ └── index.html │ └── zebra_dialog.js ├── js-xlsx │ └── LICENSE ├── datediff.js ├── bootstrap-multiselect │ └── bootstrap-multiselect.css ├── trelloexport.css ├── jquery.growl.css ├── FileSaver.min.js ├── tooltip.css ├── tingle.min.css ├── injectTrelloExporter.js ├── tingle.min.js ├── jquery.growl.js ├── tingle.css ├── simpleRetry.js ├── tooltip.js └── linq.min.js ├── bower_components ├── tingle │ ├── logo.png │ ├── bower.json │ ├── .bower.json │ ├── README.md │ ├── LICENSE │ └── dist │ │ ├── tingle.min.css │ │ ├── tingle.min.js │ │ ├── tingle.css │ │ └── tingle.js └── twigjs-bower │ ├── bower.json │ ├── package.json │ ├── .bower.json │ ├── README.md │ └── Gruntfile.js ├── .gitattributes ├── templates ├── newsletter.css ├── bibliography.css ├── newsletter.twig ├── newsletter2.twig ├── default.css ├── html.twig └── bibliography.twig ├── LICENSE ├── manifest.json └── README.md /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "jquery": "^3.6.4" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.icloud 3 | .vscode/* 4 | bower_components/* 5 | node_modules/* 6 | -------------------------------------------------------------------------------- /icons/trelloexport_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/icons/trelloexport_128.png -------------------------------------------------------------------------------- /xlsx/Trello Resources.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/xlsx/Trello Resources.xlsx -------------------------------------------------------------------------------- /lib/zebra/css/flat/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/flat/error.png -------------------------------------------------------------------------------- /xlsx/Trello Development.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/xlsx/Trello Development.xlsx -------------------------------------------------------------------------------- /lib/zebra/css/default/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/default/error.png -------------------------------------------------------------------------------- /lib/zebra/css/flat/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/flat/question.png -------------------------------------------------------------------------------- /lib/zebra/css/flat/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/flat/warning.png -------------------------------------------------------------------------------- /bower_components/tingle/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/bower_components/tingle/logo.png -------------------------------------------------------------------------------- /lib/zebra/css/default/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/default/warning.png -------------------------------------------------------------------------------- /lib/zebra/css/default/preloader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/default/preloader.gif -------------------------------------------------------------------------------- /lib/zebra/css/default/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/default/question.png -------------------------------------------------------------------------------- /lib/zebra/css/flat/confirmation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/flat/confirmation.png -------------------------------------------------------------------------------- /lib/zebra/css/flat/information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/flat/information.png -------------------------------------------------------------------------------- /lib/zebra/css/default/confirmation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/default/confirmation.png -------------------------------------------------------------------------------- /lib/zebra/css/default/information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trapias/TrelloExport/HEAD/lib/zebra/css/default/information.png -------------------------------------------------------------------------------- /lib/zebra/css/flat/icons.txt: -------------------------------------------------------------------------------- 1 | The icons were taken from http://www.elegantthemes.com/blog/freebie-of-the-week/beautiful-flat-icons-for-free -------------------------------------------------------------------------------- /lib/zebra/css/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 403 Forbidden 4 | 5 | 6 |

Directory access is forbidden.

7 | 8 | -------------------------------------------------------------------------------- /lib/zebra/css/flat/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 403 Forbidden 4 | 5 | 6 |

Directory access is forbidden.

7 | 8 | -------------------------------------------------------------------------------- /lib/zebra/css/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 403 Forbidden 4 | 5 | 6 |

Directory access is forbidden.

7 | 8 | -------------------------------------------------------------------------------- /bower_components/tingle/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tingle", 3 | "version": "0.13.2", 4 | "homepage": "https://github.com/robinparisi/tingle", 5 | "authors": [ 6 | "Robin Parisi " 7 | ], 8 | "main": "src/tingle.js", 9 | "license": "MIT", 10 | "ignore": [ 11 | "**/.*", 12 | "node_modules", 13 | "bower_components", 14 | "test", 15 | "tests", 16 | "gulpfile.js", 17 | "doc", 18 | "src", 19 | "package.json", 20 | "tingle.gif" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /bower_components/twigjs-bower/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twigjs-bower", 3 | "description": "A version of Twig JS for use with Bower", 4 | "main": "twig/twig.min.js", 5 | "authors": [ 6 | "Phil Baker " 7 | ], 8 | "license": "BSD-2-Clause", 9 | "keywords": [ 10 | "twig", 11 | "js", 12 | "bower" 13 | ], 14 | "homepage": "https://github.com/philsbury/twigjs-bower", 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /templates/newsletter.css: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3 { 4 | padding: 10px; 5 | font-weight: bold; 6 | } 7 | 8 | h2 { 9 | text-align: center 10 | } 11 | 12 | h3 { 13 | border-bottom: solid 1px #ccc; 14 | text-transform: uppercase 15 | } 16 | 17 | .card { 18 | border: none; 19 | border-bottom: solid 1px #ccc; 20 | margin-bottom: 20px; 21 | padding: 10px; 22 | } 23 | 24 | .card .info, 25 | .card .description { 26 | padding: 2px; 27 | } 28 | 29 | .card .comments, 30 | .card .attachments, 31 | .card .checklists, 32 | .card .customFields { 33 | padding-left: 10px; 34 | padding-bottom: 10px; 35 | } 36 | 37 | .card .comment, 38 | .card .attachment, 39 | .card .checklist, 40 | .card .customField { 41 | padding-left: 20px; 42 | background-color: white; 43 | } -------------------------------------------------------------------------------- /templates/bibliography.css: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3 { 4 | padding: 10px; 5 | font-weight: bold; 6 | } 7 | 8 | h2 { 9 | background-color: grey; 10 | color: white; 11 | margin-bottom: 20px; 12 | } 13 | 14 | h3 { 15 | padding: 5px; 16 | } 17 | 18 | .card { 19 | border: solid 1px #ccc; 20 | box-shadow: 5px 5px #eee; 21 | margin-bottom: 20px; 22 | padding: 10px; 23 | } 24 | 25 | .card .info, 26 | .card .description { 27 | padding: 2px; 28 | } 29 | 30 | .card .comments, 31 | .card .attachments, 32 | .card .checklists, 33 | .card .customFields { 34 | padding-left: 10px; 35 | padding-bottom: 10px; 36 | } 37 | 38 | .card .comment, 39 | .card .attachment, 40 | .card .checklist, 41 | .card .customField { 42 | padding-left: 20px; 43 | background-color: white; 44 | } -------------------------------------------------------------------------------- /bower_components/twigjs-bower/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twigjs-bower", 3 | "version": "1.10.5", 4 | "description": "A version of Twig JS for use with Bower", 5 | "main": "twig.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/philsbury/twigjs-bower.git" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/philsbury/twigjs-bower/issues" 17 | }, 18 | "homepage": "https://github.com/philsbury/twigjs-bower#readme", 19 | "devDependencies": { 20 | "grunt": "^1.0.1", 21 | "grunt-contrib-clean": "^1.0.0", 22 | "grunt-contrib-copy": "^1.0.0", 23 | "grunt-exec": "^1.0.1", 24 | "load-grunt-tasks": "^3.5.2" 25 | } 26 | } -------------------------------------------------------------------------------- /bower_components/tingle/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tingle", 3 | "version": "0.13.2", 4 | "homepage": "https://github.com/robinparisi/tingle", 5 | "authors": [ 6 | "Robin Parisi " 7 | ], 8 | "main": "src/tingle.js", 9 | "license": "MIT", 10 | "ignore": [ 11 | "**/.*", 12 | "node_modules", 13 | "bower_components", 14 | "test", 15 | "tests", 16 | "gulpfile.js", 17 | "doc", 18 | "src", 19 | "package.json", 20 | "tingle.gif" 21 | ], 22 | "_release": "0.13.2", 23 | "_resolution": { 24 | "type": "version", 25 | "tag": "v0.13.2", 26 | "commit": "1d1cdf8988ab05b9d0853ff5122e01ec0bf7d8e4" 27 | }, 28 | "_source": "https://github.com/robinparisi/tingle.git", 29 | "_target": "^0.13.2", 30 | "_originalSource": "tingle", 31 | "_direct": true 32 | } -------------------------------------------------------------------------------- /bower_components/twigjs-bower/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twigjs-bower", 3 | "description": "A version of Twig JS for use with Bower", 4 | "main": "twig/twig.min.js", 5 | "authors": [ 6 | "Phil Baker " 7 | ], 8 | "license": "BSD-2-Clause", 9 | "keywords": [ 10 | "twig", 11 | "js", 12 | "bower" 13 | ], 14 | "homepage": "https://github.com/philsbury/twigjs-bower", 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ], 22 | "version": "0.10.5", 23 | "_release": "0.10.5", 24 | "_resolution": { 25 | "type": "version", 26 | "tag": "0.10.5", 27 | "commit": "7e7dc0c59ff5b32a35f285f9a36532cbee92e0fc" 28 | }, 29 | "_source": "https://github.com/philsbury/twigjs-bower.git", 30 | "_target": "^0.10.5", 31 | "_originalSource": "twigjs-bower", 32 | "_direct": true 33 | } -------------------------------------------------------------------------------- /bower_components/tingle/README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Logo Tingle](logo.png) 3 | 4 | ## Documentation 5 | 6 | Documentation and demo can be found here: 7 | [https://robinparisi.github.io/tingle/](https://robinparisi.github.io/tingle/) 8 | 9 | ## Introduction 10 | 11 | Tingle is a minimalist and easy-to-use modal plugin written in pure JavaScript: 12 | 13 | * No dependencies required 14 | * Fully customizable via CSS 15 | * CSS transitions 16 | * Simple API 17 | * No extra files to download 18 | * Created with UX in mind 19 | 20 | ## Roadmap 21 | 22 | * ~~Flexbox support~~ 23 | * ~~Better responsive~~ 24 | * alert/dialog 25 | * Accessibility (any help is welcome) 26 | 27 | ## Contribute 28 | 29 | Run the demo and listen for changes: 30 | 31 | ```bash 32 | $ git clone git@github.com:robinparisi/tingle.git 33 | $ cd tingle 34 | $ npm install 35 | $ gulp serve 36 | ``` 37 | 38 | ## License 39 | 40 | © 2018 [Robin Parisi](https://github.com/robinparisi) 41 | Released under the [MIT LICENSE](http://opensource.org/licenses/MIT) 42 | -------------------------------------------------------------------------------- /lib/js-xlsx/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012-2014 SheetJS 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | Except where noted, this license applies to any and all software programs and associated documentation files created by the Original Author and distributed with the Software: 16 | 17 | 'jszip.js' is a modified version of JSZip, Copyright (c) Stuart Knightley, David Duponchel, Franz Buchinger, Ant'onio Afonso. JSZip is dual licensed and is used according to the terms of the MIT License. 18 | -------------------------------------------------------------------------------- /bower_components/twigjs-bower/README.md: -------------------------------------------------------------------------------- 1 | # twigjs-bower 2 | A bower package for Twig js 3 | 4 | 5 | Since the main twigjs project no longer supports bower, this has been created to plug that gap. 6 | 7 | The files are build from the main project. 8 | 9 | To use: 10 | ``` 11 | bower install twigjs-bower --save 12 | ``` 13 | 14 | ## A note on browser usage; the current docs say: 15 | 16 | ```javascript 17 | var template = twig({ 18 | data: 'The {{ baked_good }} is a lie.' 19 | }); 20 | 21 | console.log( 22 | template.render({baked_good: 'cupcake'}) 23 | ); 24 | // outputs: "The cupcake is a lie." 25 | ``` 26 | 27 | However this is resulting in `twig` being undefined. 28 | 29 | Instead, this will work: 30 | 31 | ```javascript 32 | var template = Twig.twig({ 33 | data: 'The {{ baked_good }} is a lie.' 34 | }); 35 | 36 | console.log( 37 | template.render({baked_good: 'cupcake'}) 38 | ); 39 | // outputs: "The cupcake is a lie." 40 | ``` 41 | 42 | All other documentation is as per the [main project](https://github.com/twigjs/twig.js/wiki). -------------------------------------------------------------------------------- /lib/datediff.js: -------------------------------------------------------------------------------- 1 | // https://gist.github.com/remino/1563963 2 | 3 | function DateDiff(date1, date2) { 4 | this.days = null; 5 | this.hours = null; 6 | this.minutes = null; 7 | this.seconds = null; 8 | this.date1 = date1; 9 | this.date2 = date2; 10 | 11 | this.init(); 12 | } 13 | 14 | DateDiff.prototype.init = function() { 15 | var data = new DateMeasure(this.date1 - this.date2); 16 | this.days = data.days; 17 | this.hours = data.hours; 18 | this.minutes = data.minutes; 19 | this.seconds = data.seconds; 20 | }; 21 | 22 | function DateMeasure(ms) { 23 | var d, h, m, s; 24 | s = Math.floor(ms / 1000); 25 | m = Math.floor(s / 60); 26 | s = s % 60; 27 | h = Math.floor(m / 60); 28 | m = m % 60; 29 | d = Math.floor(h / 24); 30 | h = h % 24; 31 | 32 | this.days = d; 33 | this.hours = h; 34 | this.minutes = m; 35 | this.seconds = s; 36 | }; 37 | 38 | Date.diff = function(date1, date2) { 39 | return new DateDiff(date1, date2); 40 | }; 41 | 42 | Date.prototype.diff = function(date2) { 43 | return new DateDiff(this, date2); 44 | }; 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 mtn-gc 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 | -------------------------------------------------------------------------------- /lib/bootstrap-multiselect/bootstrap-multiselect.css: -------------------------------------------------------------------------------- 1 | .multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px 3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0} -------------------------------------------------------------------------------- /bower_components/tingle/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Robin Parisi 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 | 23 | -------------------------------------------------------------------------------- /lib/trelloexport.css: -------------------------------------------------------------------------------- 1 | #optionslist { 2 | overflow-y: scroll; 3 | } 4 | 5 | #optionslist input, 6 | #optionslist select, 7 | #optionslist select option, 8 | #optionslist textarea { 9 | min-height: 1em; 10 | padding: 5px; 11 | font-size: 14px; 12 | font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; 13 | } 14 | 15 | #optionslist span { 16 | font-weight: bold; 17 | text-transform: uppercase; 18 | } 19 | 20 | #optionslist select { 21 | -webkit-appearance: menulist-button; 22 | background: #E2E4E6; 23 | } 24 | 25 | .TrelloExport h3 { 26 | color: #0079bf; 27 | /* rgb(0, 121, 191); */ 28 | } 29 | 30 | #optionslist label { 31 | display: inline-block !important; 32 | font-weight: normal !important; 33 | } 34 | 35 | #optionslist input:checked+label { 36 | text-decoration: underline; 37 | } 38 | 39 | .multiselect-container { 40 | z-index: 1; 41 | } 42 | 43 | .multiselect-container.dropdown-menu { 44 | background: white; 45 | border: solid 1px #0079bf; 46 | height: 300px; 47 | overflow-y: scroll; 48 | display: none; 49 | position: relative; 50 | } 51 | 52 | .blog-link { 53 | text-align: right; 54 | width: 70%; 55 | display: inline-block; 56 | } 57 | 58 | .sponsor img { 59 | position: relative; 60 | top: 10px; 61 | left: 20px; 62 | width: 150px; 63 | } 64 | 65 | .half { 66 | display: inline-block; 67 | width: 50%; 68 | } -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TrelloExport", 3 | "version": "1.9.81", 4 | "manifest_version": 3, 5 | "description": "TrelloExport (Trello Export) allows to export Trello boards to Excel spreadsheets, HTML with Twig templates, Markdown, OPML and CSV.", 6 | "icons": { "128": "icons/trelloexport_128.png" }, 7 | "content_scripts": [{ 8 | "matches": ["https://trello.com/*"], 9 | "css": ["lib/jquery.growl.css", 10 | "lib/zebra/css/flat/zebra_dialog.css", 11 | "lib/bootstrap-multiselect/bootstrap-multiselect.css", 12 | "lib/tooltip.css", 13 | "lib/tingle.min.css", 14 | "lib/trelloexport.css" 15 | ], 16 | "js": ["lib/jquery.min.js", 17 | "lib/FileSaver.min.js", 18 | "lib/js-xlsx/jszip.js", 19 | "lib/js-xlsx/xlsx.full.min.js", 20 | "lib/linq.min.js", 21 | "lib/jquery.growl.js", 22 | "lib/zebra/zebra_dialog.js", 23 | "lib/datediff.js", 24 | "lib/showdown.min.js", 25 | "lib/bootstrap-multiselect/bootstrap-multiselect.js", 26 | "lib/tooltip.js", 27 | "lib/twig.min.js", 28 | "lib/tingle.min.js", 29 | "lib/simpleRetry.js", 30 | "trelloexport.js", 31 | "lib/injectTrelloExporter.js" 32 | ] 33 | }], 34 | "web_accessible_resources": [ { 35 | "resources": [ 36 | "templates/*.twig", 37 | "templates/*.css" 38 | ], 39 | "matches": ["https://trello.com/*"] 40 | }], 41 | "homepage_url": "http://trapias.github.io", 42 | "host_permissions": [ 43 | "https://trello.com/", 44 | "*://*/*" 45 | ] 46 | } -------------------------------------------------------------------------------- /lib/jquery.growl.css: -------------------------------------------------------------------------------- 1 | /* jQuery Growl 2 | * Copyright 2015 Kevin Sylvestre 3 | * 1.2.5 4 | */ 5 | #growls { 6 | z-index: 50000; 7 | position: fixed; } 8 | #growls.default { 9 | top: 10px; 10 | right: 10px; } 11 | #growls.tl { 12 | top: 10px; 13 | left: 10px; } 14 | #growls.tr { 15 | top: 10px; 16 | right: 10px; } 17 | #growls.bl { 18 | bottom: 10px; 19 | left: 10px; } 20 | #growls.br { 21 | bottom: 10px; 22 | right: 10px; } 23 | #growls.tc { 24 | top: 10px; 25 | right: 10px; 26 | left: 10px; } 27 | #growls.bc { 28 | bottom: 10px; 29 | right: 10px; 30 | left: 10px; } 31 | #growls.tc .growl, #growls.bc .growl { 32 | margin-left: auto; 33 | margin-right: auto; } 34 | 35 | .growl { 36 | opacity: 0.8; 37 | filter: alpha(opacity=80); 38 | position: relative; 39 | border-radius: 4px; 40 | -webkit-transition: all 0.4s ease-in-out; 41 | -moz-transition: all 0.4s ease-in-out; 42 | transition: all 0.4s ease-in-out; } 43 | .growl.growl-incoming { 44 | opacity: 0; 45 | filter: alpha(opacity=0); } 46 | .growl.growl-outgoing { 47 | opacity: 0; 48 | filter: alpha(opacity=0); } 49 | .growl.growl-small { 50 | width: 200px; 51 | padding: 5px; 52 | margin: 5px; } 53 | .growl.growl-medium { 54 | width: 250px; 55 | padding: 10px; 56 | margin: 10px; } 57 | .growl.growl-large { 58 | width: 300px; 59 | padding: 15px; 60 | margin: 15px; } 61 | .growl.growl-default { 62 | color: #FFF; 63 | background: #7f8c8d; } 64 | .growl.growl-error { 65 | color: #FFF; 66 | background: #C0392B; } 67 | .growl.growl-notice { 68 | color: #FFF; 69 | background: #2ECC71; } 70 | .growl.growl-warning { 71 | color: #FFF; 72 | background: #F39C12; } 73 | .growl .growl-close { 74 | cursor: pointer; 75 | float: right; 76 | font-size: 14px; 77 | line-height: 18px; 78 | font-weight: normal; 79 | font-family: helvetica, verdana, sans-serif; } 80 | .growl .growl-title { 81 | font-size: 18px; 82 | line-height: 24px; } 83 | .growl .growl-message { 84 | font-size: 14px; 85 | line-height: 18px; } 86 | -------------------------------------------------------------------------------- /bower_components/twigjs-bower/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | var pkg = grunt.file.readJSON('package.json'); 4 | 5 | // Project configuration. 6 | grunt.initConfig({ 7 | pkg: pkg, 8 | exec: { 9 | update: "cd ./twig.js/ && git pull origin master && cd ../", 10 | build: "cd ./twig.js/ && npm run build && cd ../" 11 | }, 12 | copy: { 13 | main: { 14 | files: [ 15 | { 16 | cwd: 'twig.js/', 17 | src: 'twig.*', 18 | dest: 'twig/', 19 | expand: true 20 | } 21 | ] 22 | } 23 | }, 24 | gitadd: { 25 | dist: { 26 | options: { 27 | force: false 28 | }, 29 | files: { 30 | src: ['*'] 31 | } 32 | } 33 | }, 34 | gitcommit: { 35 | dist: { 36 | options: { 37 | cwd: "./", 38 | message: "Update to <%= pkg.version %>" 39 | }, 40 | files: [ 41 | { 42 | src: ["*", "!node_modules", "!twig.js"], 43 | expand: true, 44 | cwd: "./" 45 | } 46 | ] 47 | } 48 | }, 49 | gittag: { 50 | dist: { 51 | options: { 52 | tag: '<%= pkg.version %>' 53 | } 54 | } 55 | }, 56 | gitpush: { 57 | dist: { 58 | options: { 59 | remote: 'origin' 60 | // Target-specific options go here. 61 | } 62 | } 63 | }, 64 | }); 65 | 66 | // Load the plugin that provides the "uglify" task. 67 | require('load-grunt-tasks')(grunt); 68 | 69 | grunt.registerTask('test', function() { 70 | var twig = grunt.file.readJSON('twig.js/package.json'); 71 | 72 | 73 | 74 | if(pkg.version !== twig.version){ 75 | pkg.version = twig.version; 76 | var fs = require("fs"); 77 | var json = JSON.stringify(pkg, null, 2); 78 | fs.writeFileSync("package.json",json); 79 | 80 | grunt.config('pkg', twig.version); 81 | 82 | } 83 | 84 | }); 85 | 86 | // Default task(s). 87 | grunt.registerTask('default', ['exec:update', 'exec:build', 'copy', 'test']); 88 | 89 | }; -------------------------------------------------------------------------------- /lib/FileSaver.min.js: -------------------------------------------------------------------------------- 1 | /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ 2 | var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})} 3 | -------------------------------------------------------------------------------- /templates/newsletter.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TrelloExport Newsletter 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | {% set organizationName = '' %} 14 | {% set boardName = '' %} 15 | {% set prevList = '' %} 16 | {% for card in data.cards %} 17 | {% set theLink = '' %} 18 | {% if card.boardName != boardName %} 19 |

{{ card.boardName }}

20 | {% endif %} 21 | {% set boardName = card.boardName %} 22 | {% set organizationName = card.organizationName %} 23 | {% set curList = card.listName %} 24 | {% if prevList != curList %} 25 |

{{ curList }}

26 | {% endif %} 27 | {% set prevList = card.listName %} 28 | {# find attachment which is an URL and set to variable 'theLink' #} 29 | {% if card.jsonAttachments|length > 0 %} 30 | {% for attach in card.jsonAttachments %} 31 | {% if not attach.isUpload %} 32 | {% if theLink is empty %} 33 | {% set theLink = attach.url %} 34 | {% endif %} 35 | {% endif %} 36 | {% endfor %} 37 | {% endif %} 38 |
39 |
40 |
41 |

{{ card.title }}

42 |
43 |

{{ card.cardDescription }}

44 | {% if not theLink is empty %} 45 | READ MORE 46 | {% endif %} 47 |
48 |
49 |
50 |
51 | {% endfor %} 52 |
53 | 54 | -------------------------------------------------------------------------------- /templates/newsletter2.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TrelloExport Newsletter 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | {% set organizationName = '' %} 14 | {% set boardName = '' %} 15 | {% set prevList = '' %} 16 | {% for card in data.cards %} 17 | {% set theLink = '' %} 18 | {% if card.boardName != boardName %} 19 |

{{ card.boardName }}

20 | {% endif %} 21 | {% set boardName = card.boardName %} 22 | {% set organizationName = card.organizationName %} 23 | {% set curList = card.listName %} 24 | {% if prevList != curList %} 25 |

{{ curList }}

26 | {% endif %} 27 | {% set prevList = card.listName %} 28 | {# find attachment which is an URL and set to variable 'theLink' #} 29 | {% if card.jsonAttachments|length > 0 %} 30 | {% for attach in card.jsonAttachments %} 31 | {% if not attach.isUpload %} 32 | {% if theLink is empty %} 33 | {% set theLink = attach.url %} 34 | {% endif %} 35 | {% endif %} 36 | {% endfor %} 37 | {% endif %} 38 |
39 |
40 |
41 | {% if not theLink is empty %} 42 |

{{ card.title }}

43 | {% else %} 44 |

{{ card.title }}

45 | {% endif %} 46 |
47 |

{{ card.cardDescription }}

48 |
49 |
50 |
51 |
52 | {% endfor %} 53 |
54 | 55 | -------------------------------------------------------------------------------- /lib/tooltip.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | .tooltip { 8 | position: absolute; 9 | z-index: 1070; 10 | display: block; 11 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 12 | font-size: 12px; 13 | font-style: normal; 14 | font-weight: normal; 15 | line-height: 1.42857143; 16 | text-align: left; 17 | text-align: start; 18 | text-decoration: none; 19 | text-shadow: none; 20 | text-transform: none; 21 | letter-spacing: normal; 22 | word-break: normal; 23 | word-spacing: normal; 24 | word-wrap: normal; 25 | white-space: normal; 26 | filter: alpha(opacity=0); 27 | opacity: 0; 28 | line-break: auto; 29 | } 30 | 31 | .tooltip.in { 32 | filter: alpha(opacity=90); 33 | opacity: .9; 34 | } 35 | 36 | .tooltip.top { 37 | padding: 5px 0; 38 | margin-top: -3px; 39 | } 40 | 41 | .tooltip.right { 42 | padding: 0 5px; 43 | margin-left: 3px; 44 | } 45 | 46 | .tooltip.bottom { 47 | padding: 5px 0; 48 | margin-top: 3px; 49 | } 50 | 51 | .tooltip.left { 52 | padding: 0 5px; 53 | margin-left: -3px; 54 | } 55 | 56 | .tooltip-inner { 57 | max-width: 200px; 58 | padding: 3px 8px; 59 | color: #fff; 60 | text-align: center; 61 | background-color: #000; 62 | border-radius: 4px; 63 | } 64 | 65 | .tooltip-arrow { 66 | position: absolute; 67 | width: 0; 68 | height: 0; 69 | border-color: transparent; 70 | border-style: solid; 71 | } 72 | 73 | .tooltip.top .tooltip-arrow { 74 | bottom: 0; 75 | left: 50%; 76 | margin-left: -5px; 77 | border-width: 5px 5px 0; 78 | border-top-color: #000; 79 | } 80 | 81 | .tooltip.top-left .tooltip-arrow { 82 | right: 5px; 83 | bottom: 0; 84 | margin-bottom: -5px; 85 | border-width: 5px 5px 0; 86 | border-top-color: #000; 87 | } 88 | 89 | .tooltip.top-right .tooltip-arrow { 90 | bottom: 0; 91 | left: 5px; 92 | margin-bottom: -5px; 93 | border-width: 5px 5px 0; 94 | border-top-color: #000; 95 | } 96 | 97 | .tooltip.right .tooltip-arrow { 98 | top: 50%; 99 | left: 0; 100 | margin-top: -5px; 101 | border-width: 5px 5px 5px 0; 102 | border-right-color: #000; 103 | } 104 | 105 | .tooltip.left .tooltip-arrow { 106 | top: 50%; 107 | right: 0; 108 | margin-top: -5px; 109 | border-width: 5px 0 5px 5px; 110 | border-left-color: #000; 111 | } 112 | 113 | .tooltip.bottom .tooltip-arrow { 114 | top: 0; 115 | left: 50%; 116 | margin-left: -5px; 117 | border-width: 0 5px 5px; 118 | border-bottom-color: #000; 119 | } 120 | 121 | .tooltip.bottom-left .tooltip-arrow { 122 | top: 0; 123 | right: 5px; 124 | margin-top: -5px; 125 | border-width: 0 5px 5px; 126 | border-bottom-color: #000; 127 | } 128 | 129 | .tooltip.bottom-right .tooltip-arrow { 130 | top: 0; 131 | left: 5px; 132 | margin-top: -5px; 133 | border-width: 0 5px 5px; 134 | border-bottom-color: #000; 135 | } -------------------------------------------------------------------------------- /templates/default.css: -------------------------------------------------------------------------------- 1 | @import "http://fonts.googleapis.com/css?family=Open+Sans"; 2 | @import "http://fonts.googleapis.com/css?family=Patrick+Hand+SC"; 3 | html, 4 | body, 5 | footer, 6 | .footer { 7 | margin: 0; 8 | padding: 0; 9 | max-width: 100%; 10 | } 11 | 12 | html { 13 | font-size: 100%; 14 | font-family: 'Open Sans', sans-serif; 15 | margin: 0; 16 | padding: 0; 17 | width: 100%; 18 | } 19 | 20 | body { 21 | background: #fff; 22 | color: #333; 23 | font-family: 'Open Sans', sans-serif; 24 | min-height: 100vh; 25 | padding: 10px; 26 | } 27 | 28 | .TrelloExport { 29 | padding: 20px; 30 | } 31 | 32 | h1, 33 | h2, 34 | h3, 35 | h4, 36 | h5, 37 | h6, 38 | legend { 39 | font-family: 'Patrick Hand SC'; 40 | padding: 0; 41 | margin: 0; 42 | } 43 | 44 | h1 { 45 | background-color: #FFD000; 46 | color: black; 47 | padding: 10px; 48 | font-size: 2em; 49 | } 50 | 51 | h2 { 52 | color: #000; 53 | padding: 10px; 54 | font-size: 1.8em; 55 | border: solid 2px #FFD000; 56 | margin-top: 20px; 57 | } 58 | 59 | h2:first-of-type { 60 | margin-top: 10px 61 | } 62 | 63 | h3 { 64 | color: #B229FF; 65 | font-size: 1.5em; 66 | } 67 | 68 | h4 { 69 | font-size: 1.3em; 70 | /* text-decoration: underline; */ 71 | } 72 | 73 | p { 74 | font-size: 1em; 75 | } 76 | 77 | .clearfix:before, 78 | .clearfix:after { 79 | content: " "; 80 | display: table; 81 | } 82 | 83 | .clearfix:after { 84 | clear: both; 85 | } 86 | 87 | img { 88 | max-width: 100%; 89 | margin: 0 auto; 90 | } 91 | 92 | .FluidYellow { 93 | background-color: #FFD000; 94 | } 95 | 96 | a, 97 | a:visited, 98 | a:focus { 99 | color: #BB2DFF; 100 | } 101 | 102 | .col-md-3 { 103 | width: 50%; 104 | float: left; 105 | } 106 | 107 | .card { 108 | border: solid 1px #ccc; 109 | box-shadow: 5px 5px #eee; 110 | margin: 10px 0 10px 0; 111 | padding: 0 5px; 112 | } 113 | 114 | .card .info:first-of-type { 115 | margin-top: 5px 116 | } 117 | 118 | .card h1, 119 | .card h2, 120 | .card h3, 121 | .card h4, 122 | .card h5, 123 | .card h6, 124 | .card .info, 125 | .card .description, 126 | .card .comments, 127 | .card .comment, 128 | .card .attachments, 129 | .card .attachment, 130 | .card .checklists, 131 | .card .checklist, 132 | .card .customFields, 133 | .card .customField, 134 | .card .labels { 135 | padding: 2px; 136 | width: auto; 137 | max-width: 100%; 138 | background-color: white; 139 | } 140 | 141 | .card .customField { 142 | margin-left: 10px 143 | } 144 | 145 | .card .description p { 146 | padding: 0; 147 | } 148 | 149 | .card .label { 150 | display: inline-block; 151 | text-transform: uppercase; 152 | font-weight: bold; 153 | width: auto; 154 | min-width: 180px 155 | } 156 | 157 | .comment, 158 | .attachment { 159 | margin: 0 160 | } 161 | 162 | .comment .label, 163 | .attachment .label, 164 | .comment .text, 165 | .attachment .text { 166 | text-transform: none; 167 | display: block; 168 | width: auto; 169 | font-weight: bold; 170 | border: solid 1px #eee; 171 | background-color: #eee; 172 | border-radius: 5px; 173 | padding: 5px 174 | } 175 | 176 | .comment .text, 177 | .attachment .text { 178 | border: solid 1px white; 179 | background-color: white; 180 | } 181 | 182 | .checklists ul li .completed { 183 | font-size: .8em 184 | } -------------------------------------------------------------------------------- /bower_components/tingle/dist/tingle.min.css: -------------------------------------------------------------------------------- 1 | .tingle-modal *{box-sizing:border-box}.tingle-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;display:-webkit-box;display:-ms-flexbox;display:flex;visibility:hidden;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;overflow:hidden;-webkit-overflow-scrolling:touch;background:rgba(0,0,0,.8);opacity:0;cursor:pointer;-webkit-transition:-webkit-transform .2s ease;transition:-webkit-transform .2s ease;transition:transform .2s ease;transition:transform .2s ease,-webkit-transform .2s ease}.tingle-modal--noClose .tingle-modal__close,.tingle-modal__closeLabel{display:none}.tingle-modal--confirm .tingle-modal-box{text-align:center}.tingle-modal--noOverlayClose{cursor:default}.tingle-modal__close{position:fixed;top:10px;right:28px;z-index:1000;padding:0;width:5rem;height:5rem;border:none;background-color:transparent;color:#f0f0f0;font-size:6rem;font-family:monospace;line-height:1;cursor:pointer;-webkit-transition:color .3s ease;transition:color .3s ease}.tingle-modal__close:hover{color:#fff}.tingle-modal-box{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:auto;margin-bottom:auto;width:60%;border-radius:4px;background:#fff;opacity:1;cursor:auto;-webkit-transition:-webkit-transform .3s cubic-bezier(.175,.885,.32,1.275);transition:-webkit-transform .3s cubic-bezier(.175,.885,.32,1.275);transition:transform .3s cubic-bezier(.175,.885,.32,1.275);transition:transform .3s cubic-bezier(.175,.885,.32,1.275),-webkit-transform .3s cubic-bezier(.175,.885,.32,1.275);-webkit-transform:scale(.8);-ms-transform:scale(.8);transform:scale(.8)}.tingle-modal-box__content{padding:3rem}.tingle-modal-box__footer{padding:1.5rem 2rem;width:auto;border-bottom-right-radius:4px;border-bottom-left-radius:4px;background-color:#f5f5f5;cursor:auto}.tingle-modal-box__footer::after{display:table;clear:both;content:""}.tingle-modal-box__footer--sticky{position:fixed;bottom:-200px;z-index:10001;opacity:1;-webkit-transition:bottom .3s ease-in-out .3s;transition:bottom .3s ease-in-out .3s}.tingle-enabled{position:fixed;overflow:hidden;left:0;right:0}.tingle-modal--visible .tingle-modal-box__footer{bottom:0}.tingle-enabled .tingle-content-wrapper{-webkit-filter:blur(8px);filter:blur(8px)}.tingle-modal--visible{visibility:visible;opacity:1}.tingle-modal--visible .tingle-modal-box{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.tingle-modal--overflow{overflow-y:scroll;padding-top:8vh}.tingle-btn{display:inline-block;margin:0 .5rem;padding:1rem 2rem;border:none;background-color:grey;box-shadow:none;color:#fff;vertical-align:middle;text-decoration:none;font-size:inherit;font-family:inherit;line-height:normal;cursor:pointer;-webkit-transition:background-color .4s ease;transition:background-color .4s ease}.tingle-btn--primary{background-color:#3498db}.tingle-btn--danger{background-color:#e74c3c}.tingle-btn--default{background-color:#34495e}.tingle-btn--pull-left{float:left}.tingle-btn--pull-right{float:right}@media (max-width :540px){.tingle-modal{top:0;display:block;padding-top:60px;width:100%}.tingle-modal-box{width:auto;border-radius:0}.tingle-modal-box__content{overflow-y:scroll}.tingle-modal--noClose{top:0}.tingle-modal--noOverlayClose{padding-top:0}.tingle-modal-box__footer .tingle-btn{display:block;float:none;margin-bottom:1rem;width:100%}.tingle-modal__close{top:0;right:0;left:0;display:block;width:100%;height:60px;border:none;background-color:#2c3e50;box-shadow:none;color:#fff;line-height:55px}.tingle-modal__closeLabel{display:inline-block;vertical-align:middle;font-size:1.5rem;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.tingle-modal__closeIcon{display:inline-block;margin-right:.5rem;vertical-align:middle;font-size:4rem}}@supports ((-webkit-backdrop-filter:blur(12px)) or (backdrop-filter:blur(12px))){.tingle-modal{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}@media (max-width :540px){.tingle-modal{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}}.tingle-enabled .tingle-content-wrapper{-webkit-filter:none;filter:none}} -------------------------------------------------------------------------------- /lib/tingle.min.css: -------------------------------------------------------------------------------- 1 | .tingle-modal *{box-sizing:border-box}.tingle-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;display:-webkit-box;display:-ms-flexbox;display:flex;visibility:hidden;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;overflow:hidden;-webkit-overflow-scrolling:touch;background:rgba(0,0,0,.8);opacity:0;cursor:pointer;-webkit-transition:-webkit-transform .2s ease;transition:-webkit-transform .2s ease;transition:transform .2s ease;transition:transform .2s ease,-webkit-transform .2s ease}.tingle-modal--confirm .tingle-modal-box{text-align:center}.tingle-modal--noOverlayClose{cursor:default}.tingle-modal--noClose .tingle-modal__close{display:none}.tingle-modal__close{position:fixed;top:10px;right:28px;z-index:1000;padding:0;width:5rem;height:5rem;border:0;background-color:transparent;color:#f0f0f0;font-size:6rem;font-family:monospace;line-height:1;cursor:pointer;-webkit-transition:color .3s ease;transition:color .3s ease}.tingle-modal__closeLabel{display:none}.tingle-modal__close:hover{color:#fff}.tingle-modal-box{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:auto;margin-bottom:auto;width:60%;border-radius:4px;background:#fff;opacity:1;cursor:auto;-webkit-transition:-webkit-transform .3s cubic-bezier(.175,.885,.32,1.275);transition:-webkit-transform .3s cubic-bezier(.175,.885,.32,1.275);transition:transform .3s cubic-bezier(.175,.885,.32,1.275);transition:transform .3s cubic-bezier(.175,.885,.32,1.275),-webkit-transform .3s cubic-bezier(.175,.885,.32,1.275);-webkit-transform:scale(.8);-ms-transform:scale(.8);transform:scale(.8)}.tingle-modal-box__content{padding:3rem 3rem;max-height:80vh;overflow-y:scroll}.tingle-modal-box__footer{padding:1.5rem 2rem;width:auto;border-bottom-right-radius:4px;border-bottom-left-radius:4px;background-color:#f5f5f5;cursor:auto}.tingle-modal-box__footer::after{display:table;clear:both;content:""}.tingle-modal-box__footer--sticky{position:fixed;bottom:-200px;z-index:10001;opacity:1;-webkit-transition:bottom .3s ease-in-out .3s;transition:bottom .3s ease-in-out .3s}.tingle-enabled{position:fixed;overflow:hidden;left:0;right:0}.tingle-modal--visible .tingle-modal-box__footer{bottom:0}.tingle-enabled .tingle-content-wrapper{-webkit-filter:blur(8px);filter:blur(8px)}.tingle-modal--visible{visibility:visible;opacity:1}.tingle-modal--visible .tingle-modal-box{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.tingle-modal--overflow{overflow-y:scroll;padding-top:8vh}input[type="submit"]:hover,input[type="button"]:hover,button:hover,.button:hover,input[type="submit"]:focus,input[type="button"]:focus,button:focus{background:none;background-image:none!important}.tingle-btn{background-image:none!important;display:inline-block;margin:0 .5rem;padding:1rem 2rem;border:0;background-color:grey;box-shadow:none;color:#fff;vertical-align:middle;text-decoration:none;font-size:inherit;font-family:inherit;line-height:normal;cursor:pointer;-webkit-transition:background-color .4s ease;transition:background-color .4s ease}.tingle-btn--primary{background-color:#3498db}.tingle-btn--danger{background-color:#e74c3c}.tingle-btn--default{background-color:#34495e}.tingle-btn--default:hover{color:#34495e}.tingle-btn--trelloexport{background-color:#FDCE43;color:#333}.tingle-btn--trelloexport:hover{background-color:#333;color:#FDCE43}.tingle-btn--pull-left{float:left}.tingle-btn--pull-right{float:right}@media(max-width:540px){.tingle-modal{top:0;display:block;padding-top:60px;width:100%}.tingle-modal-box{width:auto;border-radius:0}.tingle-modal-box__content{overflow-y:scroll}.tingle-modal--noClose{top:0}.tingle-modal--noOverlayClose{padding-top:0}.tingle-modal-box__footer .tingle-btn{display:block;float:none;margin-bottom:1rem;width:100%}.tingle-modal__close{top:0;right:0;left:0;display:block;width:100%;height:60px;border:0;background-color:#2c3e50;box-shadow:none;color:#fff;line-height:55px}.tingle-modal__closeLabel{display:inline-block;vertical-align:middle;font-size:1.5rem;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.tingle-modal__closeIcon{display:inline-block;margin-right:.5rem;vertical-align:middle;font-size:4rem}}@supports((-webkit-backdrop-filter:blur(12px))or(backdrop-filter:blur(12px))){.tingle-modal{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}@media(max-width:540px){.tingle-modal{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}}.tingle-enabled .tingle-content-wrapper{-webkit-filter:none;filter:none}} -------------------------------------------------------------------------------- /lib/zebra/css/flat/zebra_dialog.css: -------------------------------------------------------------------------------- 1 | .ZebraDialog *, 2 | .ZebraDialog *:after, 3 | .ZebraDialog *:before { 4 | -moz-box-sizing: content-box !important; 5 | -webkit-box-sizing: content-box !important; 6 | box-sizing: content-box !important 7 | } 8 | 9 | .ZebraDialog { 10 | /*width: 450px;*/ 11 | width: 650px; 12 | z-index: 1001; 13 | border: 1px solid #DEDEDE; 14 | } 15 | 16 | .ZebraDialog, 17 | .ZebraDialog .ZebraDialog_Title, 18 | .ZebraDialog .ZebraDialog_Body, 19 | .ZebraDialog .ZebraDialog_Buttons a { 20 | margin: 0; 21 | padding: 0; 22 | font-family: Helvetica, Tahoma, Arial, sans-serif; 23 | font-size: 14px; 24 | text-align: left; 25 | line-height: 1.4; 26 | } 27 | 28 | .ZebraDialog .ZebraDialog_Title { 29 | font-size: 16px; 30 | font-weight: bold; 31 | color: #000; 32 | background: #FFF; 33 | padding: 12px 15px; 34 | vertical-align: middle; 35 | border-bottom: 1px solid #F0F0F0; 36 | } 37 | 38 | 39 | /* set background color here and not on ZebraDialog_Body, or you'll eventually run into problems with rounded corners 40 | when using smaller widths for border! */ 41 | 42 | .ZebraDialog .ZebraDialog_BodyOuter { 43 | background: #FFF; 44 | } 45 | 46 | .ZebraDialog .ZebraDialog_Body { 47 | color: #44484A; 48 | padding: 20px; 49 | overflow-y: scroll; 50 | max-height: 500px; 51 | height: auto; 52 | } 53 | 54 | .ZebraDialog .ZebraDialog_Body::-webkit-scrollbar { 55 | -webkit-appearance: scrollbarthumb-vertical 56 | } 57 | 58 | .ZebraDialog .ZebraDialog_ButtonsOuter { 59 | background: #FFF; 60 | padding: 10px 5px 10px 10px; 61 | } 62 | 63 | .ZebraDialog .ZebraDialog_Buttons:before, 64 | .ZebraDialog .ZebraDialog_Buttons:after { 65 | content: "\0020"; 66 | display: block; 67 | height: 0; 68 | visibility: hidden; 69 | font-size: 0 70 | } 71 | 72 | .ZebraDialog .ZebraDialog_Buttons:after { 73 | clear: both 74 | } 75 | 76 | .ZebraDialog .ZebraDialog_Buttons { 77 | *zoom: 1 78 | } 79 | 80 | 81 | /* for IE only */ 82 | 83 | .ZebraDialog .ZebraDialog_Buttons a { 84 | font-weight: bold; 85 | color: #FFF; 86 | padding: 10px 15px; 87 | } 88 | 89 | .ZebraDialog .ZebraDialog_Buttons a:hover { 90 | background: #224467; 91 | color: #FFF 92 | } 93 | 94 | .ZebraDialog a.ZebraDialog_Close { 95 | position: absolute; 96 | right: 6px; 97 | top: 0px; 98 | text-decoration: none; 99 | font-family: arial, sans-serif; 100 | font-weight: bold; 101 | font-size: 21px; 102 | color: #444 103 | } 104 | 105 | .ZebraDialog .ZebraDialog_Title a.ZebraDialog_Close { 106 | color: #888; 107 | } 108 | 109 | .ZebraDialog .ZebraDialog_Title a.ZebraDialog_Close:hover { 110 | color: #000; 111 | } 112 | 113 | .ZebraDialogOverlay { 114 | background: #666; 115 | z-index: 1000; 116 | width: 100%; 117 | height: 100%; 118 | } 119 | 120 | 121 | /* = YOU SHOULD NOT CHANGE ANYTHING FROM THIS POINT ON 122 | ---------------------------------------------------------------------------------------------------------------------*/ 123 | 124 | 125 | /* .ZebraDialog .ZebraDialog_Body { 126 | overflow: auto; 127 | } */ 128 | 129 | .ZebraDialog .ZebraDialog_Icon { 130 | background-repeat: no-repeat; 131 | background-position: 30px 40px; 132 | padding-left: 124px; 133 | min-height: 64px; 134 | _height: 64px; 135 | } 136 | 137 | .ZebraDialog .ZebraDialog_Confirmation { 138 | background-image: url('confirmation.png') 139 | } 140 | 141 | .ZebraDialog .ZebraDialog_Error { 142 | background-image: url('error.png') 143 | } 144 | 145 | .ZebraDialog .ZebraDialog_Information { 146 | background-image: url('information.png') 147 | } 148 | 149 | .ZebraDialog .ZebraDialog_Question { 150 | background-image: url('question.png') 151 | } 152 | 153 | .ZebraDialog .ZebraDialog_Warning { 154 | background-image: url('warning.png') 155 | } 156 | 157 | .ZebraDialog .ZebraDialog_Buttons a { 158 | white-space: nowrap; 159 | text-align: center; 160 | text-decoration: none; 161 | display: inline-block; 162 | margin-right: 5px; 163 | min-width: 60px; 164 | float: right; 165 | _width: 60px; 166 | background: #516270; 167 | } 168 | 169 | .ZebraDialog .ZebraDialog_Buttons_Centered .ZebraDialog_Buttons { 170 | display: table; 171 | margin: 0 auto; 172 | text-align: center; 173 | } 174 | 175 | .ZebraDialog .ZebraDialog_Buttons_Centered a { 176 | zoom: 1; 177 | *display: inline; 178 | } 179 | 180 | .ZebraDialog .ZebraDialog_Preloader { 181 | height: 32px; 182 | background: url('preloader.gif') no-repeat center center; 183 | } 184 | 185 | 186 | /* TrelloExport overrides */ 187 | 188 | .ZebraDialog_Body input[type=text], 189 | input[type=password], 190 | input[type=email] { 191 | width: inherit; 192 | } 193 | 194 | 195 | /** 196 | * Options Dialog 197 | */ 198 | 199 | #optionslist, 200 | #optionslist tr, 201 | #optionslist tr td { 202 | border: none; 203 | } 204 | 205 | #optionslist tr td:first-child { 206 | width: 40%; 207 | } 208 | 209 | #optionslist tr td:last-child { 210 | width: 60%; 211 | } -------------------------------------------------------------------------------- /lib/injectTrelloExporter.js: -------------------------------------------------------------------------------- 1 | var bTrelloExporterLoaded = false; 2 | var bExportSubmenuLoaded = false; 3 | 4 | console.log('[TrelloExport] Inject script loaded'); 5 | 6 | function TrelloExportLoader() { 7 | if (bTrelloExporterLoaded === true) return; 8 | setTimeout(function() { addExportLink(); }, 500); 9 | } 10 | 11 | // Check periodically but don't reset the flag unnecessarily 12 | setInterval(function() { 13 | // Only try to add if not already loaded 14 | if (bTrelloExporterLoaded === false) { 15 | addExportLink(); 16 | } 17 | // Also check for the export submenu 18 | checkExportSubmenu(); 19 | }, 1000); 20 | 21 | if (typeof String.prototype.startsWith != 'function') { 22 | String.prototype.startsWith = function(str) { 23 | return this.indexOf(str) === 0; 24 | }; 25 | } 26 | 27 | // Add a Export Excel button to the DOM and trigger export if clicked 28 | function addExportLink() { 29 | 30 | console.log('[TrelloExport] addExportLink called, loaded=' + bTrelloExporterLoaded); 31 | 32 | if(bTrelloExporterLoaded === true) return; 33 | 34 | // Just mark as loaded since we're now adding the button to the export submenu 35 | // We don't add it to the main menu anymore 36 | bTrelloExporterLoaded = true; 37 | console.log('[TrelloExport] Extension loaded, waiting for export submenu'); 38 | } 39 | 40 | // Function to check and add button to export submenu 41 | function checkExportSubmenu() { 42 | // Look for all sections that might be the export submenu 43 | // We check for multiple possible indicators 44 | var exportMenu = null; 45 | 46 | // Try to find by looking for print icon or common export-related elements 47 | $('section').each(function() { 48 | var section = $(this); 49 | // Check if this section contains buttons with print or export related content 50 | if (section.find('button').length > 0 && 51 | (section.find('svg path[d*="M4 3h12v3h1V3"]').length > 0 || // Print icon path 52 | section.find('button').text().match(/JSON|CSV|Print|Stampa|Esporta|Imprimir|Imprimer|Drucken|Печать|打印|印刷|列印/i))) { 53 | // Check if it's not the main menu (which has many more items) 54 | if (section.find('button').length < 10) { 55 | exportMenu = section; 56 | return false; // break the each loop 57 | } 58 | } 59 | }); 60 | 61 | if (!exportMenu || exportMenu.length === 0) { 62 | // Also try to find by checking if there's a section that appeared after clicking export 63 | var allSections = $('section[role="dialog"]'); 64 | if (allSections.length > 1) { 65 | // Get the last section which is likely the submenu 66 | exportMenu = allSections.last(); 67 | // Verify it's the right one by checking it has fewer items than main menu 68 | if (exportMenu.find('button').length > 10) { 69 | exportMenu = null; 70 | } 71 | } 72 | } 73 | 74 | if (!exportMenu || exportMenu.length === 0) { 75 | // Reset flag if submenu is closed 76 | if (bExportSubmenuLoaded) { 77 | console.log('[TrelloExport] Export submenu closed'); 78 | bExportSubmenuLoaded = false; 79 | } 80 | return; 81 | } 82 | 83 | if (bExportSubmenuLoaded === true) return; 84 | 85 | console.log('[TrelloExport] Found export submenu'); 86 | 87 | // Remove any existing export buttons in submenu 88 | exportMenu.find('.trelloexport-submenu').remove(); 89 | 90 | // Find the list in the submenu 91 | var submenuList = exportMenu.find('ul').first(); 92 | if (!submenuList || submenuList.length === 0) { 93 | console.log('[TrelloExport] No list found in export submenu'); 94 | return; 95 | } 96 | 97 | // Create the export button for submenu 98 | var $exportItem = $('
  • ') 99 | .append( 100 | $('