├── servers ├── flask │ ├── bll │ │ ├── __init__.py │ │ └── collectionmanager.py │ ├── core │ │ ├── __init__.py │ │ ├── lists │ │ │ ├── __init__.py │ │ │ └── listutils.py │ │ └── literature │ │ │ ├── __init__.py │ │ │ ├── text.py │ │ │ └── scribe.py │ ├── tests │ │ ├── __init__.py │ │ ├── helpers_test.py │ │ └── server_test.py │ ├── requirements.txt │ ├── runtests.py │ ├── templates │ │ ├── html-lab.html │ │ ├── partials │ │ │ ├── controls.html │ │ │ └── themes.html │ │ ├── rhtml-null-values.html │ │ ├── colors.html │ │ ├── rhtml-scores-fixed.html │ │ ├── scores-fixed.html │ │ ├── html-scores-fixed.html │ │ ├── colors-fixed.html │ │ ├── html-colors.html │ │ ├── colors-fixed-delay.html │ │ ├── rhtml-people-fixed.html │ │ ├── html-colors-fixed.html │ │ ├── rhtml-colors.html │ │ ├── html-colors-fixed-delay.html │ │ ├── rhtml-colors-fixed-delay.html │ │ ├── layout.html │ │ ├── rhtml-schemas.html │ │ ├── rhtml-colors-localized.html │ │ ├── rhtml-custom-views.html │ │ └── index.html │ └── README.md └── README.md ├── source ├── gulpfile.js ├── .babelrc ├── code │ ├── styles │ │ ├── openicon │ │ │ ├── github-link │ │ │ ├── fonts │ │ │ │ ├── open-iconic.eot │ │ │ │ ├── open-iconic.otf │ │ │ │ ├── open-iconic.ttf │ │ │ │ └── open-iconic.woff │ │ │ ├── ICON-LICENSE │ │ │ └── FONT-LICENSE │ │ └── kingtable │ │ │ ├── themes │ │ │ ├── flatblack │ │ │ │ ├── preloaders.less │ │ │ │ ├── flatblack.less │ │ │ │ ├── king-table.less │ │ │ │ ├── pagination-bars.less │ │ │ │ ├── menus.less │ │ │ │ └── search.less │ │ │ ├── midnight │ │ │ │ ├── preloaders.less │ │ │ │ ├── pagination-bars.less │ │ │ │ ├── midnight.less │ │ │ │ ├── search.less │ │ │ │ ├── menus.less │ │ │ │ └── king-table.less │ │ │ ├── flatwhite │ │ │ │ ├── flatwhite.less │ │ │ │ ├── king-table.less │ │ │ │ ├── pagination-bars.less │ │ │ │ └── search.less │ │ │ ├── clear │ │ │ │ ├── clear.less │ │ │ │ ├── menus.less │ │ │ │ ├── pagination-bars.less │ │ │ │ ├── search.less │ │ │ │ └── king-table.less │ │ │ ├── bronze │ │ │ │ ├── bronze.less │ │ │ │ ├── menus.less │ │ │ │ ├── pagination-bars.less │ │ │ │ ├── search.less │ │ │ │ └── king-table.less │ │ │ ├── olive │ │ │ │ ├── olive.less │ │ │ │ ├── menus.less │ │ │ │ ├── pagination-bars.less │ │ │ │ ├── search.less │ │ │ │ └── king-table.less │ │ │ ├── ultramarine │ │ │ │ ├── ultramarine.less │ │ │ │ ├── menus.less │ │ │ │ ├── pagination-bars.less │ │ │ │ ├── search.less │ │ │ │ └── king-table.less │ │ │ └── dark │ │ │ │ ├── menus.less │ │ │ │ ├── dark.less │ │ │ │ ├── pagination-bars.less │ │ │ │ ├── search.less │ │ │ │ └── king-table.less │ │ │ ├── filters-region.less │ │ │ ├── kingtable.dark.less │ │ │ ├── kingtable.clear.less │ │ │ ├── kingtable.flatblack.less │ │ │ ├── kingtable.midnight.less │ │ │ ├── tools.less │ │ │ ├── themes.less │ │ │ ├── preloaders.less │ │ │ ├── kingtable.core.less │ │ │ └── kingtable.less │ ├── scripts │ │ ├── main.js │ │ ├── data │ │ │ ├── querystore.js │ │ │ ├── memstore.js │ │ │ ├── sanitizer.js │ │ │ ├── xml.js │ │ │ ├── file.js │ │ │ ├── json.js │ │ │ ├── object-analyzer.js │ │ │ ├── csv.js │ │ │ └── lru.js │ │ ├── tables │ │ │ ├── kingtable.builder.js │ │ │ ├── kingtable.regional.js │ │ │ ├── kingtable.html.base.builder.js │ │ │ └── kingtable.xlsx.js │ │ ├── components │ │ │ ├── number.js │ │ │ ├── regex.js │ │ │ └── reflection.js │ │ ├── exceptions.js │ │ ├── literature │ │ │ └── text-slider.js │ │ ├── menus │ │ │ ├── kingtable.menu.js │ │ │ └── kingtable.menu.html.js │ │ └── raise.js │ ├── rp.png │ ├── ugr.png │ ├── favicon.ico │ ├── images │ │ ├── void.png │ │ └── tiny-loader.gif │ └── tests │ │ ├── number.spec.js │ │ ├── ajax.spec.js │ │ ├── regex.spec.js │ │ ├── sanitizer.spec.js │ │ ├── mock │ │ └── console.js │ │ ├── data │ │ ├── latest-scores.js │ │ └── colors-part.js │ │ ├── paginator.spec.js │ │ ├── obj-analyzer.spec.js │ │ ├── events.spec.js │ │ ├── csv.spec.js │ │ └── json.spec.js ├── gulp │ ├── index.js │ ├── util │ │ └── scriptFilter.js │ ├── tasks │ │ └── unit.js │ ├── config.js │ └── README.md ├── libs │ └── README.md ├── testdata │ ├── example-controls.js │ └── scores.js ├── karma.conf.js ├── karma-chrome.conf.js └── package.json ├── dist ├── styles │ ├── fonts │ │ ├── github-link │ │ ├── open-iconic.eot │ │ ├── open-iconic.otf │ │ ├── open-iconic.ttf │ │ ├── open-iconic.woff │ │ ├── ICON-LICENSE │ │ └── FONT-LICENSE │ └── kingtable.flatblack.css ├── README.md ├── locale │ └── kingtable.it.js └── kingtable.xlsx.js ├── kingtable-entry.js ├── snippets ├── README.md └── php-mysql │ ├── config.php │ ├── index.html │ └── README.md ├── httpdocs └── README.md ├── utils.js ├── .gitignore ├── package.json └── LICENSE /servers/flask/bll/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /servers/flask/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /servers/flask/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /servers/flask/core/lists/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /servers/flask/core/literature/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/gulpfile.js: -------------------------------------------------------------------------------- 1 | require("./gulp"); 2 | -------------------------------------------------------------------------------- /source/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } -------------------------------------------------------------------------------- /dist/styles/fonts/github-link: -------------------------------------------------------------------------------- 1 | https://github.com/iconic/open-iconic -------------------------------------------------------------------------------- /source/code/styles/openicon/github-link: -------------------------------------------------------------------------------- 1 | https://github.com/iconic/open-iconic -------------------------------------------------------------------------------- /source/code/scripts/main.js: -------------------------------------------------------------------------------- 1 | import KingTable from "../scripts/tables/kingtable"; 2 | -------------------------------------------------------------------------------- /source/code/rp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/rp.png -------------------------------------------------------------------------------- /source/code/ugr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/ugr.png -------------------------------------------------------------------------------- /kingtable-entry.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = require("./src/scripts/tables/kingtable").default; -------------------------------------------------------------------------------- /source/code/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/favicon.ico -------------------------------------------------------------------------------- /snippets/README.md: -------------------------------------------------------------------------------- 1 | # KingTable snippets 2 | This folder contains code snippets for uses of the KingTable library. -------------------------------------------------------------------------------- /source/code/images/void.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/images/void.png -------------------------------------------------------------------------------- /dist/styles/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/dist/styles/fonts/open-iconic.eot -------------------------------------------------------------------------------- /dist/styles/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/dist/styles/fonts/open-iconic.otf -------------------------------------------------------------------------------- /dist/styles/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/dist/styles/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /dist/styles/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/dist/styles/fonts/open-iconic.woff -------------------------------------------------------------------------------- /source/code/images/tiny-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/images/tiny-loader.gif -------------------------------------------------------------------------------- /source/code/styles/openicon/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/styles/openicon/fonts/open-iconic.eot -------------------------------------------------------------------------------- /source/code/styles/openicon/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/styles/openicon/fonts/open-iconic.otf -------------------------------------------------------------------------------- /source/code/styles/openicon/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/styles/openicon/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /source/code/styles/openicon/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobertoPrevato/KingTable/HEAD/source/code/styles/openicon/fonts/open-iconic.woff -------------------------------------------------------------------------------- /servers/flask/requirements.txt: -------------------------------------------------------------------------------- 1 | click==6.7 2 | Flask==0.12 3 | itsdangerous==0.24 4 | Jinja2==2.9.5 5 | MarkupSafe==0.23 6 | Unidecode==0.4.20 7 | Werkzeug==0.11.15 8 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/flatblack/preloaders.less: -------------------------------------------------------------------------------- 1 | .theme-flatblack { 2 | .king-table-container { 3 | .preloader-mask { 4 | opacity: .5; 5 | background-color: #5F0909; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/midnight/preloaders.less: -------------------------------------------------------------------------------- 1 | .theme-midnight { 2 | .king-table-container { 3 | .preloader-mask { 4 | opacity: .5; 5 | background-color: #091431; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /source/gulp/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const onlyScripts = require("./util/scriptFilter"); 3 | const tasks = fs.readdirSync("./gulp/tasks/").filter(onlyScripts); 4 | 5 | tasks.forEach(task => { 6 | require("./tasks/" + task); 7 | }); 8 | -------------------------------------------------------------------------------- /source/gulp/util/scriptFilter.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | // Filters out non .js files. Prevents 4 | // accidental inclusion of possible hidden files 5 | module.exports = function (name) { 6 | return /(\.js$)/i.test(path.extname(name)); 7 | }; 8 | -------------------------------------------------------------------------------- /servers/flask/runtests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | # 4 | # import the test cases that need to be run 5 | # 6 | from tests.server_test import ServerTestCase 7 | from tests.helpers_test import HelpersTestCase 8 | from tests.array_test import ArrayUtilsTestCase 9 | 10 | if __name__ == "__main__": 11 | unittest.main() 12 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/filters-region.less: -------------------------------------------------------------------------------- 1 | /* filters-region */ 2 | 3 | .king-table-region { 4 | .filters-region { 5 | font-size: 12px; 6 | padding-top: 2px; 7 | border-bottom: 1px solid #ccc; 8 | display: none; 9 | .buttons { 10 | padding: 0 10px 15px 15px; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/flatwhite/flatwhite.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | 5 | .theme-flatwhite { 6 | color:#000; 7 | background-color: #FFF; 8 | 9 | hr { 10 | border-top: 1px solid #aaa; 11 | border-bottom: 1px solid #fff; 12 | } 13 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/clear/clear.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | @import "menus.less"; 5 | 6 | .theme-clear { 7 | color:#000; 8 | background-color: #FFF; 9 | 10 | hr { 11 | border-top: 1px solid #aaa; 12 | border-bottom: 1px solid #fff; 13 | } 14 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/kingtable.dark.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | @import "./themes/dark/dark.less"; 12 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/kingtable.clear.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | @import "./themes/clear/clear.less"; 12 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/bronze/bronze.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | @import "menus.less"; 5 | 6 | .theme-bronze { 7 | color: #000; 8 | background-color: #3a1700; 9 | 10 | hr { 11 | border-top: 1px solid #a82d00; 12 | border-bottom: 1px solid #ffab25; 13 | } 14 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/kingtable.flatblack.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | @import "./themes/flatblack/flatblack.less"; 12 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/kingtable.midnight.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | @import "./themes/midnight/midnight.less"; 12 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/tools.less: -------------------------------------------------------------------------------- 1 | /* tools */ 2 | .king-table-region { 3 | .tools-region { 4 | float: left; 5 | margin-right: 5px; 6 | .ug-expander { 7 | display: inline-block; 8 | cursor: pointer; 9 | padding: 5px 7px; 10 | } 11 | 12 | &:hover { 13 | .menu { 14 | display: block; 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes.less: -------------------------------------------------------------------------------- 1 | @import "./themes/flatwhite/flatwhite.less"; 2 | @import "./themes/flatblack/flatblack.less"; 3 | @import "./themes/clear/clear.less"; 4 | @import "./themes/dark/dark.less"; 5 | @import "./themes/olive/olive.less"; 6 | @import "./themes/bronze/bronze.less"; 7 | @import "./themes/ultramarine/ultramarine.less"; 8 | @import "./themes/midnight/midnight.less"; 9 | -------------------------------------------------------------------------------- /source/libs/README.md: -------------------------------------------------------------------------------- 1 | ## External libraries 2 | 3 | Promise polyfill (required, for example, by IE11 and IE10) 4 | * [https://github.com/stefanpenner/es6-promise](https://github.com/stefanpenner/es6-promise) 5 | 6 | --- 7 | For export to Excel plugin: 8 | * [https://github.com/SheetJS/js-xlsx](https://github.com/SheetJS/js-xlsx) 9 | * [https://github.com/eligrey/Blob.js/](https://github.com/eligrey/Blob.js/) 10 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/flatblack/flatblack.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | @import "preloaders.less"; 5 | @import "menus.less"; 6 | 7 | .theme-flatblack { 8 | color: #DADAD4; 9 | background-color: #000; 10 | 11 | .camo-btn { 12 | color: #DADAD4; 13 | } 14 | 15 | hr { 16 | border-top: 1px solid #aaa; 17 | border-bottom: 1px solid #fff; 18 | } 19 | } -------------------------------------------------------------------------------- /servers/flask/templates/html-lab.html: -------------------------------------------------------------------------------- 1 | {%- extends "layout-no.html" -%} 2 | {%- block title -%} 3 | HTML Lab. 4 | {%- endblock -%} 5 | {%- block body -%} 6 |

Not live:

7 |
8 |
9 |

Live:

10 |
11 | {%- endblock -%} 12 | {%- block js -%} 13 | 14 | 19 | {%- endblock -%} 20 | -------------------------------------------------------------------------------- /servers/flask/templates/partials/controls.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/flatblack/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-flatblack { 2 | .king-table tr { 3 | border-bottom: 1px solid #4A1111; 4 | } 5 | 6 | 7 | .king-table-head { 8 | background-color: #000; 9 | } 10 | 11 | .filters-region { 12 | border-bottom-color: #000; 13 | } 14 | 15 | a { 16 | color: #DADAD4; 17 | } 18 | 19 | .king-table-body tr { 20 | &:hover { 21 | background-color: #2D0303; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/preloaders.less: -------------------------------------------------------------------------------- 1 | .king-table-container { 2 | .preloader-mask { 3 | height: 100%; 4 | width: 100%; 5 | min-height: 300px; 6 | position: absolute; 7 | top: 0; 8 | opacity: .5; 9 | background-color: white; 10 | .preloader-icon { 11 | position: absolute; 12 | background-repeat: no-repeat; 13 | background-position: 50% 50%; 14 | height: 100%; 15 | width: 100%; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/flatwhite/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-flatwhite { 2 | .king-table tr { 3 | border-bottom: 1px solid #eee; 4 | } 5 | 6 | .pagination-bar { 7 | .oi { 8 | color: #666; 9 | } 10 | } 11 | 12 | .king-table-head { 13 | background-color: #FFF; 14 | } 15 | 16 | .king-table a { 17 | color: #000; 18 | } 19 | 20 | .king-table-body tr { 21 | &:hover { 22 | background-color: #F7F7F7; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/flatwhite/pagination-bars.less: -------------------------------------------------------------------------------- 1 | .theme-flatwhite { 2 | .pagination-bar { 3 | background-color: #FFF; 4 | border: 0; 5 | border-bottom: 1px solid #ccc; 6 | 7 | .pagination-button, .pagination-button-disabled, .separator { 8 | border: 1px solid transparent; 9 | } 10 | 11 | .separator { 12 | border-right: 1px solid #D6D6D6; 13 | } 14 | 15 | select, .search-field { 16 | border-radius: 0; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /snippets/php-mysql/config.php: -------------------------------------------------------------------------------- 1 | { 7 | new Server({ 8 | configFile: path.resolve(__dirname, "../..", config.test.karma), 9 | singleRun: true 10 | }).start(); 11 | }); 12 | 13 | gulp.task("watch-unit", () => { 14 | new Server({ 15 | configFile: path.resolve(__dirname, "../..", config.test.karma), 16 | singleRun: false 17 | }).start(); 18 | }); -------------------------------------------------------------------------------- /servers/README.md: -------------------------------------------------------------------------------- 1 | # Servers 2 | This folder contains development web servers, to test server side integration of the KingTable library. 3 | Currently, a single implementation using Python Flask web framework is implemented. 4 | 5 | Development servers are meant to serve static files included in above `httpdocs` folder, which is prepared by running the gulp command, from `source` folder: 6 | ```bash 7 | gulp dev-init 8 | ``` 9 | 10 | Each folder contains a README.md file with instructions on how to run the provided development server. 11 | 12 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/olive/olive.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | @import "menus.less"; 5 | 6 | .theme-olive { 7 | color: #455b1b; 8 | background-color: #233107; 9 | 10 | .camo-btn { 11 | color: #455b1b; 12 | } 13 | 14 | input, select, [tabindex], [type="checkbox"] { 15 | outline-color: #25150a !important; 16 | } 17 | 18 | hr { 19 | border-top: 1px solid #afc423; 20 | border-bottom: 1px solid #e3ee9f; 21 | } 22 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/ultramarine/ultramarine.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | @import "menus.less"; 5 | 6 | .theme-ultramarine { 7 | color: #071436; 8 | background-color: #010004; 9 | 10 | .camo-btn { 11 | color: #071436; 12 | } 13 | 14 | input, select, [tabindex], [type="checkbox"] { 15 | outline-color: #c4feff !important; 16 | } 17 | 18 | hr { 19 | border-top: 1px solid #09165a; 20 | border-bottom: 1px solid #5252b3; 21 | } 22 | } -------------------------------------------------------------------------------- /source/code/scripts/data/querystore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Query string storage, provides methods to store and manipulate values 3 | * inside the query string. 4 | * https://github.com/RobertoPrevato/KingTable 5 | * 6 | * Copyright 2018, Roberto Prevato 7 | * https://robertoprevato.github.io 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | export default { 14 | 15 | getItem(name) { 16 | 17 | }, 18 | 19 | setItem(name, value) { 20 | 21 | }, 22 | 23 | removeItem(name) { 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/kingtable.core.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | @import "pagination-bars.less"; 12 | @import "filters-region.less"; 13 | @import "menus.less"; 14 | @import "tools.less"; 15 | @import "themes/flatwhite/flatwhite.less"; 16 | @import "preloaders.less"; 17 | @import "kingtable-structure.less"; 18 | @import "../openicon/css/open-iconic.less"; -------------------------------------------------------------------------------- /source/code/styles/kingtable/kingtable.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | @import "pagination-bars.less"; 12 | @import "filters-region.less"; 13 | @import "menus.less"; 14 | @import "tools.less"; 15 | @import "themes.less"; 16 | @import "preloaders.less"; 17 | @import "kingtable-structure.less"; 18 | @import "../openicon/css/open-iconic.less"; 19 | -------------------------------------------------------------------------------- /servers/flask/templates/rhtml-null-values.html: -------------------------------------------------------------------------------- 1 | {%- extends "layout.html" -%} 2 | {%- block title -%} 3 | KingTable colors demo 4 | {%- endblock -%} 5 | {%- block body -%} 6 | {% include "partials/themes.html" %} 7 |
8 | {%- endblock -%} 9 | {%- block js -%} 10 | 11 | 23 | {%- endblock -%} 24 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/clear/menus.less: -------------------------------------------------------------------------------- 1 | .theme-clear { 2 | .king-table-region { 3 | .ug-menu { 4 | box-shadow: 0 6px 12px #717171; 5 | background: #eee; 6 | color: #000; 7 | 8 | li { 9 | border-bottom: 1px solid #C1C1C1; 10 | span, a, label { 11 | color: #000; 12 | &:focus, &:hover { 13 | color: #000; 14 | background-color: #E0E0E0; 15 | } 16 | } 17 | 18 | &.open { 19 | > span, > a, > label { 20 | background-color: #E0E0E0; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/dark/menus.less: -------------------------------------------------------------------------------- 1 | .theme-dark { 2 | .king-table-region { 3 | .ug-menu { 4 | box-shadow: 0 6px 12px #000; 5 | background: #313131; 6 | color: #DEDEDE; 7 | 8 | li { 9 | border-bottom: 1px solid grey; 10 | span, a, label { 11 | color: #DEDEDE; 12 | &:focus, &:hover { 13 | color: #DEDEDE; 14 | background-color: #222; 15 | } 16 | } 17 | 18 | &.open { 19 | > span, > a, > label { 20 | background-color: #222; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/bronze/menus.less: -------------------------------------------------------------------------------- 1 | .theme-bronze { 2 | .king-table-region { 3 | .ug-menu { 4 | box-shadow: 0 6px 12px #691010; 5 | background: #FFA92D; 6 | color: #3a1700; 7 | 8 | li { 9 | border-bottom: 1px solid #4A1111; 10 | span, a, label { 11 | color: #3a1700; 12 | &:focus, &:hover { 13 | color: #3a1700; 14 | background-color: #ffecb5; 15 | } 16 | } 17 | 18 | &.open { 19 | > span, > a, > label { 20 | background-color: #ffecb5; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/olive/menus.less: -------------------------------------------------------------------------------- 1 | .theme-olive { 2 | .king-table-region { 3 | .ug-menu { 4 | box-shadow: 0 6px 12px #475F15; 5 | background: #DDE979; 6 | color: #455b1b; 7 | 8 | li { 9 | border-bottom: 1px solid #BEBD63; 10 | span, a, label { 11 | color: #455b1b; 12 | &:focus, &:hover { 13 | color: #455b1b; 14 | background-color: #e6f0a3; 15 | } 16 | } 17 | 18 | &.open { 19 | > span, > a, > label { 20 | background-color: #e6f0a3; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/flatblack/menus.less: -------------------------------------------------------------------------------- 1 | .theme-flatblack { 2 | .king-table-region { 3 | .ug-menu { 4 | box-shadow: 0 6px 12px #691010; 5 | background: #111; 6 | color: #DADAD4; 7 | 8 | li { 9 | border-bottom: 1px solid #4A1111; 10 | span, a, label { 11 | color: #DADAD4; 12 | &:focus, &:hover { 13 | color: #DADAD4; 14 | background-color: #2D0303; 15 | } 16 | } 17 | 18 | &.open { 19 | > span, > a, > label { 20 | background-color: #2D0303; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/ultramarine/menus.less: -------------------------------------------------------------------------------- 1 | .theme-ultramarine { 2 | .king-table-region { 3 | .ug-menu { 4 | box-shadow: 0 6px 12px #081125; 5 | background: #619CD6; 6 | color: #000; 7 | 8 | li { 9 | border-bottom: 1px solid #2873AC; 10 | span, a, label { 11 | color: #455b1b; 12 | &:focus, &:hover { 13 | color: #455b1b; 14 | background-color: #7DB3EF; 15 | } 16 | } 17 | 18 | &.open { 19 | > span, > a, > label { 20 | background-color: #7DB3EF; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /servers/flask/core/literature/text.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | class Text: 5 | 6 | @staticmethod 7 | def condensate(txt): 8 | """ 9 | Returns a condensed version of the given string, trimming, removing line breaks and multiple spaces 10 | """ 11 | s = txt.strip() 12 | s = Text.remove_line_breaks(s) 13 | s = Text.remove_multiple_spaces(s) 14 | return s 15 | 16 | @staticmethod 17 | def remove_line_breaks(txt): 18 | return txt.replace('\n', ' ').replace('\r', '') 19 | 20 | @staticmethod 21 | def remove_multiple_spaces(txt): 22 | return re.sub("[\s]+", " ", txt) 23 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/midnight/pagination-bars.less: -------------------------------------------------------------------------------- 1 | .theme-midnight { 2 | .pagination-bar { 3 | background-repeat: repeat-x; 4 | background-position: top left; 5 | background-image: url("data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABmJLR0QAigA6AAVbg4eFAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QcKDRQh1fbNfQAAAElJREFUCNdVikEKwDAMwxRD2fP3gLGPxinZYWWsFyEbcV53q6pQpZGdC+ncP6Ny8sZretmchnGMFoCC4LUfAhQdiGhEg/i62OIHIVwwSHkNyBEAAAAASUVORK5CYII="); 6 | 7 | .pagination-button, .pagination-button-disabled, .separator { 8 | border: 1px solid transparent; 9 | } 10 | 11 | .separator { 12 | border-right: 1px solid #1C3131; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /servers/flask/templates/partials/themes.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 10 | 19 |
-------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/midnight/midnight.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | @import "preloaders.less"; 5 | @import "menus.less"; 6 | 7 | .theme-midnight { 8 | color: #c4feff; 9 | background-color: #000; 10 | 11 | .camo-btn { 12 | color: #c4feff; 13 | } 14 | 15 | input, select, textarea { 16 | background-color: #000; 17 | border-color: #333; 18 | color: #c4feff; 19 | } 20 | 21 | input, select, [tabindex], [type="checkbox"] { 22 | outline-color: #c4feff !important; 23 | } 24 | 25 | hr { 26 | border-top: 1px solid #02232a; 27 | border-bottom: 1px solid #106274; 28 | } 29 | } -------------------------------------------------------------------------------- /servers/flask/tests/helpers_test.py: -------------------------------------------------------------------------------- 1 | import server 2 | import unittest 3 | 4 | 5 | class HelpersTestCase(unittest.TestCase): 6 | """ 7 | Custom template helpers tests. 8 | """ 9 | def setUp(self): 10 | """ 11 | The code in the setUp() method is called before each individual test function is run. 12 | """ 13 | #print("setup..") 14 | self.app = server.app.test_client() 15 | 16 | def tearDown(self): 17 | """ 18 | The code in the setUp() method is called before each individual test function is run. 19 | """ 20 | #print("end..") 21 | 22 | def test_resources_helper(self): 23 | print("Waa!") 24 | assert True == True 25 | -------------------------------------------------------------------------------- /snippets/php-mysql/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | KingTable sample working with PHP and MySQL 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 22 | 23 | -------------------------------------------------------------------------------- /source/code/tests/number.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests for Number utilities. 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | import _ from "../scripts/utils"; 12 | //import N from "../scripts/components/number"; 13 | 14 | describe("Number utilities", () => { 15 | 16 | it("must support Intl", () => { 17 | expect(typeof Intl).not.toEqual("undefined", "Intl must be defined"); 18 | }); 19 | 20 | it("must support Intl.NumberFormat", () => { 21 | var a = Intl.NumberFormat(); 22 | expect(a.format(1000)).toEqual("1,000") 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/dark/dark.less: -------------------------------------------------------------------------------- 1 | @import "king-table.less"; 2 | @import "pagination-bars.less"; 3 | @import "search.less"; 4 | @import "menus.less"; 5 | 6 | .theme-dark { 7 | color: #DEDEDE; 8 | background-color: #000; 9 | 10 | a, a:hover, a:focus { 11 | color: #DEDEDE; 12 | } 13 | 14 | .camo-btn { 15 | color: #DADAD4; 16 | } 17 | 18 | hr { 19 | border-top: 1px solid #444; 20 | border-bottom: 1px solid #000; 21 | } 22 | 23 | input { 24 | color: #000; 25 | } 26 | 27 | input, select, [tabindex], [type="checkbox"] { 28 | outline-color: #FFF !important; 29 | } 30 | 31 | .tooltip-inner { 32 | opacity: 1; 33 | background-color: #000; 34 | } 35 | } -------------------------------------------------------------------------------- /servers/flask/templates/colors.html: -------------------------------------------------------------------------------- 1 | {%- extends "layout.html" -%} 2 | {%- block title -%} 3 | KingTable colors demo 4 | {%- endblock -%} 5 | {%- block body -%} 6 | {% include "partials/controls.html" %} 7 |

 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   
26 |   
27 | {%- endblock -%}
28 | 


--------------------------------------------------------------------------------
/servers/flask/templates/rhtml-scores-fixed.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable - latest scores demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 |   {% include "partials/themes.html" %}
 7 |   
8 | {%- endblock -%} 9 | {%- block js -%} 10 | 11 | 26 | {%- endblock -%} 27 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/dark/pagination-bars.less: -------------------------------------------------------------------------------- 1 | .theme-dark { 2 | .pagination-bar { 3 | background-repeat: repeat-x; 4 | background-position: top left; 5 | background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQH/8QAGBABAQADAAAAAAAAAAAAAAAAABIBE2H/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oADAMBAAIRAxEAPwDIrE19FiptglvIEv/Z"); 6 | 7 | .pagination-button, .pagination-button-disabled, .separator { 8 | border: 1px solid transparent; 9 | } 10 | 11 | .separator { 12 | border-right: 1px solid #151515; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/code/scripts/tables/kingtable.builder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * KingTable base builder class. 3 | * Base class for all builders. 4 | * 5 | * https://github.com/RobertoPrevato/KingTable 6 | * 7 | * Copyright 2018, Roberto Prevato 8 | * https://robertoprevato.github.io 9 | * 10 | * Licensed under the MIT license: 11 | * http://www.opensource.org/licenses/MIT 12 | */ 13 | import EventsEmitter from "../../scripts/components/events" 14 | import KingTable from "../../scripts/tables/kingtable" 15 | 16 | export default class KingTableBuilder extends EventsEmitter { 17 | 18 | constructor(table) { 19 | super() 20 | this.table = table; 21 | } 22 | 23 | /** 24 | * Returns the translations for the current language configuration. 25 | */ 26 | getReg() { 27 | var table = this.table; 28 | return table ? table.getReg() : KingTable.regional.en; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/bronze/pagination-bars.less: -------------------------------------------------------------------------------- 1 | .theme-bronze { 2 | .pagination-bar { 3 | background-repeat: repeat-x; 4 | background-position: top left; 5 | background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAQFBgf/xAAeEAEAAAUFAAAAAAAAAAAAAAAAAQIEE2EFFVWU0f/EABYBAQEBAAAAAAAAAAAAAAAAAAcDBP/EABkRAAIDAQAAAAAAAAAAAAAAAAASAQJREf/aAAwDAQACEQMRAD8A6Ps+kcVQ9eTwTgAPbZFZp0yV7Irrscjchfh//9k="); 6 | 7 | .pagination-button, .pagination-button-disabled, .separator { 8 | border: 1px solid transparent; 9 | } 10 | 11 | .separator { 12 | border-right: 1px solid #000; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | utils: require("./src/scripts/utils").default, 5 | raise: require("./src/scripts/raise").default, 6 | $: require("./src/scripts/dom").default, 7 | events: require("./src/scripts/components/events").default, 8 | array: require("./src/scripts/components/array").default, 9 | date: require("./src/scripts/components/date").default, 10 | number: require("./src/scripts/components/number").default, 11 | string: require("./src/scripts/components/string").default, 12 | regex: require("./src/scripts/components/regex").default, 13 | ajax: require("./src/scripts/data/ajax").default, 14 | json: require("./src/scripts/data/json").default, 15 | lru: require("./src/scripts/data/lru").default, 16 | xml: require("./src/scripts/data/xml").default, 17 | csv: require("./src/scripts/data/csv").default, 18 | html: require("./src/scripts/data/html") 19 | }; -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/clear/pagination-bars.less: -------------------------------------------------------------------------------- 1 | .theme-clear { 2 | .pagination-bar { 3 | background-repeat: repeat-x; 4 | background-position: top left; 5 | background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAGRABAAIDAAAAAAAAAAAAAAAAAAETERJh/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/ANV2CXcBJZ0S5kB//9k="); 6 | border: 1px solid #ccc; 7 | border-top: 1px solid white; 8 | .pagination-button, .pagination-button-disabled, .separator { 9 | border: 1px solid transparent; 10 | } 11 | 12 | .separator { 13 | border-right: 1px solid #848484; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/olive/pagination-bars.less: -------------------------------------------------------------------------------- 1 | .theme-olive { 2 | .pagination-bar { 3 | background-repeat: repeat-x; 4 | background-position: top left; 5 | background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAUECP/EAB0QAQABAwUAAAAAAAAAAAAAAAABAhNhAxQVU5H/xAAXAQADAQAAAAAAAAAAAAAAAAACAwYH/8QAGBEBAAMBAAAAAAAAAAAAAAAAABESFWH/2gAMAwEAAhEDEQA/AOlr+RE5DS7J8kY5s9Mqz7fAqW6ROQJ//9k="); 6 | border: 1px solid #455b1b; 7 | 8 | .pagination-button, .pagination-button-disabled, .separator { 9 | border: 1px solid transparent; 10 | } 11 | 12 | .separator { 13 | border-right: 1px solid #455b1b; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/ultramarine/pagination-bars.less: -------------------------------------------------------------------------------- 1 | .theme-ultramarine { 2 | .pagination-bar { 3 | background-repeat: repeat-x; 4 | background-position: top left; 5 | background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAcEAEAAQQDAAAAAAAAAAAAAAAAAgEUFWFRYqH/xAAWAQEBAQAAAAAAAAAAAAAAAAAGAAT/xAAVEQEBAAAAAAAAAAAAAAAAAAAAEv/aAAwDAQACEQMRAD8AscjHkSmR7eh+D2kL+uxKXs9iZbf/2Q=="); 6 | border: 1px solid #1e2d9e; 7 | 8 | .pagination-button, .pagination-button-disabled, .separator { 9 | border: 1px solid transparent; 10 | } 11 | 12 | .separator { 13 | border-right: 1px solid #071436; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /servers/flask/templates/scores-fixed.html: -------------------------------------------------------------------------------- 1 | {%- extends "layout.html" -%} 2 | {%- block title -%} 3 | KingTable - latest scores demo 4 | {%- endblock -%} 5 | {%- block body -%} 6 | {% include "partials/controls.html" %} 7 |

 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   
11 |   
27 |   
28 | {%- endblock -%}
29 | 


--------------------------------------------------------------------------------
/servers/flask/templates/html-scores-fixed.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable - latest scores demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 |   {% include "partials/controls.html" %}
 7 |   

 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   
11 |   
27 |   
28 | {%- endblock -%}
29 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | # Logs
 2 | logs
 3 | *.log
 4 | npm-debug.log*
 5 | 
 6 | # Runtime data
 7 | pids
 8 | *.pid
 9 | *.seed
10 | 
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 | 
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 | 
17 | # nyc test coverage
18 | .nyc_output
19 | 
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 | 
23 | # node-waf configuration
24 | .lock-wscript
25 | 
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 | 
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 | 
33 | # Optional npm cache directory
34 | .npm
35 | 
36 | # Optional REPL history
37 | .node_repl_history
38 | 
39 | **/env/*
40 | **/__pycache__/*
41 | httpdocs/*
42 | .vscode/*
43 | demos/*
44 | /source/copy_to_demo.sh
45 | 
46 | /servers/flask/.vscode*
47 | /servers/flask/.idea*
48 | 
49 | *.tgz
50 | 
51 | src


--------------------------------------------------------------------------------
/servers/flask/tests/server_test.py:
--------------------------------------------------------------------------------
 1 | import server
 2 | import unittest
 3 | from flask import json
 4 | 
 5 | 
 6 | 
 7 | class ServerTestCase(unittest.TestCase):
 8 |     """
 9 |       Generic server tests.
10 |     """
11 |     def setUp(self):
12 |         """
13 |           The code in the setUp() method is called before each individual test function is run.
14 |         """
15 |         self.app = server.app.test_client()
16 | 
17 |     def tearDown(self):
18 |         """
19 |           The code in the setUp() method is called before each individual test function is run.
20 |         """
21 |         #print("end..")
22 | 
23 |     def test_homepage(self):
24 |         rv = self.app.get('/')
25 |         assert b'' in rv.data
26 | 
27 |     def test_api(self):
28 |         rv = self.app.get('/api/colors?page=1&search=%&size=30×tamp=2017-07-06T17%3A54%3A17.653Z')
29 |         data = json.loads(rv.data)
30 |         assert data["total"] == 1247
31 | 


--------------------------------------------------------------------------------
/source/testdata/example-controls.js:
--------------------------------------------------------------------------------
 1 | (function () {
 2 |     
 3 |   var events = {
 4 |     "click next": function () {
 5 |       table.pagination.next();
 6 |     },
 7 |     "click prev": function () {
 8 |       table.pagination.prev();
 9 |     },
10 |     "click first": function () {
11 |       table.pagination.first();
12 |     },
13 |     "click last": function () {
14 |       table.pagination.last();
15 |     },
16 |     "click refresh": function () {
17 |       table.refresh();
18 |     },
19 |     "change page": function () {
20 |       table.pagination.page = parseInt(document.getElementById("page").value);
21 |     },
22 |     "change search": function () {
23 |       var v = document.getElementById("search").value;
24 |       table.search(v);
25 |     }
26 |   };
27 |   var x, a;
28 |   for (x in events) {
29 |     var a = x.split(/\s/);
30 |     document.getElementById(a[1]).addEventListener(a[0], events[x], true);
31 |   }
32 |     
33 | })();
34 | 


--------------------------------------------------------------------------------
/source/code/scripts/components/number.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Number utilities.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | 
12 | export default {
13 |   format: function (v, options) {
14 |     if (!options) options = {};
15 |     //return v.toString();
16 |     //
17 |     // TODO: if available, use the Intl.NumberFormat class!!
18 |     // if not, ask for a Polyfill! But in console.info.
19 |     // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
20 |     if (typeof Intl !== "undefined") {
21 |       return Intl.NumberFormat(options.locale || "en-GB").format(v);
22 |     }
23 |     return (v || "").toString();
24 |     //
25 |     // console.log(new Intl.NumberFormat('pl', { minimumFractionDigits: 2 }).format(123123.000));
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/source/code/scripts/data/memstore.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Memory storage. Allows to replace use of localStorage and sessionStorage
 3 |  * with an in-memory storage that implements the same interface.
 4 |  * https://github.com/RobertoPrevato/KingTable
 5 |  *
 6 |  * Copyright 2018, Roberto Prevato
 7 |  * https://robertoprevato.github.io
 8 |  *
 9 |  * Licensed under the MIT license:
10 |  * http://www.opensource.org/licenses/MIT
11 |  */
12 | 
13 | const CACHE = {};
14 | 
15 | export default {
16 | 
17 |   items() {
18 |     return CACHE;
19 |   },
20 | 
21 |   length() {
22 |     var x, i = 0;
23 |     for (x in CACHE) { i++; }
24 |     return i;
25 |   },
26 | 
27 |   getItem(name) {
28 |     return CACHE[name];
29 |   },
30 | 
31 |   setItem(name, value) {
32 |     CACHE[name] = value;
33 |   },
34 | 
35 |   removeItem(name) {
36 |     delete CACHE[name];
37 |   },
38 | 
39 |   clear() {
40 |     var x;
41 |     for (x in CACHE) {
42 |       delete CACHE[x];
43 |     }
44 |   }
45 | }
46 | 


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "kingtable",
 3 |   "description": "Library for administrative tables that are able to build themselves, on the basis of the input data.",
 4 |   "version": "2.0.0",
 5 |   "homepage": "https://github.com/RobertoPrevato/KingTable",
 6 |   "main": "./kingtable-entry.js",
 7 |   "files": [
 8 |     "kingtable-entry.js",
 9 |     "utils.js",
10 |     "src"
11 |   ],
12 |   "author": {
13 |     "name": "Roberto Prevato",
14 |     "email": "roberto.prevato@gmail.com",
15 |     "url": "https://robertoprevato.github.io"
16 |   },
17 |   "repository": {
18 |     "type": "git",
19 |     "url": "https://github.com/RobertoPrevato/KingTable"
20 |   },
21 |   "bugs": {
22 |     "url": "https://github.com/RobertoPrevato/KingTable/issues"
23 |   },
24 |   "licenses": [
25 |     {
26 |       "type": "MIT",
27 |       "url": "https://github.com/RobertoPrevato/KingTable/blob/master/LICENSE"
28 |     }
29 |   ],
30 |   "keywords": [
31 |     "admin tables kingtable"
32 |   ]
33 | }


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/ultramarine/search.less:
--------------------------------------------------------------------------------
1 | .theme-ultramarine {
2 |   .kt-search-highlight {
3 |     background-color: #630404;
4 |   }
5 | 
6 |   .search-field {
7 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcaByk3FkTi2wAAAcdJREFUKM+lkzFoE2EUx//fd/FyXi8lV47LlQSqklinJu7S3KQVUZfgmBgQOyjoqouTdBKEunUpbQfBQYUiDoK6iItVcak2BStUUjHGeg1eSu7+DhoJbQ+1vunj/3g/3vt/7wH/GWKrYJi5YhAql4NQKZAiGVM6TxQZ3NxoLj39I8Awc5V2aE9L1YKQewFIMGwh3PyMGBrT39cXq5GtGGauqJou9XTVK4zdnSDpknRPnnt+SU9Xvbh1goaZOx0JSNij85pTZv7o7eskna5OMnms8uyi5pSpW8U3kYC+wTOrmlNmb3EvJLn/wpJml7g1J7uPEGo/AAgh6tuMEuIrg1YIqSMSkOhPvex6sW08M5tv+xsHVTVejwQMZobvAMAm7fu9kMRAdqiDgRlIHVbqwHzkN5K0MiPXZhufamOBvwLJ5qufo/UVFG0IkDrQWfu2J1ge9Zq11zvuAclDh4/fq7x/+6jkt9ayAKBqZt1Ojzz8+GGhFHbaRugvr8dlo9iFiB0cdwBkABi/JB9Affzqgjs3c2vyN0Rp5L0vtZW/3nmSxvkrL87q6aqX3Df+7sipqdQ/Hw5J48bUYunB41WXZGxX10dS6y3+AfpUvSB00xFiAAAAAElFTkSuQmCC");
8 |   }
9 | }


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/clear/search.less:
--------------------------------------------------------------------------------
1 | .theme-clear {
2 |   .kt-search-highlight {
3 |     background-color: yellow;
4 |   }
5 |   
6 |   .search-field {
7 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==");
8 |   }
9 | }


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/dark/search.less:
--------------------------------------------------------------------------------
1 | .theme-dark {
2 |   .kt-search-highlight {
3 |     background-color: #832525;
4 |   }
5 |   
6 |   .search-field {
7 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==");
8 |   }
9 | }


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/flatblack/search.less:
--------------------------------------------------------------------------------
1 | .theme-flatblack {
2 |   .kt-search-highlight {
3 |     background-color: #791919;
4 |   }
5 |   
6 |   .search-field {
7 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==");
8 |   }
9 | }


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/flatwhite/search.less:
--------------------------------------------------------------------------------
1 | .theme-flatwhite {
2 |   .kt-search-highlight {
3 |     background-color: yellow;
4 |   }
5 |   
6 |   .search-field {
7 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==");
8 |   }
9 | }


--------------------------------------------------------------------------------
/servers/flask/templates/colors-fixed.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable colors demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 |   {% include "partials/controls.html" %}
 7 |   <pre id="main"></pre>
 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   <script src="scripts/colors.js"></script>
11 |   <script>
12 |   (function () {
13 |     /*
14 |     sort example:
15 |     -- table.sortBy({"hsvValue": "asc", "color": "asc"});
16 |     */
17 |     var table = window.table = new KingTable({
18 |       data: COLORS,
19 |       caption: "KingTable - colors demo with client side pagination (whole collection in memory, immediately available).",
20 |       element: document.getElementById("main"),
21 |       builder: "text"
22 |     });
23 | 
24 |     table.render().then(function () {
25 |       console.log("ok :)");
26 |     }, function () {
27 |       console.log("noo :(");
28 |     });
29 |   })();
30 |   </script>
31 |   <script src="scripts/example-controls.js"></script>
32 | {%- endblock -%}
33 | 


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/midnight/search.less:
--------------------------------------------------------------------------------
1 | .theme-midnight {
2 |   .kt-search-highlight {
3 |     background-color: rgb(58, 58, 228);
4 |   }
5 | 
6 |   .search-field {
7 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEDE7ljUssgAAAeNJREFUKM+lk81PE1EUxc+b99op40SKfHQIJkZDAU0DmGg1fsFCie5YdEnSEP8BWGgM6A5M40LUrlFUdm4gcWHAhZgIbtS6IsRGQ0LjzCSUEZqinY/rQoY0xUaNd3Vz8u7v5p13HvCfxSqFvtSdHrWlZUgOh7t5MBgumuarQi53b+7G9YU/Aq5M3E9GTp6YQlAGBP8lOi5Q+gHrU3ZqZjA5WAng5Zubz56Z8UKhAj9Qd/fhsaO3+pu1x4tCZArb2+dq6hviWnt7Jjs/t1IOEH5T2xa9BkWBUGoeTB45nGaM6QBARJlhItcyjHRdLDYGYLYcIPlNSNOOA8BkNLo7DACMMWtCi0w7tp2Vm5pilVfYBbBAYP/OgL7HKMYs2LYHzlEV4HreB9+LykOXxm93CVlucx1HrwoQsvwMACLx+Gw55OLY+KH6zs4n4BwEPK/6jETUMPDu/dOAJF1GsYiiYWYAQGls7MY+BeAc7lZhU3+9cGF+dOTjb3NARB1XP39JlvL5hJCkVgBwiXQWlF/ALiUkxlRnw/pmvF3q8SF7kkhEGoCDANQd6TsAPWWavctrubQP0ZcWu17eHF1lf5t5IlJTpplYXsulPcf5GiA6/+j0KeOfPg4RqdPr+cSbza1eIhIA8BOAQ7mCZoIs4QAAAABJRU5ErkJggg==");
8 |   }
9 | }


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/bronze/search.less:
--------------------------------------------------------------------------------
 1 | .theme-bronze {
 2 |   .kt-search-highlight {
 3 |     background-color: yellow;
 4 |   }
 5 | 
 6 |   .king-table-gallery {
 7 |     .kt-search-highlight {
 8 |       background-color: #000;
 9 |     }
10 |   }
11 |   
12 |   .search-field {
13 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcaBygLIDCvHQAAAdFJREFUKM+lk81rE1EUxc/LTCbjZGJTCZkqhZSSaMHgxEVdSTMrFUTcBJepEWkWCvoPSHEhrgSx7kQo2kWhSCsU6aIL3YgI1oqbYlOwi5aMGGw7qWnSZI4bI0Pawa+3epx37+8+zr0X+M8jOoWUoWcltm5KaGUEGG1CftkS0v1lu/rqt4CUoQ/Hg/XxmBbAAVkgIIDtXeLrdxeVhjy+9KVW8P1KytCzVkJhwdSc6ZHMXZIWSevN7Qs3CqbmnE+GmDL0i76Aof7IbD6tcvKKeYdkT1snGX196+z1fFpltk/76Au4dDy8lk+r9CZ7IddORZdzAyo73wLtiyLcgwAghCjvMUqIje1dupq8t/AvgNEded/2ojMoaUTMaq1+NBRSyr6AY4nDUwAQVxrPvZCkEUkcCjafaDLQfyQ269tGkrHRM71PS+uVc6ubLXxrBBYBICy5mUSXBE0G7Bq2VqrBoZLtfNh3DkgOzBRPDs8vfs7ZWztJAOgOK+UTffG5hdJ6rt509ZUNd7PSDGXbELGP4z0AegHoP6UdAOWFsaL18PHEmAdilmxn9Y9nnqT+7sHI5YKpOcXB6KdHV08bf704JPWlZ/dya29fWCTlf9o+kqo3+Qdpar4Yro3HOgAAAABJRU5ErkJggg==");
14 |   }
15 | }


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/olive/search.less:
--------------------------------------------------------------------------------
 1 | .theme-olive {
 2 |   .kt-search-highlight {
 3 |     background-color: yellow;
 4 |   }
 5 | 
 6 |   .king-table-gallery {
 7 |     .kt-search-highlight {
 8 |       background-color: #792323;
 9 |     }
10 |   }
11 | 
12 |   .search-field {
13 |     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcaBygLIDCvHQAAAdFJREFUKM+lk81rE1EUxc/LTCbjZGJTCZkqhZSSaMHgxEVdSTMrFUTcBJepEWkWCvoPSHEhrgSx7kQo2kWhSCsU6aIL3YgI1oqbYlOwi5aMGGw7qWnSZI4bI0Pawa+3epx37+8+zr0X+M8jOoWUoWcltm5KaGUEGG1CftkS0v1lu/rqt4CUoQ/Hg/XxmBbAAVkgIIDtXeLrdxeVhjy+9KVW8P1KytCzVkJhwdSc6ZHMXZIWSevN7Qs3CqbmnE+GmDL0i76Aof7IbD6tcvKKeYdkT1snGX196+z1fFpltk/76Au4dDy8lk+r9CZ7IddORZdzAyo73wLtiyLcgwAghCjvMUqIje1dupq8t/AvgNEded/2ojMoaUTMaq1+NBRSyr6AY4nDUwAQVxrPvZCkEUkcCjafaDLQfyQ269tGkrHRM71PS+uVc6ubLXxrBBYBICy5mUSXBE0G7Bq2VqrBoZLtfNh3DkgOzBRPDs8vfs7ZWztJAOgOK+UTffG5hdJ6rt509ZUNd7PSDGXbELGP4z0AegHoP6UdAOWFsaL18PHEmAdilmxn9Y9nnqT+7sHI5YKpOcXB6KdHV08bf704JPWlZ/dya29fWCTlf9o+kqo3+Qdpar4Yro3HOgAAAABJRU5ErkJggg==");
14 |   }
15 | }


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | MIT License
 2 | 
 3 | Copyright (c) 2017 Roberto Prevato
 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 | 


--------------------------------------------------------------------------------
/source/code/scripts/data/sanitizer.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Strings sanitizer.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../../scripts/utils";
12 | 
13 | export default class Sanitizer {
14 | 
15 |   sanitize(o) {
16 |     var x;
17 |     for (x in o) {
18 |       if (_.isString(o[x])) {
19 |         o[x] = this.escape(o[x]);
20 |       } else if (_.isObject(o[x])) {
21 |         if (_.isArray(o[x])) {
22 |           for (var i = 0, l = o[x].length; i < l; i++) {
23 |             o[x][i] = this.sanitize(o[x][i]);
24 |           }
25 |         } else {
26 |           o[x] = this.sanitize(o[x]);
27 |         }
28 |       }
29 |     }
30 |     return o;
31 |   }
32 | 
33 | escapeHtml(s) {
34 |   return s
35 |     .replace(/&/g, "&")
36 |     .replace(/</g, "<")
37 |     .replace(/>/g, ">")
38 |     .replace(/"/g, """)
39 |     .replace(/'/g, "'");
40 |  }
41 | 
42 |   escape(s) {
43 |     return s ? this.escapeHtml(s) : "";
44 |   }
45 | }
46 | 


--------------------------------------------------------------------------------
/dist/styles/fonts/ICON-LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2014 Waybury
 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
13 | all 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
21 | THE SOFTWARE.


--------------------------------------------------------------------------------
/servers/flask/templates/html-colors.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable colors demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 |   {% include "partials/controls.html" %}
 7 |   <div id="main"></div>
 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   <script>
11 |   (function () {
12 |     var table = window.table = new KingTable({
13 |       url: "/api/colors",
14 |       caption: "KingTable - colors demo with server side pagination (paginated set in memory)",
15 |       element: document.getElementById("main"),
16 |       builder: "html",
17 |       columns: {
18 |         "color": {
19 |           name: "Color",
20 |           html: function (item, value) {
21 |             return "<span class=\"kt-color\" style=\"background-color:" + value + "\"></span><span class=\"kt-color-hex\">" + this.highlight(value) + "</span>";
22 |           }
23 |         }
24 |       }
25 |     });
26 | 
27 |     table.render().then(function () {
28 |       console.log("ok :)");
29 |     }, function () {
30 |       console.log("noo :(");
31 |     });
32 |   })();
33 |   </script>
34 |   <script src="scripts/example-controls.js"></script>
35 | {%- endblock -%}
36 | 


--------------------------------------------------------------------------------
/source/code/styles/openicon/ICON-LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2014 Waybury
 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
13 | all 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
21 | THE SOFTWARE.


--------------------------------------------------------------------------------
/servers/flask/templates/colors-fixed-delay.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable - colors demo with client side pagination (whole collection in memory, obtained after delay)
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 |   {% include "partials/controls.html" %}
 7 |   <pre id="main"></pre>
 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   <script src="scripts/colors.js"></script>
11 |   <script>
12 |   (function () {
13 |     var table = window.table = new KingTable({
14 |       caption: "KingTable - colors demo with client side pagination (whole collection in memory, obtained after delay)",
15 |       element: document.getElementById("main"),
16 |       builder: "text"
17 |     }, {
18 |       getFetchPromise: function (params) {
19 |         return new Promise(function (resolve, reject) {
20 |           setTimeout(function () {
21 |             resolve(COLORS);
22 |           }, 5000);
23 |         });
24 |       }
25 |     });
26 | 
27 |     table.render().then(function () {
28 |       console.log("ok :)");
29 |     }, function () {
30 |       console.log("noo :(");
31 |     });
32 |   })();
33 |   </script>
34 |   <script src="scripts/example-controls.js"></script>
35 | {%- endblock -%}
36 | 


--------------------------------------------------------------------------------
/snippets/php-mysql/README.md:
--------------------------------------------------------------------------------
 1 | Example of PHP MySQL integration with KingTable library.
 2 | 
 3 | ## Credits
 4 | This example was kindly prepared by GitHub user [ad2sound](https://github.com/hadiarakos).
 5 | 
 6 | ## Steps.
 7 | 
 8 | 1. Create a database and run users.sql (This will create `kt_users` table with dummy data.)
 9 | 2. Open `config.php` and fill up the constants
10 | 
11 |     For example: 
12 | 
13 |     define("SERVER", "localhost");
14 |     define("USERNAME", "root");
15 |     define("PASSWORD", "12345");
16 |     define("DB_NAME", "myDB");
17 |     ///////////////////////////////////////////////
18 | 
19 | 3. Define the table that you want to populate (Not need for the demo its already assigned)
20 |     For example:
21 | 
22 |     define("DB_TABLE", "kt_users");
23 |     ///////////////////////////////////////////////
24 | 
25 | 4. Define database columns that you want to include in table.
26 |     For example:
27 | 
28 |     define(
29 |         "COLUMNS",
30 |         array(
31 |             "id",
32 |             "first_name",
33 |             "last_name",
34 |             "email",
35 |             "gender",
36 |             "ip_address"
37 |         )
38 |     );
39 |     ///////////////////////////////////////////////


--------------------------------------------------------------------------------
/source/karma.conf.js:
--------------------------------------------------------------------------------
 1 | const istanbul = require("browserify-istanbul");
 2 | const isparta = require("isparta");
 3 | 
 4 | module.exports = config => {
 5 |   config.set({
 6 | 
 7 |     basePath: "./",
 8 | 
 9 |     singleRun: true,
10 | 
11 |     frameworks: ["jasmine", "browserify", "intl-shim"],
12 | 
13 |     preprocessors: {
14 |       "code/scripts/*.js": ["browserify"],
15 |       "code/tests/*.spec.js": ["browserify"],
16 |       "code/scripts/**/*.js": ["browserify"],
17 |       "code/tests/**/*.spec.js": ["browserify"]
18 |     },
19 | 
20 |     browsers: ["PhantomJS"],
21 | 
22 |     reporters: ["progress", "coverage"],
23 | 
24 |     autoWatch: true,
25 | 
26 |     browserify: {
27 |       debug: true,
28 |       extensions: [".js"],
29 |       transform: [
30 |         "babelify",
31 |         istanbul({
32 |           instrumenter: isparta,
33 |           ignore: ["**/node_modules/**", "**/test/**"]
34 |         })
35 |       ]
36 |     },
37 | 
38 |     urlRoot: "/__karma__/",
39 | 
40 |     files: [
41 |       "node_modules/babel-polyfill/dist/polyfill.js",
42 |       "node_modules/intl/locale-data/jsonp/en-GB.js",
43 |       "code/scripts/*.js",
44 |       "code/tests/*.spec.js",
45 |       "code/scripts/**/*.js"
46 |     ],
47 | 
48 |     exclude: []
49 | 
50 |   });
51 | };
52 | 


--------------------------------------------------------------------------------
/servers/flask/templates/rhtml-people-fixed.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable people demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 | {% include "partials/themes.html" %}
 7 | <div id="main"></div>
 8 | {%- endblock -%}
 9 | {%- block js -%}
10 | <script src="scripts/people.js"></script>
11 | <style>
12 |   .king-table { white-space: nowrap; }
13 | </style>
14 | <script>
15 | (function () {
16 |   var table = window.table = new KingTable({
17 |     id: "people-table",
18 |     data: PEOPLE,
19 |     caption: "KingTable - people demo with client side pagination (whole collection in memory)",
20 |     element: document.getElementById("main"),
21 |     sortBy: "name, birthdate desc", // example sort by option (multiple properties)
22 |     columns: {
23 |       name: "Name",
24 |       email: "Email",
25 |       phone: "Phone",
26 |       birthdate: {
27 |         name: "Birthdate"
28 |       },
29 |       isActive: {
30 |         name: "Active",
31 |         hidden: 1
32 |       },
33 |       _id: {
34 |         secret: true
35 |       },
36 |       address: "Address",
37 |       company: "Company",
38 |       gender: "Gender",
39 |       registered: "Registered"
40 |     }
41 |   });
42 | 
43 |   table.render();
44 | })();
45 | </script>
46 | {%- endblock -%}
47 | 


--------------------------------------------------------------------------------
/source/karma-chrome.conf.js:
--------------------------------------------------------------------------------
 1 | module.exports = config => {
 2 |   config.set({
 3 | 
 4 |     basePath: "./",
 5 | 
 6 |     singleRun: false,
 7 | 
 8 |     frameworks: ["jasmine", "browserify", "intl-shim"],
 9 | 
10 |     preprocessors: {
11 |       "code/scripts/*.js": ["browserify"],
12 |       "code/tests/*.spec.js": ["browserify"],
13 |       "code/scripts/**/*.js": ["browserify"],
14 |       "code/tests/**/*.spec.js": ["browserify"]
15 |     },
16 | 
17 |     browsers: ["ChromeDebugging"],
18 | 
19 |     reporters: ["progress", "coverage"],
20 | 
21 |     autoWatch: true,
22 | 
23 |     customLaunchers: {
24 |       ChromeDebugging: {
25 |         base: 'Chrome',
26 |         flags: [ '--remote-debugging-port=9333' ]
27 |       }
28 |     },
29 | 
30 |     browserify: {
31 |       debug: true,
32 |       extensions: [".js"],
33 |       transform: [
34 |         "babelify"
35 |       ]
36 |     },
37 | 
38 |     urlRoot: "/__karma__/",
39 | 
40 |     files: [
41 |       "node_modules/babel-polyfill/dist/polyfill.js",
42 |       "node_modules/intl/locale-data/jsonp/en-GB.js",
43 |       "code/scripts/*.js",
44 |       "code/tests/*.spec.js",
45 |       "code/tests/**/*.spec.js",
46 |       "code/scripts/**/*.js",
47 |       "code/styles/dataentry.css",
48 |       "tests/tests.css"
49 |     ],
50 | 
51 |     exclude: []
52 | 
53 |   });
54 | };
55 | 


--------------------------------------------------------------------------------
/servers/flask/templates/html-colors-fixed.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable colors demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 |   {% include "partials/controls.html" %}
 7 |   <div id="main"></div>
 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   <script src="scripts/colors.js"></script>
11 |   <script>
12 |   (function () {
13 |     /*
14 |     sort example:
15 |     -- table.sortBy({"hsvValue": "asc", "color": "asc"});
16 |     */
17 |     var table = window.table = new KingTable({
18 |       data: COLORS,
19 |       caption: "KingTable - colors demo with client side pagination (whole collection in memory, immediately available).",
20 |       element: document.getElementById("main"),
21 |       columns: {
22 |         "color": {
23 |           name: "Color",
24 |           html: function (item, value) {
25 |             return "<span class=\"kt-color\" style=\"background-color:" + value + "\"></span><span class=\"kt-color-hex\">" + this.highlight(value) + "</span>";
26 |           }
27 |         }
28 |       },
29 |       builder: "html"
30 |     });
31 | 
32 |     table.render().then(function () {
33 |       console.log("ok :)");
34 |     }, function () {
35 |       console.log("noo :(");
36 |     });
37 |   })();
38 |   </script>
39 |   <script src="scripts/example-controls.js"></script>
40 | {%- endblock -%}
41 | 


--------------------------------------------------------------------------------
/dist/README.md:
--------------------------------------------------------------------------------
 1 | This folder contains distribution files.
 2 | 
 3 | ## JS
 4 | The file `kingtable.js` is minified and transpiled from ES6 source code, it can be included in projects in classic way (i.e. downloading it and loading it using a script tag). To work with ES6 source code, look at [https://github.com/RobertoPrevato/KingTable/tree/master/source/gulp](https://github.com/RobertoPrevato/KingTable/tree/master/source/gulp).
 5 | 
 6 | ## CSS
 7 | CSS files are organized inside the `styles` folder.
 8 | 
 9 | The file `kingtable.css` contains all themes. It is recommended to optimize your solution, by using the file: `kingtable.core.css`, which includes only the basic "flatwhite" theme; and eventually add the specific `.css` files of the desired themes.
10 | 
11 | ## Open Iconic
12 | Open Iconic fonts ([GitHub page](https://github.com/iconic/open-iconic)) are a dependency of KingTable styles. The folder `fonts` contains a copy of the font, used for the published demos. CSS rules for the fonts are already included inside kingtable .css files.
13 | 
14 | ## KingTable plugins
15 | This folder also contains optional plugins. Refer to [dedicated wiki page for detailed information](https://github.com/RobertoPrevato/KingTable/wiki/Plugins).
16 | 
17 | | File | Description |
18 | |---------|-------------|
19 | | kingtable.xlsx.js | Plugin to support client side export in Excel (xlsx) files. |
20 | 


--------------------------------------------------------------------------------
/servers/flask/templates/rhtml-colors.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable colors demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 |   {% include "partials/themes.html" %}
 7 |   <div id="main"></div>
 8 | {%- endblock -%}
 9 | {%- block js -%}
10 |   <script>
11 |   (function () {
12 |     var table = window.table = new KingTable({
13 |       id: "colors-table",
14 |       url: "/api/colors",
15 |       caption: "KingTable - colors demo with server side pagination (paginated set in memory)",
16 |       element: document.getElementById("main"),
17 |       columns: {
18 |         name: "Name",
19 |         color: {
20 |           name: "Color",
21 |           html: function (item, value) {
22 |             return "<span class=\"kt-color\" style=\"background-color:" + value + "\"></span><span class=\"kt-color-hex\">" + this.highlight(value) + "</span>";
23 |           }
24 |         },
25 |         red: "Red",
26 |         green: "Green",
27 |         blue: "Blue",
28 |         hue: "Hue",
29 |         hslLight: "Light (HSL)",
30 |         hslSaturation: "Saturation (HSL)",
31 |         hsvSaturation: "Saturation (HSV)",
32 |         hsvValue: "Value (HSV)"
33 |       }
34 |     });
35 | 
36 |     table.render().then(function () {
37 |       console.log("ok :)");
38 |     }, function () {
39 |       console.log("noo :(");
40 |     });
41 |   })();
42 |   </script>
43 | {%- endblock -%}
44 | 


--------------------------------------------------------------------------------
/source/code/scripts/data/xml.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * XML format functions.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../../scripts/utils"
12 | 
13 | export default {
14 |   normal: function (xml) {
15 |     return "<?xml version=\"1.0\"?>" + xml.replace(/\sxmlns="http:\/\/www\.w3\.org\/\d+\/xhtml"/, "");
16 |   },
17 | 
18 |   pretty: function (xml, indentation) {
19 |     xml = this.normal(xml);
20 |     if (typeof indentation != "number")
21 |       indentation = 2;
22 |     var reg = /(>)(<)(\/*)/g, a = [];
23 |     xml = xml.replace(reg, "$1\r\n$2$3");
24 |     var pad = 0, parts = xml.split('\r\n'), l = parts.length;
25 | 
26 |     for (var i = 0; i < l; i++) {
27 |       var node = parts[i];
28 |       var indent = 0;
29 |       if (node.match(/.+<\/\w[^>]*>$/)) {
30 |         indent = 0;
31 |       } else if (node.match(/^<\/\w/)) {
32 |         if (pad != 0) {
33 |           pad -= 1;
34 |         }
35 |       } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) {
36 |         indent = 1;
37 |       } else {
38 |         indent = 0;
39 |       }
40 |       var padding = new Array(pad * indentation).join(" ");
41 |       a.push(padding + node + "\r\n");
42 |       pad += indent;
43 |     }
44 |     return a.join("");
45 |   }
46 | }
47 | 


--------------------------------------------------------------------------------
/source/code/scripts/exceptions.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Proxy functions to raise exceptions.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | function isNumber(x) {
12 |   return typeof x == "number";
13 | }
14 | const NO_PARAM = "???"
15 | 
16 | function ArgumentNullException(name) {
17 |   throw new Error("The parameter cannot be null: " + (name || NO_PARAM))
18 | }
19 | 
20 | function ArgumentException(details) {
21 |   throw new Error("Invalid argument: " + (details || NO_PARAM))
22 | }
23 | 
24 | function TypeException(name, expectedType) {
25 |   throw new Error("Expected parameter: " + (name || NO_PARAM) + " of type: " + (type || NO_PARAM))
26 | }
27 | 
28 | function OperationException(desc) {
29 |   throw new Error("Invalid operation: " + desc);
30 | }
31 | 
32 | function OutOfRangeException(name, min, max) {
33 |   var message = "Out of range. Expected parameter: " + (name || NO_PARAM)
34 |   if (!isNumber(max) && min === 0) {
35 |     message = " to be positive.";
36 |   } else {
37 |     if (isNumber(min))
38 |       message = " >=" + min;
39 |     if (isNumber(max))
40 |       message = " <=" + max;
41 |   }
42 |   throw new Error(message)
43 | }
44 | 
45 | export {
46 |   ArgumentException,
47 |   ArgumentNullException,
48 |   TypeException,
49 |   OutOfRangeException,
50 |   OperationException
51 | }
52 | 


--------------------------------------------------------------------------------
/source/testdata/scores.js:
--------------------------------------------------------------------------------
 1 | var SCORES = [
 2 |   {
 3 |     "time": "2017-02-03T10:25:40.000Z",
 4 |     "player": "UnregisteredUser",
 5 |     "score": 16938
 6 |   },
 7 |   {
 8 |     "time": "2017-02-02T18:24:34.000Z",
 9 |     "player": "UnregisteredUser",
10 |     "score": 4934
11 |   },
12 |   {
13 |     "time": "2017-02-02T18:10:01.000Z",
14 |     "player": "UnregisteredUser",
15 |     "score": 10316
16 |   },
17 |   {
18 |     "time": "2017-02-02T17:57:36.000Z",
19 |     "player": "UnregisteredUser",
20 |     "score": 5346
21 |   },
22 |   {
23 |     "time": "2017-01-30T21:00:43.000Z",
24 |     "player": "EdytaMP",
25 |     "score": 4394
26 |   },
27 |   {
28 |     "time": "2017-01-30T20:55:06.000Z",
29 |     "player": "EdytaMP",
30 |     "score": 26834
31 |   },
32 |   {
33 |     "time": "2017-01-30T20:17:36.000Z",
34 |     "player": "UnregisteredUser",
35 |     "score": 5308
36 |   },
37 |   {
38 |     "time": "2017-01-30T19:04:56.000Z",
39 |     "player": "UnregisteredUser",
40 |     "score": 3004
41 |   },
42 |   {
43 |     "time": "2017-01-30T18:59:50.000Z",
44 |     "player": "UnregisteredUser",
45 |     "score": 2948
46 |   },
47 |   {
48 |     "time": "2017-01-30T18:00:42.000Z",
49 |     "player": "UnregisteredUser",
50 |     "score": 3192
51 |   },
52 |   {
53 |     "time": "2017-01-29T15:08:49.000Z",
54 |     "player": "UnregisteredUser",
55 |     "score": 18858
56 |   },
57 |   {
58 |     "time": "2017-01-28T22:50:51.000Z",
59 |     "player": "Roberto",
60 |     "score": 18994
61 |   }
62 | ];


--------------------------------------------------------------------------------
/servers/flask/templates/html-colors-fixed-delay.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable colors demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 | <p class="small">KingTable - colors demo with client side pagination (whole collection in memory, obtained after delay)</p>
 7 | {% include "partials/controls.html" %}
 8 | <div id="main"></div>
 9 | {%- endblock -%}
10 | {%- block js -%}
11 | <script src="scripts/colors.js"></script>
12 | <script>
13 | (function () {
14 |   var table = window.table = new KingTable({
15 |     caption: "KingTable - colors demo with client side pagination (whole collection in memory, obtained after delay)",
16 |     element: document.getElementById("main"),
17 |     columns: {
18 |       "color": {
19 |         name: "Color",
20 |         html: function (item, value) {
21 |           return "<span class=\"kt-color\" style=\"background-color:" + value + "\"></span><span class=\"kt-color-hex\">" + this.highlight(value) + "</span>";
22 |         }
23 |       }
24 |     },
25 |     builder: "html"
26 |   }, {
27 |     getFetchPromise: function (params) {
28 |       return new Promise(function (resolve, reject) {
29 |         setTimeout(function () {
30 |           resolve(COLORS);
31 |         }, 5000);
32 |       });
33 |     }
34 |   });
35 | 
36 |   table.render().then(function () {
37 |     console.log("ok :)");
38 |   }, function () {
39 |     console.log("noo :(");
40 |   });
41 | })();
42 | </script>
43 | <script src="scripts/example-controls.js"></script>
44 | {%- endblock -%}
45 | 


--------------------------------------------------------------------------------
/source/code/tests/ajax.spec.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Tests for AJAX utilities.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../scripts/utils";
12 | import ajax from "../scripts/data/ajax";
13 | 
14 | describe("AJAX utilities", () => {
15 | 
16 |   it("must allow to produce query strings (single parameter)", () => {
17 |     var a = {
18 |       "search": "Hello"
19 |     }
20 | 
21 |     var qs = ajax.createQs(a)
22 |     expect(qs).toEqual("search=Hello")
23 |   })
24 | 
25 |   it("must allow to produce query strings (multiple parameters)", () => {
26 |     var a = {
27 |       "search": "Hello",
28 |       "page": 1,
29 |       "size": 30
30 |     }
31 | 
32 |     var qs = ajax.createQs(a)
33 |     expect(qs).toEqual("page=1&search=Hello&size=30")
34 |   })
35 | 
36 |   it("must allow to produce query strings, ignoring null values (multiple parameters)", () => {
37 |     var a = {
38 |       "search": null,
39 |       "page": 1,
40 |       "size": 30,
41 |       "moo": undefined,
42 |       "foo": ""
43 |     }
44 | 
45 |     var qs = ajax.createQs(a)
46 |     expect(qs).toEqual("page=1&size=30")
47 |   })
48 | 
49 |   it("must allow to produce query strings, handling null and undefined values", () => {
50 |     expect(ajax.createQs(null)).toEqual("", "null must produce an empty query string")
51 | 
52 |     expect(ajax.createQs(undefined)).toEqual("", "undefined must produce an empty query string")
53 |   })
54 | })
55 | 


--------------------------------------------------------------------------------
/source/code/tests/regex.spec.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Tests for RegExp utilities.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../scripts/utils";
12 | import R from "../scripts/components/regex";
13 | 
14 | describe("Regex utilities", () => {
15 |   it("must prepare strings for RegExp", () => {
16 | 
17 |     expect(R.escapeCharsForRegex("Hello.World?")).toEqual("Hello\\.World\\?", "dots and question marks must be escaped")
18 |     expect(R.escapeCharsForRegex("(Hello World)")).toEqual("\\(Hello\\sWorld\\)", "parentheses must be escaped")
19 |     expect(R.escapeCharsForRegex("[Hello World]")).toEqual("\\[Hello\\sWorld\\]", "square brackets must be escaped")
20 |     expect(R.escapeCharsForRegex("{Hello World}")).toEqual("\\{Hello\\sWorld\\}", "curly braces must be escaped")
21 |     expect(R.escapeCharsForRegex("Hello World*")).toEqual("Hello\\sWorld\\*", "stars must be escaped")
22 |     expect(R.escapeCharsForRegex("Hello^ World$")).toEqual("Hello\\^\\sWorld\\$", "^ and $ must be escaped")
23 |   });
24 | 
25 |   it("must allow to obtain regex from multiple words", () => {
26 | 
27 |     var a = R.getPatternFromStrings(["Hello", "World", "Kitty"])
28 |     expect(a instanceof RegExp).toEqual(true, "return object must be a regex")
29 |     expect(a.source).toEqual("(Hello|World|Kitty)", "words must be alternatives")
30 |     expect(a.flags).toEqual("gim", "pattern must be global, case insensitive and multiline")
31 |   });
32 | });
33 | 


--------------------------------------------------------------------------------
/servers/flask/templates/rhtml-colors-fixed-delay.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable colors demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 | {% include "partials/themes.html" %}
 7 | <div id="main"></div>
 8 | {%- endblock -%}
 9 | {%- block js -%}
10 | <script src="scripts/colors.js"></script>
11 | <script>
12 | (function () {
13 |   var table = window.table = new KingTable({
14 |     id: "colors-table",
15 |     caption: "KingTable - colors demo with client side pagination (whole collection in memory, obtained after delay)",
16 |     element: document.getElementById("main"),
17 |     columns: {
18 |       name: "Name",
19 |       color: {
20 |         name: "Color",
21 |         html: function (item, value) {
22 |           return "<span class=\"kt-color\" style=\"background-color:" + value + "\"></span><span class=\"kt-color-hex\">" + this.highlight(value) + "</span>";
23 |         }
24 |       },
25 |       red: "Red",
26 |       green: "Green",
27 |       blue: "Blue",
28 |       hue: "Hue",
29 |       hslLight: "Light (HSL)",
30 |       hslSaturation: "Saturation (HSL)",
31 |       hsvSaturation: "Saturation (HSV)",
32 |       hsvValue: "Value (HSV)"
33 |     },
34 |   }, {
35 |     getFetchPromise: function (params) {
36 |       return new Promise(function (resolve, reject) {
37 |         setTimeout(function () {
38 |           resolve(COLORS);
39 |         }, 2000);
40 |       });
41 |     }
42 |   });
43 | 
44 |   table.render().then(function () {
45 |     console.log("ok :)");
46 |   }, function () {
47 |     console.log("noo :(");
48 |   });
49 | })();
50 | </script>
51 | {%- endblock -%}
52 | 


--------------------------------------------------------------------------------
/source/code/scripts/tables/kingtable.regional.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * KingTable default regional object.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | 
12 | export default {
13 |   "en": {
14 |     "goToDetails": "Go to details",
15 |     "sortOptions": "Sort options",
16 |     "searchSortingRules": "When searching, sort by relevance",
17 |     "advancedFilters": "Advanced filters",
18 |     "sortModes": {
19 |       "simple": "Simple (single property)",
20 |       "complex": "Complex (multiple properties)"
21 |     },
22 |     "viewsType": {
23 |       "table": "Table",
24 |       "gallery": "Gallery"
25 |     },
26 |     "exportFormats": {
27 |       "csv": "Csv",
28 |       "json": "Json",
29 |       "xml": "Xml"
30 |     },
31 |     "columns": "Columns",
32 |     "export": "Export",
33 |     "view": "View",
34 |     "views": "Views",
35 |     "loading": "Loading",
36 |     "noData": "No data to display",
37 |     "page": "Page",
38 |     "resultsPerPage": "Results per page",
39 |     "results": "Results",
40 |     "of": "of",
41 |     "firstPage": "First page",
42 |     "lastPage": "Last page",
43 |     "prevPage": "Previous page",
44 |     "nextPage": "Next page",
45 |     "refresh": "Refresh",
46 |     "fetchTime": "Data fetched at:",
47 |     "anchorTime": "Data at:",
48 |     "sortAscendingBy": "Sort by {{name}} ascending",
49 |     "sortDescendingBy": "Sort by {{name}} descending",
50 |     "errorFetchingData": "An error occurred while fetching data."
51 |   }
52 | }
53 | 


--------------------------------------------------------------------------------
/source/code/tests/sanitizer.spec.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Tests for Sanitizer class.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../scripts/utils";
12 | import Sanitizer from "../scripts/data/sanitizer";
13 | 
14 | const san = new Sanitizer();
15 | 
16 | 
17 | describe("Sanitizer class", () => {
18 |   it("must escape strings", () => {
19 |     var a = san.escape("<script>alert('foo');</script>");
20 |     expect(a).toEqual("<script>alert('foo');</script>");
21 |   });
22 | 
23 |   it("must escape strings inside objects", () => {
24 |     var o = {
25 |       a: {
26 |         b: "<script>alert('foo');</script>"
27 |       }
28 |     };
29 |     var a = san.sanitize(o);
30 |     expect(_.equal(o, {
31 |       a: {
32 |         b: "<script>alert('foo');</script>"
33 |       }
34 |     })).toEqual(true);
35 |   });
36 | 
37 |   it("must escape strings inside arrays", () => {
38 |     var o = {
39 |       a: {
40 |         b: "<script>alert('foo');</script>"
41 |       },
42 |       c: [
43 |         {
44 |           x: "<script>alert('foo');</script>"
45 |         }
46 |       ]
47 |     };
48 |     var a = san.sanitize(o);
49 |     expect(_.equal(o, {
50 |       a: {
51 |         b: "<script>alert('foo');</script>"
52 |       },
53 |       c: [
54 |         {
55 |           x: "<script>alert('foo');</script>"
56 |         }
57 |       ]
58 |     })).toEqual(true);
59 |   });
60 | });
61 | 


--------------------------------------------------------------------------------
/source/code/tests/mock/console.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Mocks, by monkey patching, the console object for unit tests.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | 
12 | /**
13 |  * @example
14 |    var mock = new MockConsole()
15 | 
16 |    mock.fire(() => {
17 |      console.error("foo")
18 |    })
19 | 
20 |    expect(mock.log[0]).toEqual("ERROR: foo")
21 |    // dispose the mock console
22 |    mock.dispose()
23 |  */
24 | 
25 | class MockConsole {
26 |   constructor(verbose=false) {
27 |     this.log = []
28 |     this.setup()
29 |     this.verbose = verbose;
30 |   }
31 | 
32 |   setup() {
33 |     var self = this;
34 |     var names = "log info error".split(" ");
35 |     var original = {};
36 |     for (var i = 0, l = names.length; i < l; i++) {
37 |       var name = names[i];
38 |       original[name] = console[name];
39 | 
40 |       console[name] = function (a) {
41 |         if (self.verbose) {
42 |           original[name](a);
43 |         }
44 |         self.log.push(name.toUpperCase() + ": " + a);
45 |       }
46 |     }
47 |     self.original = original;
48 |   }
49 | 
50 |   dispose() {
51 |     var original = this.original;
52 |     for (var x in original) {
53 |       console[x] = original[x];
54 |     }
55 |   }
56 | 
57 |   fire(fn, eatExceptions = true) {
58 |     // mock global console object
59 |     var self = this;
60 |     try {
61 |       fn();
62 |     } catch (ex) {
63 |       if (!eatExceptions) {
64 |         throw ex;
65 |       }
66 |     }
67 |   }
68 | }
69 | 
70 | export { MockConsole }
71 | 


--------------------------------------------------------------------------------
/servers/flask/templates/layout.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <!--
 3 | /**
 4 |  * KingTable 2.0.0
 5 |  * https://github.com/RobertoPrevato/KingTable
 6 |  *
 7 |  * Copyright 2017, Roberto Prevato
 8 |  *
 9 |  * Licensed under the MIT license:
10 |  * http://www.opensource.org/licenses/MIT
11 |  */
12 | -->
13 | <html lang="en">
14 | <head>
15 |   <!-- Force latest IE rendering engine or ChromeFrame if installed -->
16 |   <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><![endif]-->
17 |   <meta charset="utf-8">
18 |   <title>{%- block title -%}{%- endblock -%}
19 |   
20 |   
21 |   
22 |   
23 |   
24 | 
25 | 
26 |   
34 |   {%- block body -%}{%- endblock -%}
35 |   
36 | 
37 |   
38 |   
39 |   
40 | 
41 |   
42 |   
43 |   {%- block js -%}{%- endblock -%}
44 | 
45 | 
46 | 


--------------------------------------------------------------------------------
/source/code/styles/kingtable/themes/midnight/menus.less:
--------------------------------------------------------------------------------
 1 | .theme-midnight {
 2 |   .king-table-region {
 3 |     .ug-menu {
 4 |       box-shadow: 0 6px 12px #4347B3;
 5 |       background: #111;
 6 |       color: #c4feff;
 7 |       
 8 |       li {
 9 |         border-bottom: 1px solid #000;
10 |         span, a, label {
11 |           color: #c4feff;
12 |           &:focus, &:hover {
13 |             color: #c4feff;
14 |             background-color: #000;
15 |             background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAAAWCAYAAAASPXQbAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcMEw8zvKqmCQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAkklEQVRo3u3aQRLCIAxA0R/Bo3s2D1U6uMEpIsXu3Pw3wzQNIU33BMDjWTOQgNxWauve5fv9vubIBYn6sT8/F2Tqsu8qvnqun3+szcBt+L9Z7wLs7XkW97n3+06wUZf1v3rN+37n5nFQ2ve3of/YoxDsJ7PO5pAkSZIkSZIkSZIkSZIkSZL0RwFeAsdL4Jcvgb8Adb+Yn8Y8eNcAAAAASUVORK5CYII=");
16 |             background-repeat: no-repeat;
17 |             background-position: center;
18 |           }
19 |         }
20 |         
21 |         &.open {
22 |           > span, > a, > label {
23 |             background-color: #000;
24 |             background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAAAWCAYAAAASPXQbAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcMEw8zvKqmCQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAkklEQVRo3u3aQRLCIAxA0R/Bo3s2D1U6uMEpIsXu3Pw3wzQNIU33BMDjWTOQgNxWauve5fv9vubIBYn6sT8/F2Tqsu8qvnqun3+szcBt+L9Z7wLs7XkW97n3+06wUZf1v3rN+37n5nFQ2ve3of/YoxDsJ7PO5pAkSZIkSZIkSZIkSZIkSZL0RwFeAsdL4Jcvgb8Adb+Yn8Y8eNcAAAAASUVORK5CYII=");
25 |             background-repeat: no-repeat;
26 |             background-position: center;
27 |           }
28 |         }
29 |       }
30 |     }
31 |   }
32 | }


--------------------------------------------------------------------------------
/source/code/tests/data/latest-scores.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * KingTable latest scores test data.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | export default [
12 |   {
13 |     "time": "2017-02-03T10:25:40.000Z",
14 |     "player": "UnregisteredUser",
15 |     "score": 16938
16 |   },
17 |   {
18 |     "time": "2017-02-02T18:24:34.000Z",
19 |     "player": "UnregisteredUser",
20 |     "score": 4934
21 |   },
22 |   {
23 |     "time": "2017-02-02T18:10:01.000Z",
24 |     "player": "UnregisteredUser",
25 |     "score": 10316
26 |   },
27 |   {
28 |     "time": "2017-02-02T17:57:36.000Z",
29 |     "player": "UnregisteredUser",
30 |     "score": 5346
31 |   },
32 |   {
33 |     "time": "2017-01-30T21:00:43.000Z",
34 |     "player": "EdytaMP",
35 |     "score": 4394
36 |   },
37 |   {
38 |     "time": "2017-01-30T20:55:06.000Z",
39 |     "player": "EdytaMP",
40 |     "score": 26834
41 |   },
42 |   {
43 |     "time": "2017-01-30T20:17:36.000Z",
44 |     "player": "UnregisteredUser",
45 |     "score": 5308
46 |   },
47 |   {
48 |     "time": "2017-01-30T19:04:56.000Z",
49 |     "player": "UnregisteredUser",
50 |     "score": 3004
51 |   },
52 |   {
53 |     "time": "2017-01-30T18:59:50.000Z",
54 |     "player": "UnregisteredUser",
55 |     "score": 2948
56 |   },
57 |   {
58 |     "time": "2017-01-30T18:00:42.000Z",
59 |     "player": "UnregisteredUser",
60 |     "score": 3192
61 |   },
62 |   {
63 |     "time": "2017-01-29T15:08:49.000Z",
64 |     "player": "UnregisteredUser",
65 |     "score": 18858
66 |   },
67 |   {
68 |     "time": "2017-01-28T22:50:51.000Z",
69 |     "player": "Roberto",
70 |     "score": 18994
71 |   }
72 | ];


--------------------------------------------------------------------------------
/source/code/scripts/data/file.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * File utilities.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | 
12 | export default {
13 |   /**
14 |    * Returns a value indicating whether the client side export is supported
15 |    * by the client, or not.
16 |    */
17 |   supportsCsExport: function () {
18 |     return navigator.msSaveBlob || (function () {
19 |       var link = document.createElement("a");
20 |       return link.download !== undefined;
21 |     })();
22 |   },
23 | 
24 |   /**
25 |    * Exports a file; prompting the user for download.
26 |    * 
27 |    * @param filename
28 |    * @param lines
29 |    */
30 |   exportfile: function (filename, text, type) {
31 |     var setAttribute = "setAttribute", msSaveBlob = "msSaveBlob";
32 |     var blob = new Blob([text], { type: type });
33 |     if (navigator[msSaveBlob]) { // IE 10+
34 |       navigator[msSaveBlob](blob, filename);
35 |     } else {
36 |       var link = document.createElement("a");
37 |       if (link.download !== undefined) { // feature detection
38 |         // Browsers that support HTML5 download attribute
39 |         var url = URL.createObjectURL(blob);
40 |         link[setAttribute]("href", url);
41 |         link[setAttribute]("download", filename);
42 |         var style = {
43 |           visibility: "hidden",
44 |           position: "absolute",
45 |           left: "-9999px"
46 |         };
47 |         for (var x in style)
48 |           link.style[x] = style[x];
49 |         //inject
50 |         document.body.appendChild(link);
51 |         link.click();
52 |         document.body.removeChild(link);
53 |       }
54 |     }
55 |   }
56 | }


--------------------------------------------------------------------------------
/source/code/scripts/data/json.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Proxy functions for built-in JSON API.
 3 |  * Proxy functions are used, for example, to remove the asymmetry between
 4 |  * -  JSON stringify (creating string representations of dates) and
 5 |  * -  JSON parse (NOT parsing dates in ISO format - losing dates).
 6 |  *
 7 |  * Besides, I HATE the word "stringify"!!!
 8 |  *
 9 |  * https://github.com/RobertoPrevato/KingTable
10 |  *
11 |  * Copyright 2018, Roberto Prevato
12 |  * https://robertoprevato.github.io
13 |  *
14 |  * Licensed under the MIT license:
15 |  * http://www.opensource.org/licenses/MIT
16 |  */
17 | import _ from "../../scripts/utils"
18 | import D from "../../scripts/components/date"
19 | 
20 | export default {
21 |   /**
22 |    * Serializes an object into JSON format.
23 |    */
24 |   compose: function (o, indentation) {
25 |     return JSON.stringify(o, function(k, v) {
26 |       if (v === undefined) { return null; }
27 |       return v;
28 |     }, indentation);
29 |   },
30 | 
31 |   /**
32 |    * Parses an object represented in JSON format.
33 |    */
34 |   parse: function (s, options) {
35 |     var o = _.extend({
36 |       parseDates: true
37 |     }, options);
38 | 
39 |     if (!o.parseDates) {
40 |       return JSON.parse(s);
41 |     }
42 | 
43 |     return JSON.parse(s, function(k, v) {
44 |       if (_.isString(v) && D.looksLikeDate(v)) {
45 |         // check if the value looks like a date and can be parsed
46 |         var a = D.parse(v);
47 |         if (a && D.isValid(a)) {
48 |           return a;
49 |         }
50 |       }
51 |       return v;
52 |     });
53 |   },
54 | 
55 |   /**
56 |    * Clones an object using JSON.
57 |    * Unlike the normal JSON API, Dates are kept as dates;
58 |    * however, strings that looks like dates becomes dates.
59 |    */
60 |   clone: function (o) {
61 |     return this.parse(this.compose(o));
62 |   }
63 | }
64 | 


--------------------------------------------------------------------------------
/source/code/scripts/literature/text-slider.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Text slider.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../../scripts/utils"
12 | import {
13 |  ArgumentException,
14 |  ArgumentNullException
15 | } from "../../scripts/exceptions"
16 | 
17 | class TextSlider {
18 | 
19 |   constructor(text, filler) {
20 |     if (!text) ArgumentNullException("text");
21 |     this.length = text.length
22 |     this.i = 0
23 |     this.j = this.length
24 |     this.text = text
25 |     this.filler = filler || " "
26 |     this.right = true
27 |   }
28 | 
29 |   /**
30 |    * Resets this TextSlider at its initial statte.
31 |    */
32 |   reset() {
33 |     this.i = 0
34 |     this.j = this.length
35 |     this.right = true
36 |   }
37 | 
38 |   next() {
39 |    var self = this,
40 |        s = self.text,
41 |        filler = self.filler,
42 |        length = self.length,
43 |        i = self.i,
44 |        j = self.j,
45 |        right = self.right;
46 |    var a = s.substr(i, j);
47 |    var change = false;
48 |    if (right) {
49 |      if (j == 1) {
50 |        j = s.length;
51 |        i = j;
52 |        change = true;
53 |      } else {
54 |        j--;
55 |      }
56 |    } else {
57 |      if (i == 0) {
58 |        j--;
59 |        change = true;
60 |      } else {
61 |        i--;
62 |      }
63 |    }
64 | 
65 |    if (right && s.length != a.length) {
66 |      a = new Array(s.length - a.length + 1).join(filler) + a;
67 |    } else {
68 |      a = a + new Array(s.length - a.length + 1).join(filler);
69 |    }
70 |    if (change) {
71 |      right = !right;
72 |      self.right = right;
73 |    }
74 |    self.i = i;
75 |    self.j = j;
76 |    return a;
77 |   }
78 | }
79 | 
80 | export { TextSlider }
81 | 


--------------------------------------------------------------------------------
/source/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "kingtable",
 3 |   "version": "2.0.0",
 4 |   "description": "Library for administrative tables that are able to build themselves, on the basis of their input data.",
 5 |   "private": true,
 6 |   "scripts": {
 7 |     "karchrome": "karma start karma-chrome.conf.js",
 8 |     "build": "babel code --presets babel-preset-es2015 --out-dir ../src",
 9 |     "dev": "./node_modules/.bin/gulp dev",
10 |     "test": "./node_modules/.bin/gulp unit"
11 |   },
12 |   "author": "https://github.com/RobertoPrevato",
13 |   "devDependencies": {
14 |     "babel-cli": "^6.26.0",
15 |     "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
16 |     "babel-preset-env": "^1.6.1",
17 |     "babel-core": "^6.14.0",
18 |     "babel-eslint": "^6.1.2",
19 |     "babel-polyfill": "^6.22.0",
20 |     "babel-preset-es2015": "^6.14.0",
21 |     "babelify": "^7.3.0",
22 |     "browser-sync": "^2.16.0",
23 |     "browserify": "^13.1.0",
24 |     "browserify-istanbul": "^2.0.0",
25 |     "es6-promise": "^4.0.5",
26 |     "eslint-config-xo-space": "^0.15.0",
27 |     "gulp": "^3.9.1",
28 |     "gulp-cssmin": "^0.1.7",
29 |     "gulp-eslint": "^3.0.1",
30 |     "gulp-header": "^1.8.8",
31 |     "gulp-less": "^3.3.0",
32 |     "gulp-notify": "^2.2.0",
33 |     "gulp-uglify": "^2.1.2",
34 |     "gulp-util": "^3.0.7",
35 |     "isparta": "^4.0.0",
36 |     "jasmine-core": "^2.8.0",
37 |     "karma": "^1.7.1",
38 |     "karma-browserify": "^5.1.0",
39 |     "karma-chrome-launcher": "^2.2.0",
40 |     "karma-coverage": "^1.1.1",
41 |     "karma-intl-shim": "^1.0.3",
42 |     "karma-jasmine": "^1.1.1",
43 |     "karma-phantomjs-launcher": "^1.0.4",
44 |     "phantomjs-prebuilt": "^2.1.12",
45 |     "pretty-hrtime": "^1.0.2",
46 |     "vinyl-buffer": "^1.0.0",
47 |     "vinyl-source-stream": "^1.1.0",
48 |     "watchify": "3.7.0"
49 |   },
50 |   "eslintConfig": {
51 |     "extends": "xo-space/esnext",
52 |     "env": {
53 |       "jasmine": true
54 |     }
55 |   }
56 | }
57 | 


--------------------------------------------------------------------------------
/dist/locale/kingtable.it.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * KingTable 2.0.0
 3 |  * Italian locale file.
 4 |  * https://github.com/RobertoPrevato/KingTable
 5 |  *
 6 |  * Copyright 2017, Roberto Prevato
 7 |  * https://robertoprevato.github.io
 8 |  *
 9 |  * Licensed under the MIT license:
10 |  * http://www.opensource.org/licenses/MIT
11 |  */
12 | (function () {
13 | 
14 |   if (typeof KingTable == "undefined") {
15 |     var message = "KingTable library is not defined. For further details: https://github.com/RobertoPrevato/KingTable/wiki/Errors#39";
16 |     throw new Error(message);
17 |   }
18 | 
19 |   KingTable.regional.it = {
20 |     "goToDetails": "Dettagli",
21 |     "sortOptions": "Ordinamento",
22 |     "searchSortingRules": "Durante una ricerca testuale, ordina per rilevanza.",
23 |     "advancedFilters": "Filtri avanzati",
24 |     "sortModes": {
25 |       "simple": "Semplice (proprietà singola)",
26 |       "complex": "Complesso (proprietà multiple)"
27 |     },
28 |     "viewsType": {
29 |       "table": "Tabella",
30 |       "gallery": "Galleria"
31 |     },
32 |     "exportFormats": {
33 |       "csv": "Csv",
34 |       "json": "Json",
35 |       "xml": "Xml"
36 |     },
37 |     "columns": "Colonne",
38 |     "export": "Esporta",
39 |     "view": "Vista",
40 |     "views": "Viste",
41 |     "loading": "Caricamento dati",
42 |     "noData": "Nessun oggetto da mostrare",
43 |     "page": "Pagina",
44 |     "resultsPerPage": "Risultati per pagina",
45 |     "results": "Risultati",
46 |     "of": "di",
47 |     "firstPage": "Prima pagina",
48 |     "lastPage": "Ultima pagina",
49 |     "prevPage": "Pagina precedente",
50 |     "nextPage": "Prossima pagina",
51 |     "refresh": "Ricarica",
52 |     "fetchTime": "Dati caricati alle:",
53 |     "anchorTime": "Dati fino alle:",
54 |     "sortAscendingBy": "Ordina per {{name}} crescente",
55 |     "sortDescendingBy": "Ordina per {{name}} decrescente",
56 |     "errorFetchingData": "Si è verificato un errore durante il caricamento dei dati."
57 |   };
58 | })();


--------------------------------------------------------------------------------
/source/code/tests/paginator.spec.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Tests for Paginator class.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import Paginator from "../scripts/filters/paginator";
12 | 
13 | var paginator = new Paginator();
14 | 
15 | describe("Paginator class", () => {
16 |   it("next must increase page number", () => {
17 |     paginator.page = 0;
18 |     expect(paginator.next()).toEqual(paginator);
19 | 
20 |     expect(paginator.page).toEqual(1);
21 | 
22 |     paginator.next();
23 | 
24 |     expect(paginator.page).toEqual(2);
25 |   });
26 | 
27 |   it("must return the number of pages to display n items, with k page size", () => {
28 |     expect(paginator.getPageCount(0, 30)).toEqual(0);
29 |     expect(paginator.getPageCount(10, 30)).toEqual(1);
30 |     expect(paginator.getPageCount(20, 30)).toEqual(1);
31 |     expect(paginator.getPageCount(30, 30)).toEqual(1);
32 |     expect(paginator.getPageCount(41, 30)).toEqual(2);
33 |     expect(paginator.getPageCount(50, 30)).toEqual(2);
34 |     expect(paginator.getPageCount(60, 30)).toEqual(2);
35 |     expect(paginator.getPageCount(61, 30)).toEqual(3);
36 |     expect(paginator.getPageCount(61, 10)).toEqual(7);
37 |     expect(paginator.getPageCount(123, 10)).toEqual(13);
38 |     expect(paginator.getPageCount(149, 10)).toEqual(15);
39 |     expect(paginator.getPageCount(150, 10)).toEqual(15);
40 |   });
41 | 
42 |   it("must fire a callback whenever page changes", () => {
43 |     // example: note that the static method is called on the class
44 |     var i = 0;
45 |     paginator.onPageChange = () => { i++; }
46 | 
47 |     paginator.next()
48 |     expect(i).toEqual(1);
49 | 
50 |     paginator.next();
51 |     expect(i).toEqual(2);
52 | 
53 |     paginator.prev();
54 |     expect(i).toEqual(3);
55 | 
56 |     paginator.first();
57 |     expect(i).toEqual(4);
58 | 
59 |     paginator.page = 100;
60 |     expect(i).toEqual(5);
61 |   });
62 | });
63 | 


--------------------------------------------------------------------------------
/source/code/tests/obj-analyzer.spec.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Tests for Analyzer class.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../scripts/utils";
12 | import Analyzer from "../scripts/data/object-analyzer";
13 | 
14 | const a = new Analyzer();
15 | 
16 | 
17 | describe("Objects Analyzer class", () => {
18 |   it("must describe an object structure", () => {
19 |     var o = {
20 |       a: "Hello",
21 |       b: true,
22 |       c: /aaa/,
23 |       d: 300,
24 |       e: 45.56
25 |     };
26 | 
27 |     var schema = a.describe(o);
28 |     expect(_.equal(schema, {
29 |       "a": "string",
30 |       "b": "boolean",
31 |       "c": "regex",
32 |       "d": "number",
33 |       "e": "number"
34 |     })).toEqual(true, "the properties contain values of asserted types");
35 |   });
36 | 
37 |   it("must describe the structure of list items", () => {
38 |     var data = [{
39 |       age: 30,
40 |       name: "Roberto",
41 |       status: "M",
42 |       gender: "M"
43 |     }];
44 | 
45 |     var schema = a.describeList(data, { limit: 1 });
46 |     expect(_.equal(schema, {
47 |       "age": "number",
48 |       "name": "string",
49 |       "gender": "string",
50 |       "status": "string"
51 |     })).toEqual(true);
52 |   });
53 | 
54 |   it("must describe the structure of list items with nullable properties", () => {
55 |     var data = [{
56 |       age: undefined,
57 |       name: "AA",
58 |       status: "M",
59 |       gender: null
60 |     },{
61 |       age: undefined,
62 |       name: "BB",
63 |       status: "M",
64 |       gender: null
65 |     },{
66 |       age: 30,
67 |       name: "CC",
68 |       status: "M",
69 |       gender: "M"
70 |     }];
71 | 
72 |     var schema = a.describeList(data);
73 |     expect(_.equal(schema, {
74 |       "age": "number",
75 |       "name": "string",
76 |       "gender": "string",
77 |       "status": "string"
78 |     })).toEqual(true);
79 |   });
80 | 
81 | });
82 | 


--------------------------------------------------------------------------------
/servers/flask/core/literature/scribe.py:
--------------------------------------------------------------------------------
 1 | import io
 2 | import sys
 3 | is_python3 = sys.version_info >= (3, 0)
 4 | 
 5 | 
 6 | class Scribe:
 7 | 
 8 |     @staticmethod
 9 |     def read(path):
10 |         with io.open(path, mode="rt", encoding="utf-8") as f:
11 |             s = f.read()
12 |             # go to beginning
13 |             f.seek(0)
14 |         return s
15 |         
16 |     @staticmethod
17 |     def read_beginning(path, lines):
18 |         with io.open(path, mode="rt", encoding="utf-8") as f:
19 |             s = f.read(lines)
20 |             # go to beginning
21 |             f.seek(0)
22 |         return s
23 |     
24 |     @staticmethod
25 |     def read_lines(path):
26 |         with io.open(path, mode="rt", encoding="utf-8") as f:
27 |             content = f.readlines()
28 |         return content
29 |         
30 |     @staticmethod
31 |     def write(contents, path):
32 |         if is_python3:
33 |             with open(path, mode="wt", encoding="utf-8") as f:
34 |                 # truncate previous contents
35 |                 f.truncate()
36 |                 f.write(contents)
37 |         else:
38 |             with io.open(path, mode="wt", encoding="utf-8") as f:
39 |                 # truncate previous contents
40 |                 f.truncate()
41 |                 f.write(contents.decode("utf8"))
42 | 
43 |     @staticmethod
44 |     def write_lines(lines, path):
45 |         if is_python3:
46 |             with open(path, mode="wt", encoding="utf-8") as f:
47 |                 f.writelines([l + "\n" for l in lines])
48 |         else:
49 |             with io.open(path, mode="wt") as f:
50 |                 for line in lines:
51 |                     f.writelines(line.decode("utf8") + "\n")
52 | 
53 |     @staticmethod
54 |     def add_content(contents, path):
55 |         if is_python3:
56 |             with open(path, mode="a", encoding="utf-8") as f:
57 |                 f.writelines(contents)
58 |         else:
59 |             with io.open(path, mode="a") as f:
60 |                 f.writelines(contents.decode("utf8"))
61 | 
62 | 


--------------------------------------------------------------------------------
/source/code/scripts/components/regex.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Regex utilities.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../../scripts/utils.js"
12 | 
13 | export default {
14 | 
15 |   /**
16 |    * Gets a search pattern from a list of strings.
17 |    */
18 |   getPatternFromStrings(a) {
19 |     if (!a || !a.length)
20 |       throw new Error("invalid parameter");
21 |     var s = _.map(a, x => {
22 |       return this.escapeCharsForRegex(x);
23 |     }).join("|");
24 |     return new RegExp("(" + s + ")", "mgi");
25 |   },
26 | 
27 |   /**
28 |    * Prepares a string to use it to declare a regular expression.
29 |    */
30 |   escapeCharsForRegex(s) {
31 |     if (typeof s != "string") {
32 |       return "";
33 |     }
34 |     //characters to escape in regular expressions
35 |     return s.replace(/([\^\$\.\(\)\[\]\?\!\*\+\{\}\|\/\\])/g, "\\$1").replace(/\s/g, "\\s");
36 |   },
37 | 
38 |   /**
39 |    * Gets a regular expression for a search pattern,
40 |    * returns undefined if the regular expression is not valid.
41 |    */
42 |   getSearchPattern(s, options) {
43 |     if (!s) return /.+/mgi;
44 |     options = _.extend({ searchMode: "fullstring" }, options || {});
45 |     switch (options.searchMode.toLowerCase()) {
46 |       case "splitwords":
47 |         throw new Error("Not implemented")
48 | 
49 |       case "fullstring":
50 |         //escape characters
51 |         s = this.escapeCharsForRegex(s);
52 |         try {
53 |           return new RegExp("(" + s + ")", "mgi");
54 |         } catch (ex) {
55 |           //this should not happen
56 |           return;
57 |         }
58 |       break;
59 |       default:
60 |         throw "invalid searchMode";
61 |     }
62 |   },
63 | 
64 |   /**
65 |    * Gets a regular expression for a search match pattern.
66 |    */
67 |   getMatchPattern(s) {
68 |     if (!s) { return /.+/mg; }
69 |     s = this.escapeCharsForRegex(s);
70 |     return new RegExp(s, "i");
71 |   }
72 | }
73 | 


--------------------------------------------------------------------------------
/source/code/scripts/data/object-analyzer.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Object analyzer.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../../scripts/utils";
12 | 
13 | export default class Analyzer {
14 | 
15 |   /**
16 |    * Returns an object describing the properties of a given item.
17 |    * @return {object}
18 |    */
19 |   describe(o, options) {
20 |     if (_.isArray(o))
21 |       return this.describeList(o, options);
22 |     var schema = {}, x;
23 |     for (x in o) {
24 |       schema[x] = this.getType(o[x]);
25 |     }
26 |     return schema;
27 |   }
28 | 
29 |   /**
30 |    * Returns an object describing the properties of the items contained by a list.
31 |    * @return {object}
32 |    */
33 |   describeList(a, options) {
34 |     var schema = {};
35 |     options = options || {};
36 |     function typ(o) {
37 |       return o; // TODO: refactor to return object with "nullable" info?
38 |     }
39 |     var l = _.isNumber(options.limit) ? options.limit : a.length;
40 |     for (var i = 0; i < l; i++) {
41 |       var o = this.describe(a[i]);
42 |       for (var x in o) {
43 |         if (_.has(schema, x)) {
44 |           //compare
45 |           if (typ(o[x]) != undefined && typ(schema[x]) != typ(o[x])) {
46 |             if (!typ(schema[x])) {
47 |               schema[x] = typ(o[x]);
48 |             } else {
49 |               //force string type
50 |               schema[x] = "string";
51 |             }
52 |           }
53 |         } else {
54 |           // add new  property
55 |           _.extend(schema, o);
56 |         }
57 |       }
58 |       if (options.lazy && !_.any(schema, (k, v) => {
59 |         return v === undefined;
60 |       })) {
61 |         break;
62 |       }
63 |     }
64 |     return schema;
65 |   }
66 | 
67 |   /**
68 |    * Returns a string representing a type, in greater detail than normal JS.
69 |    * @return {string}
70 |    */
71 |   getType(o) {
72 |     if (o == null || o == undefined) return;
73 |     if (o instanceof Array) return "array";
74 |     if (o instanceof Date) return "date";
75 |     if (o instanceof RegExp) return "regex";
76 |     return typeof o;
77 |   }
78 | 
79 | }
80 | 


--------------------------------------------------------------------------------
/source/code/scripts/components/reflection.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Reflection utilities.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import _ from "../../scripts/utils"
12 | 
13 | export default {
14 |    // gets value or values of a given object, from a name or namespace (example: "dog.name")
15 |   getPropertyValue(o, name) {
16 |     var a = name.split("."), x = o, p;
17 |     while (p = a.shift()) {
18 |       if (_.has(x, p)) {
19 |         x = x[p];
20 |       }
21 |       if (_.isArray(x)) {
22 |         break;
23 |       }
24 |     }
25 |     if (_.isArray(x)) {
26 |       if (!a.length) {
27 |         return x;
28 |       }
29 |       return this.getCollectionPropertiesValue(x, a.join("."));
30 |     }
31 |     return x;
32 |   },
33 | 
34 |   // gets properties values from a given collection
35 |   getCollectionPropertiesValue(collection, name, includeEmptyValues) {
36 |     if (!name) {
37 |       return collection;
38 |     }
39 |     if (typeof includeEmptyValues != "boolean") {
40 |       includeEmptyValues = false;
41 |     }
42 |     var a = name.split("."), values = [];
43 |     for (var i = 0, l = collection.length; i < l; i++) {
44 |       var o = collection[i];
45 | 
46 |       if (!_.has(o, a[0])) {
47 |         if (includeEmptyValues) {
48 |           values.push(null);
49 |         }
50 |         continue;
51 |       }
52 |       if (_.isArray(o)) {
53 |         var foundColl = this.getCollectionPropertiesValue(o, name);
54 |         if (includeEmptyValues || foundColl.length) {
55 |           values.push(foundColl);
56 |         }
57 |       } else if (_.isPlainObject(o)) {
58 |         var foundVal = this.getPropertyValue(o, name);
59 |         if (includeEmptyValues || this.validateValue(foundVal)) {
60 |           values.push(foundVal);
61 |         }
62 |       } else {
63 |         if (includeEmptyValues || this.validateValue(o)) {
64 |           values.push(o);
65 |         }
66 |       }
67 |     }
68 |     return values;
69 |   },
70 | 
71 |   // returns true if the object has a significant value, false otherwise
72 |   validateValue(o) {
73 |     if (!o) return false;
74 |     if (_.isArray(o)) {
75 |       return !!o.length;
76 |     }
77 |     return true;
78 |   }
79 | }
80 | 


--------------------------------------------------------------------------------
/servers/flask/README.md:
--------------------------------------------------------------------------------
 1 | # Python Flask development server
 2 | A development server is required for the development of the KingTable library, since some features require server side pagination, sorting and filtering (since filtering and sorting affect pagination). Python Flask has been chosen because it's a lightweight web framework that enables fast development (and to take a break from JavaScript!).
 3 | Following are instructions on how to run a Flask development server.
 4 | 
 5 | In order to run the provided Flask development server it is necessary to use Python and Flask (either Python 2.x or 3.x).
 6 | It is recommended to create a virtual environment and use **pip** (package management system for Python) to install Flask.
 7 | Steps:
 8 | 
 9 | * If necessary, install Python from the [official website](https://www.python.org/downloads/)
10 | * When in doubt, version 3.x is recommended
11 | * Depending on the operating system, Python could be already installed or using different PATH variables: in most Linux distributions both Python 3.x and 2.x are pre-installed, Python 3.x has the PATH name python3, while Python 2.x has the PATH name python; while in Windows they are not installed by default, and Python 3.x can be launched using py -3; Python 2.x using py -2 (when they are both installed)
12 | * Learn how to create virtual environments: this is a best practice when working with Python, since it allows to keep the base installation clean and to install dependencies when needed, on a project-basis
13 | ```bash
14 | # creating a virtual environment in a folder called 'env', using Python 3.x in Ubuntu:
15 | python3 -m venv env
16 | 
17 | # creating a virtual environment in a folder called 'env', using Python 3.x in Windows:
18 | py -3 -m venv env
19 | ```
20 | * NB: in Linux, a Python virtual environment with name _"env"_ has its interpreter files under _env/bin/_ folder; in Windows under _env\Scripts\_ folder. In following instructions, _env/bin_ is used: adapt as needed if you are using Windows
21 | * Install Flask using the command: `env/bin/pip install Flask`
22 | * (OPTIONAL) Activate the virtual environment using the command: `source env/bin/activate`
23 | 
24 | * Run the development server.py included in the repository:
25 | ```bash
26 | # if you activated the virtual environment, you can run simply using:
27 | python server.py
28 | 
29 | # if you did not activate the virtual environment, you need to call the right Python executable:
30 | env/bin/python server.py
31 | 
32 | # (or, for Windows users):
33 | env\Scripts\python server.py
34 | ```
35 | 


--------------------------------------------------------------------------------
/source/code/tests/events.spec.js:
--------------------------------------------------------------------------------
  1 | /**
  2 |  * Tests for EventsEmitter class.
  3 |  * https://github.com/RobertoPrevato/KingTable
  4 |  *
  5 |  * Copyright 2018, Roberto Prevato
  6 |  * https://robertoprevato.github.io
  7 |  *
  8 |  * Licensed under the MIT license:
  9 |  * http://www.opensource.org/licenses/MIT
 10 |  */
 11 | import EventsEmitter from "../scripts/components/events";
 12 | 
 13 | class Cat extends EventsEmitter {
 14 |   constructor() {
 15 |     super();
 16 |   }
 17 | };
 18 | 
 19 | class Dog extends EventsEmitter {
 20 |   constructor() {
 21 |     super();
 22 |   }
 23 | 
 24 |   bark() {
 25 |     this.trigger("bark");
 26 |   }
 27 | }
 28 | 
 29 | var CACHE = {
 30 |   meow: 0,
 31 |   meowzz: 0
 32 | };
 33 | 
 34 | describe("EventsEmitter class", () => {
 35 | 
 36 |   it("must support custom event handlers", () => {
 37 |     var cat = new Cat();
 38 |     cat.on("meow", () => {
 39 |       CACHE.meow++;
 40 |     });
 41 | 
 42 |     cat.trigger("meow");
 43 |     expect(CACHE.meow).toEqual(1);
 44 | 
 45 |     cat.trigger("meow");
 46 |     expect(CACHE.meow).toEqual(2);
 47 |   });
 48 | 
 49 |   it("must support once event handlers", () => {
 50 |     var cat = new Cat();
 51 | 
 52 |     cat.once("meowzz", () => {
 53 |       CACHE.meowzz++;
 54 |     });
 55 | 
 56 |     cat.trigger("meowzz");
 57 |     expect(CACHE.meowzz).toEqual(1);
 58 | 
 59 |     cat.trigger("meowzz");
 60 |     expect(CACHE.meowzz).toEqual(1);
 61 | 
 62 |     cat.trigger("meowzz");
 63 |     expect(CACHE.meowzz).toEqual(1);
 64 |   });
 65 | 
 66 |   it("must allow to listen other events transmitters", () => {
 67 |     var cat = new Cat(), dog = new Dog(), n = 0;
 68 | 
 69 |     cat.listenTo(dog, "bark", function() {
 70 |       expect(this).toEqual(cat);
 71 |       cat.trigger("run");
 72 |       n++;
 73 |     });
 74 | 
 75 |     dog.trigger("bark");
 76 |     expect(n).toEqual(1);
 77 | 
 78 |     dog.trigger("bark");
 79 |     expect(n).toEqual(2);
 80 |   });
 81 | 
 82 |   it("must allow to listen other events transmitters", () => {
 83 |     var cat = new Cat(), dog = new Dog(), n = 0;
 84 | 
 85 |     // NB: context is respected only if using function () { } syntax
 86 |     cat.listenToOnce(dog, "bark", function() {
 87 |       expect(this).toEqual(cat);
 88 |       cat.trigger("run");
 89 |       n++;
 90 |     });
 91 | 
 92 |     dog.trigger("bark");
 93 |     expect(n).toEqual(1);
 94 | 
 95 |     dog.trigger("bark");
 96 |     expect(n).toEqual(1);
 97 | 
 98 |     dog.trigger("bark");
 99 |     expect(n).toEqual(1);
100 |   });
101 | 
102 | });
103 | 


--------------------------------------------------------------------------------
/source/code/tests/csv.spec.js:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Tests for csv utility functions.
 3 |  * https://github.com/RobertoPrevato/KingTable
 4 |  *
 5 |  * Copyright 2018, Roberto Prevato
 6 |  * https://robertoprevato.github.io
 7 |  *
 8 |  * Licensed under the MIT license:
 9 |  * http://www.opensource.org/licenses/MIT
10 |  */
11 | import csv from "../scripts/data/csv"
12 | 
13 | const BOM = "\uFEFF"
14 | 
15 | describe("CSV helper functions", () => {
16 |   it("must allow to serialize collections in CSV", () => {
17 |     var a = [
18 |       ["id", "firstname", "lastname"],
19 |       [1, "Giulio", "Cesare"]
20 |     ];
21 |     var b = csv.serialize(a);
22 | 
23 |     var expected = `${BOM}id,firstname,lastname
24 | 1,Giulio,Cesare`;
25 |     expect(b).toEqual(expected);
26 |   })
27 | 
28 |   it("must handle values containing commas", () => {
29 |     var a = [
30 |       ["id", "model", "something"],
31 |       [1, "A31, KOP", "Hello World"]
32 |     ];
33 |     var b = csv.serialize(a);
34 | 
35 |     var expected = `${BOM}id,model,something
36 | 1,"A31, KOP",Hello World`;
37 |     expect(b).toEqual(expected);
38 |   })
39 | 
40 |   it("must handle values containing commas and double quotes", () => {
41 |     var a = [
42 |       ["id", "model", "something"],
43 |       [1, "A31, \"KOP\"", "Hello World"]
44 |     ];
45 |     var b = csv.serialize(a);
46 |     var expected = `${BOM}id,model,something
47 | 1,"A31, \"\"KOP\"\"",Hello World`;
48 |     expect(b).toEqual(expected);
49 |   })
50 | 
51 |   it("must allow to use custom separators", () => {
52 |     var a = [
53 |       ["id", "model", "something"],
54 |       [1, "A31, KOP", "Hello World"]
55 |     ];
56 |     var b = csv.serialize(a, { separator: "|" });
57 | 
58 |     var expected = `${BOM}id|model|something
59 | 1|A31, KOP|Hello World`;
60 |     expect(b).toEqual(expected);
61 |   })
62 | 
63 |   it("must allow to remove BOM", () => {
64 |     var a = [
65 |       ["id", "model", "something"],
66 |       [1, "A31, KOP", "Hello World"]
67 |     ];
68 |     var b = csv.serialize(a, { addBom: false, separator: "|" });
69 | 
70 |     var expected = `id|model|something
71 | 1|A31, KOP|Hello World`;
72 |     expect(b).toEqual(expected);
73 |   })
74 | 
75 |   it("must allow to include separator, for MS Excel", () => {
76 |     var a = [
77 |       ["id", "firstname", "lastname"],
78 |       [1, "Giulio", "Cesare"]
79 |     ];
80 |     var b = csv.serialize(a, { addSeparatorLine: true });
81 | 
82 |     var expected = `${BOM}id,firstname,lastname
83 | 1,Giulio,Cesare
84 | \t,`;
85 |     expect(b).toEqual(expected);
86 |   })
87 | 
88 | });
89 | 


--------------------------------------------------------------------------------
/servers/flask/templates/rhtml-schemas.html:
--------------------------------------------------------------------------------
 1 | {%- extends "layout.html" -%}
 2 | {%- block title -%}
 3 |   KingTable schemas demo
 4 | {%- endblock -%}
 5 | {%- block body -%}
 6 | {% include "partials/themes.html" %}
 7 | 
8 |
9 |
10 | {%- endblock -%} 11 | {%- block js -%} 12 | 79 | {%- endblock -%} 80 | -------------------------------------------------------------------------------- /source/code/scripts/menus/kingtable.menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * KingTable menu core functions. 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | import $ from "../../scripts/dom" 12 | import _ from "../../scripts/utils" 13 | 14 | function eventToIgnore(e) { 15 | return /input|select|textarea|label|^a$/i.test(e.target.tagName); 16 | } 17 | 18 | var menufunctions = { 19 | 20 | closeMenus: function (e) { 21 | var self = this; 22 | if (e && e.which === 3) return; 23 | _.each(["ug-menu", "ug-submenu"], className => { 24 | var elements = document.body.getElementsByClassName(className); 25 | 26 | _.each(elements, el => { 27 | if ($.contains(el, e.target)) return; 28 | 29 | var parent = el.parentNode; 30 | if (!$.hasClass(parent, "open")) return; 31 | 32 | if (/input|textarea/i.test(e.target.tagName) && $.contains(parent, e.target)) return; 33 | 34 | $.removeClass(parent, "open"); 35 | }); 36 | }); 37 | }, 38 | 39 | expandMenu: function (e) { 40 | if (eventToIgnore(e)) return true; 41 | var self = this, 42 | el = e.target, disabled = "disabled"; 43 | if ($.hasClass(el, disabled) || el.hasAttribute(disabled)) { 44 | return false; 45 | } 46 | var parent = el.parentElement, open = "open"; 47 | if ($.hasClass(parent, open)) { 48 | $.removeClass(parent, open); 49 | } else { 50 | $.addClass(parent, open); 51 | } 52 | e.preventDefault(); 53 | return false; 54 | }, 55 | 56 | expandSubMenu: function (e) { 57 | if (eventToIgnore(e)) return true; 58 | var open = "open", 59 | el = $.closestWithTag(e.target, "li"), 60 | siblings = $.siblings(el); 61 | _.each(siblings, sib => { 62 | $.removeClass(sib, open); 63 | var allOpen = sib.getElementsByClassName(open); 64 | _.each(allOpen, a => { 65 | $.removeClass(a, open); 66 | }); 67 | }); 68 | $.addClass(el, open); 69 | return false; 70 | } 71 | }; 72 | 73 | export default { 74 | 75 | setup() { 76 | if (this.initialized) { 77 | return false; 78 | } 79 | this.initialized = true; 80 | var click = "click.menus", 81 | keydown = "keydown.menus", bo = document.body; 82 | $.off(bo, click) 83 | $.on(bo, click, menufunctions.closeMenus); // order is important 84 | $.on(bo, click, ".ug-expander", menufunctions.expandMenu); 85 | $.on(bo, click, ".ug-submenu", menufunctions.expandSubMenu); 86 | } 87 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/midnight/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-midnight { 2 | 3 | .king-table-container { 4 | border-top: 1px solid #222; 5 | } 6 | 7 | .filters-region { 8 | border-bottom-color: #000; 9 | } 10 | 11 | .king-table { 12 | color:#c4feff; 13 | background: #000; 14 | border-collapse: collapse; 15 | border: none; 16 | font-family: Sans-Serif; 17 | font-size: 12px; 18 | line-height: 17px; 19 | margin-bottom: 10px; 20 | border-bottom: 1px solid #666; 21 | } 22 | 23 | .king-table caption { 24 | border: 1px solid #d0d0d0; 25 | font-weight: bold; 26 | background: #000 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAcF/8QAHhABAAAFBQAAAAAAAAAAAAAAAAEDFBUXUVVipOL/xAAVAQEBAAAAAAAAAAAAAAAAAAABA//EABYRAQEBAAAAAAAAAAAAAAAAAAASAf/aAAwDAQACEQMRAD8A27xyEHylM2ns+Q0lOpVUQ1ACr//Z") top left repeat-x; 27 | } 28 | 29 | .king-table tr td.row-number { 30 | width:40px; 31 | text-align:center; 32 | } 33 | 34 | .king-table a { 35 | color: #00becf; 36 | } 37 | 38 | .king-table a:hover { 39 | color: #FFF; 40 | } 41 | 42 | .king-table .king-table tr, .king-table .king-table-head tr { 43 | width: 100%; 44 | border-color: #333; 45 | } 46 | 47 | .king-table-body tr:hover:nth-child(even), .king-table-body tr:hover:nth-child(odd) { 48 | background-color: #06002a; 49 | &.king-table-empty, &.king-table-error { 50 | background: #000; 51 | } 52 | } 53 | .king-table .king-table-head tr { 54 | background-color: #000; 55 | border-bottom: 1px solid #222; 56 | } 57 | .king-table .king-table-head tr { 58 | height: 18px; 59 | } 60 | .king-table tr th { 61 | text-align: left; 62 | border-top: 1px solid #222; 63 | } 64 | .king-table tr td { 65 | line-height: 15px; 66 | border-right: 1px solid #222; 67 | border-bottom: 1px solid #222; 68 | } 69 | .king-table tr { 70 | th, td { 71 | &.row-number { 72 | border-top: 1px solid #222; 73 | background: #000 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAWAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYH/8QAGBABAAMBAAAAAAAAAAAAAAAAAAIUYmH/xAAUAQEAAAAAAAAAAAAAAAAAAAAC/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAMAwEAAhEDEQA/AMTv6Erf0HRiWuT6ABP/2Q==") top left repeat-x; 74 | } 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/bronze/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-bronze { 2 | 3 | .king-table-container { 4 | border-top: 1px solid #533e29; 5 | } 6 | 7 | .filters-region { 8 | background-color: #FFA92D; 9 | border-bottom-color: #FFA92D; 10 | } 11 | 12 | .king-table { 13 | background: #DA832C; 14 | border-collapse: collapse; 15 | border-color: #533e29; 16 | border: none; 17 | font-family: Sans-Serif; 18 | font-size: 12px; 19 | line-height: 17px; 20 | margin-bottom: 10px; 21 | border-bottom: 1px solid #533e29; 22 | } 23 | 24 | .king-table-gallery { 25 | background-color: #3A1700; 26 | color: #FFA53D; 27 | li > span { 28 | border-bottom: 1px solid #533E29; 29 | } 30 | } 31 | 32 | .king-table caption { 33 | border: 1px solid #533e29; 34 | font-weight: bold; 35 | background: white url("data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAABmJLR0QA3wB5ABSzHNRVAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QkaFRIaz7uY6QAAAENJREFUCNdly7EJgFAQBNG5xUxswf4Tq7ICBUN3Df5pYvYYGLytURIkFobKEwIQdb2SW87cOvYT2e7NNqrU1/7iZrwPFLYoooBe/o4AAAAASUVORK5CYII=") top left repeat; 36 | } 37 | 38 | .king-table tr td.row-number { 39 | width:40px; 40 | text-align:center; 41 | } 42 | 43 | .king-table a { 44 | color: #000; 45 | &:hover { 46 | color: #C00; 47 | } 48 | } 49 | 50 | .king-table .king-table tr, .king-table .king-table-head tr { 51 | width: 100%; 52 | border-color: #483419; 53 | } 54 | 55 | .king-table-body tr:hover:nth-child(even), .king-table-body tr:hover:nth-child(odd) { 56 | background-color: #ffecb5; 57 | &.king-table-empty, &.king-table-error { 58 | background: #DA832C; 59 | } 60 | } 61 | 62 | .king-table .king-table-head tr { 63 | height: 18px; 64 | background: #E27D15 url("data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAABmJLR0QA3wB5ABSzHNRVAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QkaFRIaz7uY6QAAAENJREFUCNdly7EJgFAQBNG5xUxswf4Tq7ICBUN3Df5pYvYYGLytURIkFobKEwIQdb2SW87cOvYT2e7NNqrU1/7iZrwPFLYoooBe/o4AAAAASUVORK5CYII=") top left repeat-x; 65 | border-bottom: 1px solid #000; 66 | } 67 | 68 | .king-table tr th { 69 | text-align: left; 70 | border-top: 1px solid #efb77c; 71 | border-right: 1px solid #000; 72 | } 73 | 74 | .king-table tr td { 75 | line-height: 15px; 76 | border-right: 1px solid #483419; 77 | border-bottom: 1px solid #483419; 78 | } 79 | 80 | .king-table tr { 81 | th, td { 82 | &.row-number { 83 | background: #e27d15 url("data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAABmJLR0QA3wB5ABSzHNRVAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QkaFRIaz7uY6QAAAENJREFUCNdly7EJgFAQBNG5xUxswf4Tq7ICBUN3Df5pYvYYGLytURIkFobKEwIQdb2SW87cOvYT2e7NNqrU1/7iZrwPFLYoooBe/o4AAAAASUVORK5CYII=") top left repeat-x; 84 | } 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /servers/flask/templates/rhtml-colors-localized.html: -------------------------------------------------------------------------------- 1 | {%- extends "layout.html" -%} 2 | {%- block title -%} 3 | KingTable demo colori 4 | {%- endblock -%} 5 | {%- block body -%} 6 | {% include "partials/themes.html" %} 7 |
8 | {%- endblock -%} 9 | {%- block js -%} 10 | 11 | 89 | {%- endblock -%} 90 | -------------------------------------------------------------------------------- /source/gulp/config.js: -------------------------------------------------------------------------------- 1 | const WWWROOT = "../httpdocs/"; 2 | const JS_DEST = WWWROOT + "scripts/"; 3 | const CSS_DEST = WWWROOT + "styles/"; 4 | const IMG_DEST = WWWROOT + "images/"; 5 | const FONTS_DEST = WWWROOT + "styles/fonts/"; 6 | 7 | const year = new Date().getFullYear(); 8 | const VERSION = "2.0.0" 9 | const LICENSE = ` 10 | /** 11 | * KingTable ${VERSION} 12 | * https://github.com/RobertoPrevato/KingTable 13 | * 14 | * Copyright ${year}, Roberto Prevato 15 | * https://robertoprevato.github.io 16 | * 17 | * Licensed under the MIT license: 18 | * http://www.opensource.org/licenses/MIT 19 | */ 20 | `.replace(/^\s+/m, "") 21 | 22 | module.exports = { 23 | 24 | // root folder to less source code 25 | lessRoot: "./code/styles/**/*.less", 26 | 27 | distFolder: "../dist/", 28 | cssDistFolder: "../dist/styles/", 29 | 30 | license: LICENSE, 31 | version: VERSION, 32 | 33 | lessToCss: [ 34 | { 35 | src: "./code/styles/kingtable/kingtable.less", 36 | dest: CSS_DEST 37 | }, 38 | { 39 | src: "./code/styles/examples.less", 40 | dest: CSS_DEST, 41 | nodist: true 42 | } 43 | ], 44 | 45 | lessToCssExtras: [ 46 | { 47 | src: "./code/styles/kingtable/kingtable.core.less", 48 | dest: CSS_DEST 49 | }, 50 | { 51 | src: "./code/styles/kingtable/kingtable.flatblack.less", 52 | dest: CSS_DEST 53 | }, 54 | { 55 | src: "./code/styles/kingtable/kingtable.midnight.less", 56 | dest: CSS_DEST 57 | }, 58 | { 59 | src: "./code/styles/kingtable/kingtable.clear.less", 60 | dest: CSS_DEST 61 | }, 62 | { 63 | src: "./code/styles/kingtable/kingtable.dark.less", 64 | dest: CSS_DEST 65 | } 66 | ], 67 | 68 | esToJs: [ 69 | { 70 | entry: "./code/scripts/tables/kingtable.js", 71 | destfolder: JS_DEST, 72 | filename: "kingtable" 73 | }, 74 | { 75 | entry: "./code/scripts/tables/kingtable.xlsx.js", 76 | destfolder: JS_DEST, 77 | filename: "kingtable.xlsx" 78 | } 79 | ], 80 | 81 | toBeCopied: [ 82 | { 83 | src: "code/favicon.ico", 84 | dest: WWWROOT 85 | }, 86 | { 87 | src: "code/kingtable.svg", 88 | dest: WWWROOT 89 | }, 90 | { 91 | src: "code/*.png", 92 | dest: WWWROOT 93 | }, 94 | { 95 | src: "testdata/*.js", 96 | dest: JS_DEST 97 | }, 98 | { 99 | src: "libs/*.js", 100 | dest: JS_DEST 101 | }, 102 | { 103 | src: "code/styles/openicon/fonts/*", 104 | dest: FONTS_DEST 105 | }, 106 | { 107 | src: "code/images/*", 108 | dest: IMG_DEST 109 | }, 110 | { 111 | src: "code/scripts/libs/**/*.js", 112 | dest: JS_DEST + "libs/" 113 | } 114 | ], 115 | 116 | test: { 117 | karma: "karma.conf.js" 118 | } 119 | }; 120 | -------------------------------------------------------------------------------- /servers/flask/templates/rhtml-custom-views.html: -------------------------------------------------------------------------------- 1 | {%- extends "layout.html" -%} 2 | {%- block title -%} 3 | KingTable views demo 4 | {%- endblock -%} 5 | {%- block body -%} 6 | {% include "partials/themes.html" %} 7 |
8 | {%- endblock -%} 9 | {%- block js -%} 10 | 18 | 79 | {%- endblock -%} 80 | -------------------------------------------------------------------------------- /source/code/tests/json.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests for json proxy functions. 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | import json from "../scripts/data/json" 12 | 13 | describe("JSON proxy functions", () => { 14 | it("must parse dates in ISO format automatically", () => { 15 | var a = '{"a":"2017-02-08T15:32:27.118Z"}'; 16 | var b = json.parse(a); 17 | 18 | expect(b.a instanceof Date).toEqual(true, "a string in ISO format should be parsed automatically as date"); 19 | expect(b.a.getFullYear()).toEqual(2017); 20 | expect(b.a.getMonth()).toEqual(1); 21 | expect(b.a.getDate()).toEqual(8); 22 | expect(b.a.getUTCHours()).toEqual(15); 23 | expect(b.a.getUTCMinutes()).toEqual(32); 24 | }) 25 | 26 | it("must parse dates not in ISO format automatically (HH:mm:ss)", () => { 27 | var a = '{"a":"2017-02-08 15:32:15"}'; 28 | var b = json.parse(a); 29 | 30 | expect(b.a instanceof Date).toEqual(true, "a string in ISO format should be parsed automatically as date"); 31 | expect(b.a.getFullYear()).toEqual(2017); 32 | expect(b.a.getMonth()).toEqual(1); 33 | expect(b.a.getDate()).toEqual(8); 34 | expect(b.a.getHours()).toEqual(15); 35 | expect(b.a.getMinutes()).toEqual(32); 36 | expect(b.a.getSeconds()).toEqual(15); 37 | }) 38 | 39 | it("must parse dates not in ISO format automatically (HH:mm)", () => { 40 | var a = '{"a":"2017-02-08 15:32"}'; 41 | var b = json.parse(a); 42 | 43 | expect(b.a instanceof Date).toEqual(true, "a string in ISO format should be parsed automatically as date"); 44 | expect(b.a.getFullYear()).toEqual(2017); 45 | expect(b.a.getMonth()).toEqual(1); 46 | expect(b.a.getDate()).toEqual(8); 47 | expect(b.a.getHours()).toEqual(15); 48 | expect(b.a.getMinutes()).toEqual(32); 49 | expect(b.a.getSeconds()).toEqual(0); 50 | }) 51 | 52 | it("must parse dates not in ISO format automatically (HH)", () => { 53 | var a = '{"a":"2017-02-08 15"}'; 54 | var b = json.parse(a); 55 | 56 | expect(b.a instanceof Date).toEqual(true, "a string in ISO format should be parsed automatically as date"); 57 | expect(b.a.getFullYear()).toEqual(2017); 58 | expect(b.a.getMonth()).toEqual(1); 59 | expect(b.a.getDate()).toEqual(8); 60 | expect(b.a.getHours()).toEqual(15); 61 | expect(b.a.getMinutes()).toEqual(0); 62 | expect(b.a.getSeconds()).toEqual(0); 63 | }) 64 | 65 | it("must include properties with undefined values in serialized strings", () => { 66 | var a = {"someProperty": undefined }; 67 | var b = json.compose(a); 68 | 69 | expect(b.indexOf("someProperty") != -1).toEqual(true, "a serialized JSON object must include undefined properties"); 70 | expect(b.indexOf("someProperty\":null") != -1).toEqual(true, "undefined values are serialized as null"); 71 | }) 72 | }); 73 | -------------------------------------------------------------------------------- /dist/styles/kingtable.flatblack.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */.theme-flatblack .king-table tr{border-bottom:1px solid #4A1111}.theme-flatblack .king-table-head{background-color:#000}.theme-flatblack .filters-region{border-bottom-color:#000}.theme-flatblack a{color:#DADAD4}.theme-flatblack .king-table-body tr:hover{background-color:#2D0303}.theme-flatblack .pagination-bar{background-color:#000;border:1px solid rgba(18,18,18,.87);border-top:0}.theme-flatblack .pagination-bar .pagination-button,.theme-flatblack .pagination-bar .pagination-button-disabled,.theme-flatblack .pagination-bar .separator{border:1px solid transparent}.theme-flatblack .pagination-bar .separator{border-right:1px solid #666}.theme-flatblack .pagination-bar .search-field,.theme-flatblack .pagination-bar select{border-radius:0}.theme-flatblack .kt-search-highlight{background-color:#791919}.theme-flatblack .search-field{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==)}.theme-flatblack .king-table-container .preloader-mask{opacity:.5;background-color:#5F0909}.theme-flatblack .king-table-region .ug-menu{box-shadow:0 6px 12px #691010;background:#111;color:#DADAD4}.theme-flatblack .king-table-region .ug-menu li{border-bottom:1px solid #4A1111}.theme-flatblack .king-table-region .ug-menu li a,.theme-flatblack .king-table-region .ug-menu li label,.theme-flatblack .king-table-region .ug-menu li span{color:#DADAD4}.theme-flatblack .king-table-region .ug-menu li a:focus,.theme-flatblack .king-table-region .ug-menu li a:hover,.theme-flatblack .king-table-region .ug-menu li label:focus,.theme-flatblack .king-table-region .ug-menu li label:hover,.theme-flatblack .king-table-region .ug-menu li span:focus,.theme-flatblack .king-table-region .ug-menu li span:hover{color:#DADAD4;background-color:#2D0303}.theme-flatblack .king-table-region .ug-menu li.open>a,.theme-flatblack .king-table-region .ug-menu li.open>label,.theme-flatblack .king-table-region .ug-menu li.open>span{background-color:#2D0303}.theme-flatblack{color:#DADAD4;background-color:#000}.theme-flatblack .camo-btn{color:#DADAD4}.theme-flatblack hr{border-top:1px solid #aaa;border-bottom:1px solid #fff} -------------------------------------------------------------------------------- /dist/kingtable.xlsx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * KingTable 2.0.0 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | !function e(t,n,r){function o(l,a){if(!n[l]){if(!t[l]){var s="function"==typeof require&&require;if(!a&&s)return s(l,!0);if(i)return i(l,!0);var u=new Error("Cannot find module '"+l+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[l]={exports:{}};t[l][0].call(f.exports,function(e){var n=t[l][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[l].exports}for(var i="function"==typeof require&&require,l=0;lo&&(r.s.r=o),r.s.c>i&&(r.s.c=i),r.e.r" + escapeHtml(val) + ""; 83 | } 84 | if (j < text.length) { 85 | s += escapeHtml(text.substr(j)); 86 | } 87 | return s; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /servers/flask/templates/index.html: -------------------------------------------------------------------------------- 1 | {%- extends "layout.html" -%} 2 | {%- block title -%} 3 | KingTable 2.0.0 4 | {%- endblock -%} 5 | {%- block body -%} 6 |

Links

7 |
    8 |
  1. 9 |

    Plain text examples

    10 |

    Table rendered in plain text, without event handlers. 11 | Suitable for Node.js console applications, read only interfaces and emails.

    12 | 18 |
  2. 19 |
  3. 20 |

    HTML examples

    21 |

    Table rendered in HTML format without event handlers. 22 | Suitable for web pages, desktop applications implemented using Electron, and emails with HTML body.

    23 | 29 |
  4. 30 |
  5. 31 |

    Rich HTML examples

    32 |

    Table rendered in HTML format with event handlers and extra tools. 33 | Suitable for web pages and desktop applications implemented using Electron.

    34 | 45 |
  6. 46 |
47 | {%- endblock -%} 48 | {%- block js -%} 49 | {%- endblock -%} 50 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/dark/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-dark { 2 | 3 | .king-table-container { 4 | border-top: 1px solid #222; 5 | } 6 | 7 | .king-table-head { 8 | background-color: #000; 9 | } 10 | 11 | .filters-region { 12 | border-bottom-color: #000; 13 | } 14 | 15 | .king-table { 16 | color: #DEDEDE; 17 | background: #222; 18 | border-collapse: collapse; 19 | border: none; 20 | font-family: Sans-Serif; 21 | font-size: 12px; 22 | line-height: 17px; 23 | margin-bottom: 10px; 24 | border-bottom: 1px solid #666; 25 | } 26 | 27 | .king-table-gallery { 28 | background-color: #303435; 29 | } 30 | 31 | .king-table caption { 32 | border: 1px solid #d0d0d0; 33 | font-weight: bold; 34 | background: #373737 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYF/8QAFxABAQEBAAAAAAAAAAAAAAAAABRhYv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDMu0S9+gJa7oAH/9k=") top left repeat; 35 | } 36 | 37 | .king-table tr td.row-number { 38 | width:40px; 39 | text-align:center; 40 | } 41 | 42 | .king-table a { 43 | color: #DEDEDE; 44 | &:focus, &:hover { 45 | color: #FFF; 46 | } 47 | } 48 | 49 | .king-table .king-table tr, .king-table .king-table-head tr { 50 | width: 100%; 51 | border-color: #666; 52 | } 53 | 54 | .king-table-body tr:hover:nth-child(even), .king-table-body tr:hover:nth-child(odd) { 55 | background-color: #111; 56 | &.king-table-empty, &.king-table-error { 57 | background: #222; 58 | } 59 | } 60 | 61 | .king-table .king-table-head tr { 62 | background: #373737 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYF/8QAFxABAQEBAAAAAAAAAAAAAAAAABRhYv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDMu0S9+gJa7oAH/9k=") top left repeat-x; 63 | } 64 | 65 | .king-table .king-table-head tr { 66 | height: 18px; 67 | } 68 | 69 | .king-table tr th { 70 | text-align: left; 71 | border: 1px solid #666; 72 | border-top: 1px solid #d6d6d6; 73 | } 74 | 75 | .king-table tr td { 76 | line-height: 15px; 77 | border-right: 1px solid #444; 78 | border-bottom: 1px solid #444; 79 | } 80 | 81 | .king-table tr { 82 | th, td { 83 | &.row-number { 84 | border: 1px solid #666; 85 | border-top: 1px solid #d6d6d6; 86 | background: #373737 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYF/8QAFxABAQEBAAAAAAAAAAAAAAAAABRhYv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDMu0S9+gJa7oAH/9k=") top left repeat-x; 87 | } 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/olive/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-olive { 2 | .king-table { 3 | color: #1c2706; 4 | background: #bebd63; 5 | border-collapse: collapse; 6 | border: none; 7 | font-family: Sans-Serif; 8 | font-size: 12px; 9 | line-height: 17px; 10 | margin-bottom: 10px; 11 | border-bottom: 1px solid #475f15; 12 | } 13 | 14 | .filters-region { 15 | background-color: #CBDF30; 16 | } 17 | 18 | .king-table-gallery { 19 | background-color: #233107; 20 | color: #DCF043; 21 | li > span { 22 | border-bottom: 1px solid #4C5D2C; 23 | } 24 | } 25 | 26 | .king-table caption { 27 | border: 1px solid #475f15; 28 | font-weight: bold; 29 | background: white url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAQGCP/EABwQAQACAQUAAAAAAAAAAAAAAAABFGECBFGR0f/EABcBAAMBAAAAAAAAAAAAAAAAAAEDBQf/xAAXEQEBAQEAAAAAAAAAAAAAAAAAEQIV/9oADAMBAAIRAxEAPwDSlrIr1rdcaOp9GK9vZsTq0YARIL//2Q==") top left repeat; 30 | } 31 | 32 | .king-table tr td.row-number { 33 | width:40px; 34 | text-align:center; 35 | color:#475f15; 36 | } 37 | 38 | .king-table a { 39 | color: #000; 40 | } 41 | 42 | .king-table a:hover { 43 | color: #C00; 44 | } 45 | 46 | .king-table .king-table tr, .king-table .king-table-head tr { 47 | width: 100%; 48 | } 49 | 50 | .king-table-body tr:hover:nth-child(even), .king-table-body tr:hover:nth-child(odd) { 51 | background-color: #e6f0a3; 52 | &.king-table-empty, &.king-table-error { 53 | background: #bebd63; 54 | } 55 | } 56 | 57 | .king-table .king-table-head tr { 58 | background: #dbf043 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAQGCP/EABwQAQACAQUAAAAAAAAAAAAAAAABFGECBFGR0f/EABcBAAMBAAAAAAAAAAAAAAAAAAEDBQf/xAAXEQEBAQEAAAAAAAAAAAAAAAAAEQIV/9oADAMBAAIRAxEAPwDSlrIr1rdcaOp9GK9vZsTq0YARIL//2Q==") top left repeat-x; 59 | } 60 | 61 | .king-table .king-table-head tr { 62 | height: 18px; 63 | } 64 | 65 | .king-table tr th { 66 | text-align: left; 67 | border: 1px solid #475f15; 68 | } 69 | 70 | .king-table tr td { 71 | line-height: 15px; 72 | border-right: 1px solid #475f15; 73 | border-bottom: 1px solid #475f15; 74 | } 75 | 76 | .king-table tr { 77 | th, td { 78 | &.row-number { 79 | border: 1px solid #475f15; 80 | border-top: 1px solid #475f15; 81 | background: #dbf043 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAWAAEDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAUGCP/EABoQAQACAwEAAAAAAAAAAAAAAAACEwQUUZH/xAAXAQADAQAAAAAAAAAAAAAAAAABAwUH/8QAFxEBAAMAAAAAAAAAAAAAAAAAAAMSFf/aAAwDAQACEQMRAD8A0ptiv35PI+DE9qQ2qQogAjC//9k=") top left repeat-x; 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /servers/flask/core/lists/listutils.py: -------------------------------------------------------------------------------- 1 | import re 2 | import locale 3 | import unidecode 4 | locale.setlocale(locale.LC_ALL, "") 5 | 6 | 7 | class ListUtils: 8 | 9 | @staticmethod 10 | def parse_sort_by(s): 11 | """ 12 | Parses a sort by string, converting it into an array of arrays. 13 | 14 | :param s: sort by string 15 | """ 16 | if not s: 17 | return 18 | parts = re.split("\s*,\s*", s) 19 | result = [] 20 | for part in parts: 21 | a = re.split("\s*", part) 22 | name = a[0] 23 | order = a[1] if len(a) == 2 else "asc" 24 | result.append([name, 1 if order.startswith("asc") else -1]) 25 | return result 26 | 27 | @staticmethod 28 | def sort_by(a, criteria): 29 | """ 30 | Sorts an array of items by one or more properties. 31 | 32 | :param a: array to sort 33 | :param criteria: sort criteria 34 | :return: 35 | """ 36 | if isinstance(criteria, str): 37 | criteria = ListUtils.parse_sort_by(criteria) 38 | # assume that properties are in order of importance, sorting must be from less important 39 | # to most important property: 40 | criteria.reverse() 41 | for k in criteria: 42 | prop, order = k 43 | def fn(o): 44 | v = o.get(prop) 45 | if isinstance(v, str): 46 | # TODO: check if the string look like a number 47 | # (like '100%', if so, parse as number) 48 | # normalize 49 | v = unidecode.unidecode(v) 50 | return v 51 | a.sort(key=fn, reverse=order == -1) 52 | return a 53 | 54 | 55 | @staticmethod 56 | def sampling(selection, offset=0, limit=None): 57 | return selection[offset:(limit + offset if limit is not None else None)] 58 | 59 | @staticmethod 60 | def optimize_list(collection): 61 | """ 62 | Optimizes a collection of items; into a collection of arrays. 63 | The first array contains the property names; the others the items values. 64 | """ 65 | if len(collection) == 0: 66 | return collection 67 | first = collection[0] 68 | data = [] 69 | data.append([x for x in first.keys()]) 70 | for o in collection: 71 | data.append([x for x in o.values()]) 72 | return data 73 | 74 | 75 | @staticmethod 76 | def search(collection, search, properties): 77 | """Simple search method, that supports only exact text.""" 78 | # escape characters that need to be escaped 79 | search = re.escape(search) 80 | rx = re.compile(search, re.IGNORECASE) 81 | result = [] 82 | for item in collection: 83 | if properties == "*": 84 | for x in item: 85 | # TODO: support better non-strings with their culture-dependent representations 86 | if rx.search(item[x]): 87 | result.append(item) 88 | break 89 | else: 90 | for p in properties: 91 | if rx.search(item[p]): 92 | result.append(item) 93 | break 94 | return result 95 | -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/clear/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-clear { 2 | 3 | .king-table-container { 4 | border-top: 1px solid #aaa; 5 | } 6 | 7 | .king-table-head { 8 | background-color: #eee; 9 | } 10 | 11 | .filters-region { 12 | background-color: #e6e6e6; 13 | } 14 | 15 | .king-table { 16 | background: #eee; 17 | border-collapse: collapse; 18 | border: none; 19 | font-family: Sans-Serif; 20 | font-size: 12px; 21 | line-height: 17px; 22 | margin-bottom: 10px; 23 | border-bottom: 1px solid #bbb; 24 | } 25 | 26 | .king-table-gallery { 27 | background-color: #EEE; 28 | 29 | li > span { 30 | border-bottom: 1px solid #777777; 31 | } 32 | } 33 | 34 | .king-table caption { 35 | border: 1px solid #d0d0d0; 36 | font-weight: bold; 37 | background: white url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAFxABAQEBAAAAAAAAAAAAAAAAABMBYf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVlMEdegIKgA//2Q==") top left repeat; 38 | } 39 | 40 | .king-table tr td.row-number { 41 | width: 40px; 42 | text-align: center; 43 | } 44 | 45 | .king-table a { 46 | color: #000; 47 | &:hover { 48 | color: #C00; 49 | } 50 | } 51 | 52 | .king-table .king-table tr, .king-table .king-table-head tr { 53 | width: 100%; 54 | border-color: #ccc; 55 | } 56 | 57 | .king-table-body tr:hover:nth-child(even), .king-table-body tr:hover:nth-child(odd) { 58 | background-color: #fefefe; 59 | &.king-table-empty, &.king-table-error { 60 | background: #eee; 61 | } 62 | } 63 | 64 | .king-table .king-table-head tr { 65 | background: #d7d7d7 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAFxABAQEBAAAAAAAAAAAAAAAAABMBYf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVlMEdegIKgA//2Q==") top left repeat-x; 66 | } 67 | 68 | .king-table .king-table-head tr { 69 | height: 18px; 70 | } 71 | 72 | .king-table tr th { 73 | text-align: left; 74 | border: 1px solid #d0d0d0; 75 | border-top: 1px solid #fff; 76 | } 77 | 78 | .king-table tr td { 79 | line-height: 15px; 80 | border-right: 1px solid #ddd; 81 | border-bottom: 1px solid #ddd; 82 | } 83 | 84 | .king-table tr { 85 | th, td { 86 | &.row-number { 87 | border: 1px solid #d0d0d0; 88 | border-top: 1px solid #fff; 89 | background: #d7d7d7 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAFxABAQEBAAAAAAAAAAAAAAAAABMBYf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVlMEdegIKgA//2Q==") top left repeat-x; 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /source/code/scripts/data/csv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Csv format functions. 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | import _ from "../../scripts/utils" 12 | 13 | var TypeHandling = { 14 | allStrings: 1, // all values are treated as allStrings 15 | keepType: 2 // types are kept 16 | }; 17 | 18 | export default { 19 | 20 | default: { 21 | /** 22 | * Whether to add BOM 23 | */ 24 | addBom: true, 25 | /** 26 | * Separator to use 27 | */ 28 | separator: ",", 29 | /** 30 | * Whether to add a separator line at the beginning of the file, or not. 31 | * (May be useful for excel) 32 | */ 33 | addSeparatorLine: false, 34 | /** 35 | * How the types should be handled: allStrings to manage all properties as strings (all will be quoted) 36 | */ 37 | typeHandling: TypeHandling.keepType 38 | }, 39 | 40 | /** 41 | * Serializes the given collection in csv format. 42 | * Assumes that the collection is optimized (the first row contains properties, the other only values) 43 | * 44 | * @param data collection 45 | * @param options 46 | */ 47 | serialize(data, options) { 48 | var o = _.extend({}, this.default, options); 49 | 50 | var re = [], 51 | push = "push", 52 | toString = "toString", 53 | len = "length", 54 | rep = "replace", 55 | test = "test", 56 | sep = o.separator, 57 | dobquote = "\"", 58 | typeHandling = o.typeHandling, 59 | mark = o.addBom ? "\uFEFF" : ""; 60 | //if (o.addSeparatorLine) { 61 | // re[push]("sep=" + sep); 62 | //} 63 | for (var i = 0, l = data[len]; i < l; i++) { 64 | var a = [], row = data[i]; 65 | //assume that the first row contains the columns 66 | for (var k = 0, j = row[len]; k < j; k++) { 67 | var v = row[k]; 68 | if (v instanceof Date) { 69 | // TODO: use date utilities. 70 | // if the value has time, include time; otherwise use only date 71 | v = v.toLocaleString(); 72 | } else { 73 | if (typeof v != "string") { 74 | v = v && v[toString] ? v[toString]() : ""; 75 | } 76 | } 77 | //escape quotes - RFC-4180, paragraph "If double-quotes are used to enclose fields, then a double-quote 78 | //appearing inside a field must be escaped by preceding it with another double quote." 79 | if (/"/[test](v)) 80 | v = v[rep](/"/g, "\"\""); 81 | //https://en.wikipedia.org/wiki/Comma-separated_values 82 | //Fields with embedded commas or double-quote characters must be quoted. (by standard, so even if CsvTypeHandling is different than "AllStrings") 83 | //1997, Ford, E350, "Super, ""luxurious"" truck" 84 | //1997, Ford, E350, "Super, luxurious truck" 85 | if (typeHandling == TypeHandling.allStrings || /"|\n/[test](v) || v.indexOf(sep) > -1) 86 | v = dobquote + v + dobquote; 87 | a[push](v); 88 | } 89 | re[push](a.join(sep)); 90 | } 91 | // the only way to make MS Excel work with UTF-8 and specific separator, 92 | // is to put at the end a tab + separator; and a BOM mark at the beginning 93 | if (o.addSeparatorLine) { 94 | re[push]("\t" + sep); 95 | } 96 | return mark + (re.join("\n")); 97 | } 98 | } -------------------------------------------------------------------------------- /source/code/styles/kingtable/themes/ultramarine/king-table.less: -------------------------------------------------------------------------------- 1 | .theme-ultramarine { 2 | 3 | .king-table-container { 4 | border-top: 1px solid #071436; 5 | } 6 | 7 | .filters-region { 8 | background-color: #275E8E; 9 | border-bottom: 1px solid #275E8E; 10 | } 11 | 12 | .king-table { 13 | background: #0b2258; 14 | border-collapse: collapse; 15 | border-color: #071436; 16 | border: none; 17 | font-family: Sans-Serif; 18 | font-size: 12px; 19 | line-height: 17px; 20 | margin-bottom: 10px; 21 | border-bottom: 1px solid #071436; 22 | tr { 23 | color: #BEE0FF; 24 | } 25 | } 26 | 27 | .king-table-gallery { 28 | background-color: #05385A; 29 | color: #7DB3EF; 30 | li > span { 31 | border-bottom: 1px solid #000; 32 | } 33 | } 34 | 35 | .king-table caption { 36 | border: 1px solid #071436; 37 | font-weight: bold; 38 | background: white url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYB/8QAGRABAQEAAwAAAAAAAAAAAAAAAAEUUVKh/8QAFgEBAQEAAAAAAAAAAAAAAAAABwED/8QAFhEBAQEAAAAAAAAAAAAAAAAAABES/9oADAMBAAIRAxEAPwDNt59ExuvaBBH2kxvoCMa//9k=") top left repeat; 39 | } 40 | 41 | .king-table tr td.row-number { 42 | width:40px; 43 | text-align:center; 44 | color:#071436; 45 | } 46 | 47 | .king-table a { 48 | color: #BEE0FF; 49 | &:focus, &:hover { 50 | color: #BEE0FF; 51 | } 52 | } 53 | 54 | .king-table a:hover { 55 | color: #C00; 56 | } 57 | 58 | .king-table .king-table tr, .king-table .king-table-head tr { 59 | width: 100%; 60 | border-color: #483419; 61 | } 62 | 63 | .king-table .king-table tr { 64 | color:#5498d2; 65 | } 66 | 67 | .king-table-body tr:hover:nth-child(even), .king-table-body tr:hover:nth-child(odd) { 68 | background-color: #071436; 69 | &.king-table-empty, &.king-table-error { 70 | background: #0b2258; 71 | } 72 | } 73 | .king-table .king-table-head tr { 74 | height: 18px; 75 | background: #07578c url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYB/8QAGRABAQEAAwAAAAAAAAAAAAAAAAEUUVKh/8QAFgEBAQEAAAAAAAAAAAAAAAAABwED/8QAFhEBAQEAAAAAAAAAAAAAAAAAABES/9oADAMBAAIRAxEAPwDNt59ExuvaBBH2kxvoCMa//9k=") top left repeat-x; 76 | } 77 | 78 | .king-table tr { 79 | th { 80 | text-align: left; 81 | border: 1px solid #09165a; 82 | border-top: 1px solid #6080bd; 83 | } 84 | td { 85 | line-height: 15px; 86 | border-right: 1px solid #09165a; 87 | border-bottom: 1px solid #09165a; 88 | } 89 | th, td { 90 | &.row-number { 91 | background: #07578c url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYB/8QAGRABAQEAAwAAAAAAAAAAAAAAAAEUUVKh/8QAFgEBAQEAAAAAAAAAAAAAAAAABwED/8QAFhEBAQEAAAAAAAAAAAAAAAAAABES/9oADAMBAAIRAxEAPwDNt59ExuvaBBH2kxvoCMa//9k=") top left repeat-x; 92 | } 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /servers/flask/bll/collectionmanager.py: -------------------------------------------------------------------------------- 1 | """ 2 | * KingTable 2.0.0 example server 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2017, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | * 11 | * This file contains the business logic to work with example collections. 12 | """ 13 | import os 14 | import json 15 | from core.lists.listutils import ListUtils 16 | from core.literature.scribe import Scribe 17 | 18 | 19 | class CollectionManager: 20 | """Provides methods to work with underlying collections; read from static json structures""" 21 | def __init__(self, file_path): 22 | self.file_path = file_path 23 | self._collection = None 24 | 25 | def get_catalog(self, data): 26 | if data is None: 27 | raise TypeError 28 | 29 | # timestamp = data["timestamp"] # timestamp of the first time a page was required 30 | page_number = int(data.get("page")) 31 | page_size = int(data.get("size")) 32 | search = data.get("search") 33 | sort_by = data.get("sortBy") 34 | # get the collection 35 | collection, total_rows = self.get_catalog_page(page_number, page_size, search, sort_by) 36 | # optimize the collection 37 | collection = ListUtils.optimize_list(collection) 38 | result = {"subset": collection, "page": page_number, "total": total_rows} 39 | return result 40 | 41 | def get_data_path(self): 42 | root_dir = os.path.dirname(os.getcwd()) 43 | rel = os.path.join(root_dir, "flask", "data", self.file_path) 44 | return os.path.abspath(rel) 45 | 46 | def get_catalog_page(self, page_number, page_size, search, sort_by): 47 | """Gets a catalog page of the managed collection.""" 48 | collection = self.get_all() 49 | if search is not None and search != "": 50 | """ 51 | # NB: if a search filter is provided by the client; then the server side should: 52 | # 1. search inside the properties we know should be searched into, and skim the results. 53 | # 2. set the total items count as the total of items that respond to the search. 54 | # 3. return the full set of items that respect the search criteria. 55 | # 56 | # As a side note, keep in mind that some properties, like dates and decimal, should be evaluated for their 57 | # culture-dependent string representations of values; not their intrinsic values. 58 | # Example: a date in UK English can be dd/mm/yyyy; in US English can be mm/dd/yyyy. 59 | # A well designed search implementation adapts to the current user's culture. 60 | """ 61 | collection = ListUtils.search(collection, search, "*") 62 | 63 | # NB: if an order by is defined; we need to order before paginating results! 64 | if sort_by: 65 | collection = ListUtils.sort_by(collection, sort_by) 66 | 67 | # return a paginated result to the client: 68 | skip = ((page_number-1)*page_size) if page_number > 0 else 0 69 | 70 | # the client needs to know the total items count, in order to build the pagination 71 | total_items_count = len(collection) 72 | 73 | result = ListUtils.sampling(collection, skip, page_size) 74 | # return the collection and the count of results: 75 | return result, total_items_count 76 | 77 | def get_all(self): 78 | """Gets the complete list of colors.""" 79 | if self._collection is None: 80 | file_path = self.get_data_path() 81 | 82 | # read the colors.json file (this simulates the data access, without data access layer) 83 | file_data = Scribe.read(file_path) 84 | self._collection = json.loads(file_data) 85 | 86 | return self._collection 87 | -------------------------------------------------------------------------------- /source/code/scripts/tables/kingtable.xlsx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * KingTable plugin for Excel client side export using SheetJS/js-xlsx library 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | import raise from "../../scripts/raise" 12 | var und = "undefined"; 13 | 14 | // KingTable is immediately necessary 15 | if (typeof KingTable == und) raise(39, "KingTable is not defined in global namespace"); 16 | 17 | var _ = KingTable.Utils; 18 | var dateValue = KingTable.DateUtils.toExcelDateValue; 19 | 20 | function sheetFromArrayOfArrays(data, opts) { 21 | var ws = {}; 22 | var range = {s: {c:10000000, r:10000000}, e: {c:0, r:0 }}; 23 | for(var R = 0; R != data.length; ++R) { 24 | for(var C = 0; C != data[R].length; ++C) { 25 | if(range.s.r > R) range.s.r = R; 26 | if(range.s.c > C) range.s.c = C; 27 | if(range.e.r < R) range.e.r = R; 28 | if(range.e.c < C) range.e.c = C; 29 | var value = data[R][C]; 30 | var cell = {v: value }; 31 | if(cell.v == null) continue; 32 | var cell_ref = XLSX.utils.encode_cell({c:C,r:R}); 33 | 34 | if (typeof value == "number") { 35 | cell.t = "n"; 36 | // TODO: support desired precision of numbers 37 | //cell.z = ... 38 | } 39 | else if (typeof value == "boolean") cell.t = "b"; 40 | else if (value instanceof Date) { 41 | cell.t = "n"; cell.z = XLSX.SSF._table[14]; 42 | cell.v = dateValue(cell.v); 43 | } 44 | else cell.t = "s"; 45 | 46 | ws[cell_ref] = cell; 47 | } 48 | } 49 | if(range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range); 50 | return ws; 51 | } 52 | 53 | function Workbook() { 54 | if(!(this instanceof Workbook)) return new Workbook(); 55 | this.SheetNames = []; 56 | this.Sheets = {}; 57 | } 58 | 59 | function s2ab(s) { 60 | var buf = new ArrayBuffer(s.length); 61 | var view = new Uint8Array(buf); 62 | for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; 63 | return buf; 64 | } 65 | 66 | function handler(itemsToDisplay) { 67 | // at this point, dependencies are required 68 | if (typeof XLSX == und) raise(2, "Missing dependency: js-xlsx"); 69 | if (typeof Blob == und) raise(2, "Missing dependency: Blob"); 70 | 71 | var self = this, o = self.options; 72 | var data = self.optimizeCollection(itemsToDisplay, null, { 73 | format: o.excelAllStrings 74 | }); 75 | var wb = new Workbook(), ws = sheetFromArrayOfArrays(data); 76 | 77 | // add worksheet to workbook 78 | var wsName = o.excelWorkbookName; 79 | wb.SheetNames.push(wsName); 80 | wb.Sheets[wsName] = ws; 81 | 82 | // columns auto width 83 | // for each column, get the cell width 84 | var padding = o.excelCellPadding, minCellWidth = o.excelCellMinWidth; 85 | var cols = _.cols(data), 86 | wscols = _.map(cols, x => { 87 | return {wch:Math.max(_.max(x, y => { return y.length; }), minCellWidth) + padding}; 88 | }); 89 | ws["!cols"] = wscols; 90 | 91 | var wbout = XLSX.write(wb, {bookType:"xlsx", bookSST:true, type: "binary"}); 92 | return new Blob([s2ab(wbout)], {type:"application/octet-stream"}); 93 | } 94 | 95 | // regional settings 96 | KingTable.regional.en.exportFormats.xlsx = "Excel (.xlsx)"; 97 | 98 | // extend options 99 | KingTable.defaults.excelWorkbookName = "data"; 100 | KingTable.defaults.excelCellPadding = 0; 101 | KingTable.defaults.excelCellMinWidth = 0; 102 | KingTable.defaults.excelAllStrings = false; 103 | 104 | // add export format for client side Xlsx 105 | KingTable.defaults.exportFormats.unshift({ 106 | name: "Xlsx", 107 | format: "xlsx", 108 | type: "application/octet-stream", 109 | cs: true, // client side 110 | handler: handler 111 | }); 112 | 113 | -------------------------------------------------------------------------------- /source/code/scripts/menus/kingtable.menu.html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * KingTable menu builder function. 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | import _ from "../../scripts/utils" 12 | import $ from "../../scripts/dom" 13 | import { ArgumentNullException } from "../../scripts/exceptions" 14 | import { VHtmlElement, VTextElement, VCommentElement, VWrapperElement } from "../../scripts/data/html" 15 | 16 | function buildMenuItemCaret() { 17 | return new VHtmlElement("span", { 18 | "class": "oi", 19 | "data-glyph": "caret-right" 20 | }); 21 | } 22 | 23 | function menuBuilder(menus) { 24 | if (!menus) throw "missing menus"; 25 | if (_.isPlainObject(menus)) return menuBuilder([menus]); 26 | if (!_.isArray(menus) || !menus.length) throw "missing menus"; 27 | //normalize schema, if needed 28 | var first = menus[0]; 29 | if (!first.items && first.menu) { 30 | menus = [{ items: menus }]; 31 | } 32 | var a = _.map(menus, menu => { 33 | var items = menu.items; 34 | return new VHtmlElement("ul", { 35 | "id": menu.id, 36 | "class": "ug-menu" 37 | }, items ? _.map(items, x => { 38 | if (!x) return; 39 | return menuItemBuilder(x); 40 | }) : null); 41 | }); 42 | return new VWrapperElement(a); 43 | } 44 | 45 | function menuItemCaret() { 46 | return new VHtmlElement("span", { 47 | "class": "oi", 48 | "data-glyph": "caret-right" 49 | }) 50 | } 51 | 52 | function menuItemBuilder(options) { 53 | var o = options || {}; 54 | var type = o.type, 55 | href = o.href, 56 | classes = [], 57 | name = o.name, 58 | submenu = o.menu, 59 | attr = o.attr, 60 | caret = submenu ? buildMenuItemCaret() : null, 61 | children = [], 62 | el, 63 | nameTextEl = new VTextElement(name || ""); 64 | if (attr && attr.css && !attr["class"]) { 65 | // allow to use attribute css for class 66 | attr["class"] = attr.css; 67 | delete attr.css; 68 | } 69 | switch (type) { 70 | case "checkbox": 71 | var cid = _.uniqueId("mnck-"); 72 | var checked = o.checked ? true : undefined; 73 | el = new VWrapperElement([new VHtmlElement("input", _.extend({}, attr, { 74 | "id": cid, 75 | "type": "checkbox", 76 | "checked": checked 77 | })), new VHtmlElement("label", { 78 | "for": cid 79 | }, nameTextEl)]); 80 | break; 81 | case "radio": 82 | var value = o.value; 83 | if (!value) throw new Error("missing 'value' for radio menu item"); 84 | var cid = _.uniqueId("mnrd-"); 85 | var checked = o.checked ? true : undefined; 86 | el = new VWrapperElement([new VHtmlElement("input", _.extend({}, attr, { 87 | "id": cid, 88 | "type": "radio", 89 | "checked": checked, 90 | "value": value 91 | })), new VHtmlElement("label", { 92 | "for": cid 93 | }, nameTextEl)]); 94 | break; 95 | default: 96 | if (href) { 97 | el = new VHtmlElement("a", _.extend({ 98 | "href": href 99 | }, attr), [nameTextEl, caret]); 100 | } else { 101 | el = new VHtmlElement("span", _.extend({ 102 | "tabindex": "0" 103 | }, attr), [nameTextEl, caret]); 104 | } 105 | break; 106 | } 107 | // name element 108 | children.push(el); 109 | 110 | if (submenu) { 111 | children.push(menuBuilder(submenu)); 112 | } 113 | 114 | return new VHtmlElement("li", { 115 | "id": o.id, 116 | "class": submenu ? "ug-submenu" : undefined 117 | }, children); 118 | } 119 | 120 | export { menuBuilder, menuItemBuilder } -------------------------------------------------------------------------------- /source/code/scripts/data/lru.js: -------------------------------------------------------------------------------- 1 | /** 2 | * LRU cache. 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | import _ from "../../scripts/utils" 12 | import json from "../../scripts/data/json" 13 | import { 14 | ArgumentNullException 15 | } from "../../scripts/exceptions" 16 | 17 | function getStorage(type) { 18 | if (_.isObject(type)) return type; 19 | switch (type) { 20 | case 1: 21 | return localStorage; 22 | case 2: 23 | return sessionStorage; 24 | default: 25 | return sessionStorage; 26 | } 27 | } 28 | 29 | export default { 30 | 31 | get: function (name, condition, type, details) { 32 | if (condition === true) { 33 | details = true; 34 | condition = undefined; 35 | } 36 | if (type === true) { 37 | details = true; 38 | type = undefined; 39 | } 40 | var storage = getStorage(type); 41 | var i, o = storage.getItem(name); 42 | if (o) { 43 | try { 44 | o = json.parse(o); 45 | } catch (ex) { 46 | storage.removeItem(name); 47 | return; 48 | } 49 | // set timestamp in each item data 50 | if (!condition) 51 | return _.map(o, x => { return details ? x : x.data; }); 52 | var toRemove = [], toReturn; 53 | var l = o.length; 54 | for (i = 0; i < l; i++) { 55 | var ca = o[i]; 56 | if (!ca) continue; 57 | var data = ca.data, expiration = data.expiration; 58 | if (_.isNumber(expiration) && expiration > 0) { 59 | // is the data expired? 60 | if (new Date().getTime() > expiration) { 61 | // the item expired, it should be removed 62 | toRemove.push(ca); 63 | // skip 64 | continue; 65 | } 66 | } 67 | if (condition(data)) { 68 | toReturn = details ? ca : data; 69 | } 70 | } 71 | if (toRemove.length) { 72 | this.remove(name, x => { 73 | return toRemove.indexOf(x) > -1; 74 | }); 75 | } 76 | return toReturn; 77 | } 78 | }, 79 | 80 | /** 81 | * Removes an item from the cache, eventually using a condition. 82 | */ 83 | remove: function (name, condition, type) { 84 | var storage = getStorage(type); 85 | if (!condition) { 86 | storage.removeItem(name); 87 | return; 88 | } 89 | var i, o = storage.getItem(name); 90 | 91 | if (o) { 92 | try { 93 | o = json.parse(o); 94 | } catch (ex) { 95 | storage.removeItem(name); 96 | return; 97 | } 98 | var l = o.length; 99 | var toKeep = []; 100 | for (i = 0; i < l; i++) { 101 | var ca = o[i]; 102 | if (!ca) continue; 103 | var data = ca.data; 104 | if (!condition(data)) { 105 | // keep this item 106 | toKeep.push(ca); 107 | } 108 | } 109 | return storage.setItem(name, json.compose(toKeep)); 110 | } 111 | }, 112 | 113 | set: function (name, value, maxSize, maxAge, type) { 114 | if (!_.isNumber(maxSize)) 115 | maxSize = 10; 116 | if (!_.isNumber(maxAge)) 117 | maxAge = -1; 118 | var storage = getStorage(type); 119 | var ts = new Date().getTime(), exp = maxAge > 0 ? ts + maxAge : -1; 120 | var data = { 121 | ts: ts, 122 | expiration: exp, 123 | data: value 124 | }; 125 | var o = storage.getItem(name); 126 | if (o) { 127 | try { 128 | o = json.parse(o); 129 | } catch (ex) { 130 | storage.removeItem(name); 131 | return this.set(name, value, maxSize); 132 | } 133 | if (o.length >= maxSize) { 134 | // remove oldest item 135 | o.shift(); 136 | } 137 | o.push(data); 138 | } else { 139 | // new object 140 | o = [{ 141 | ts: ts, 142 | expiration: exp, 143 | data: value 144 | }]; 145 | } 146 | return storage.setItem(name, json.compose(o)); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /source/code/tests/data/colors-part.js: -------------------------------------------------------------------------------- 1 | /** 2 | * KingTable colors test data. 3 | * https://github.com/RobertoPrevato/KingTable 4 | * 5 | * Copyright 2018, Roberto Prevato 6 | * https://robertoprevato.github.io 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | export default [ 12 | { 13 | "red": "0%", 14 | "hsvSaturation": "100%", 15 | "blue": "73%", 16 | "hslSaturation": "100%", 17 | "hsvValue": "73%", 18 | "hue": "217°", 19 | "hslLight": "37%", 20 | "green": "28%", 21 | "name": "Absolute Zero", 22 | "color": "#0048BA" 23 | }, 24 | { 25 | "red": "69%", 26 | "hsvSaturation": "86%", 27 | "blue": "10%", 28 | "hslSaturation": "76%", 29 | "hsvValue": "75%", 30 | "hue": "65°", 31 | "hslLight": "43%", 32 | "green": "75%", 33 | "name": "Acid green", 34 | "color": "#B0BF1A" 35 | }, 36 | { 37 | "red": "49%", 38 | "hsvSaturation": "47%", 39 | "blue": "91%", 40 | "hslSaturation": "70%", 41 | "hsvValue": "91%", 42 | "hue": "206°", 43 | "hslLight": "70%", 44 | "green": "73%", 45 | "name": "Aero", 46 | "color": "#7CB9E8" 47 | }, 48 | { 49 | "red": "79%", 50 | "hsvSaturation": "21%", 51 | "blue": "90%", 52 | "hslSaturation": "100%", 53 | "hsvValue": "100%", 54 | "hue": "151°", 55 | "hslLight": "89%", 56 | "green": "100%", 57 | "name": "Aero blue", 58 | "color": "#C9FFE5" 59 | }, 60 | { 61 | "red": "70%", 62 | "hsvSaturation": "31%", 63 | "blue": "75%", 64 | "hslSaturation": "31%", 65 | "hsvValue": "75%", 66 | "hue": "288°", 67 | "hslLight": "63%", 68 | "green": "52%", 69 | "name": "African violet", 70 | "color": "#B284BE" 71 | }, 72 | { 73 | "red": "36%", 74 | "hsvSaturation": "45%", 75 | "blue": "66%", 76 | "hslSaturation": "30%", 77 | "hsvValue": "66%", 78 | "hue": "204°", 79 | "hslLight": "51%", 80 | "green": "54%", 81 | "name": "Air Force blue (RAF)", 82 | "color": "#5D8AA8" 83 | }, 84 | { 85 | "red": "0%", 86 | "hsvSaturation": "100%", 87 | "blue": "56%", 88 | "hslSaturation": "100%", 89 | "hsvValue": "56%", 90 | "hue": "220°", 91 | "hslLight": "28%", 92 | "green": "19%", 93 | "name": "Air Force blue (USAF)", 94 | "color": "#00308F" 95 | }, 96 | { 97 | "red": "45%", 98 | "hsvSaturation": "41%", 99 | "blue": "76%", 100 | "hslSaturation": "39%", 101 | "hsvValue": "76%", 102 | "hue": "205°", 103 | "hslLight": "60%", 104 | "green": "63%", 105 | "name": "Air superiority blue", 106 | "color": "#72A0C1" 107 | }, 108 | { 109 | "red": "69%", 110 | "hsvSaturation": "100%", 111 | "blue": "16%", 112 | "hslSaturation": "100%", 113 | "hsvValue": "69%", 114 | "hue": "346°", 115 | "hslLight": "34%", 116 | "green": "0%", 117 | "name": "Alabama crimson", 118 | "color": "#AF002A" 119 | }, 120 | { 121 | "red": "94%", 122 | "hsvSaturation": "6%", 123 | "blue": "100%", 124 | "hslSaturation": "100%", 125 | "hsvValue": "100%", 126 | "hue": "208°", 127 | "hslLight": "97%", 128 | "green": "97%", 129 | "name": "Alice blue", 130 | "color": "#F0F8FF" 131 | }, 132 | { 133 | "red": "52%", 134 | "hsvSaturation": "99%", 135 | "blue": "1%", 136 | "hslSaturation": "98%", 137 | "hsvValue": "87%", 138 | "hue": "85°", 139 | "hslLight": "44%", 140 | "green": "87%", 141 | "name": "Alien Armpit", 142 | "color": "#84DE02" 143 | }, 144 | { 145 | "red": "89%", 146 | "hsvSaturation": "83%", 147 | "blue": "21%", 148 | "hslSaturation": "77%", 149 | "hsvValue": "89%", 150 | "hue": "355°", 151 | "hslLight": "52%", 152 | "green": "15%", 153 | "name": "Alizarin crimson", 154 | "color": "#E32636" 155 | }, 156 | { 157 | "red": "77%", 158 | "hsvSaturation": "92%", 159 | "blue": "6%", 160 | "hslSaturation": "85%", 161 | "hsvValue": "77%", 162 | "hue": "27°", 163 | "hslLight": "42%", 164 | "green": "38%", 165 | "name": "Alloy orange", 166 | "color": "#C46210" 167 | } 168 | ]; 169 | -------------------------------------------------------------------------------- /dist/styles/fonts/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | -------------------------------------------------------------------------------- /source/code/styles/openicon/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | --------------------------------------------------------------------------------