From 30ef960ad7238ab5d53a249ecd7da11d681f4249 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Tue, 26 May 2020 08:59:32 -0400 Subject: [PATCH 1/6] Fixes dense column-indices. Adds `DEBUG` env flag, fixes missing Material fonts. --- .eslintrc.json | 3 +- README.md | 26 +- examples/canvas_data_model.html | 53 +- examples/perspective.html | 31 +- package.json | 5 +- src/js/table.js | 3 +- src/js/thead.js | 7 +- src/less/material.less | 2 + test/two_billion_rows/metadata.test.js | 6 +- webpack.config.js | 2 +- yarn.lock | 873 ++----------------------- 11 files changed, 146 insertions(+), 865 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index c9ecad2e..d1d87bff 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,8 @@ { "parser": "babel-eslint", "plugins": [ - "prettier" + "prettier", + "html" ], "env": { "browser": true, diff --git a/README.md b/README.md index 442e7e33..aaf5f20c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ named ``, which renders a regular HTML `` to a `fixed` position within a scollable viewport. Only visible cells are rendered and queried from a natively `async` virtual data model, making `regular-table` ideal for enormous or remote data -sets. Use it to build high-performance Data Grids, +sets. Use it to build Data Grids, Spreadsheets, Pivot Tables, File Trees, or anytime you need: * Just a regular `
`. @@ -106,9 +106,7 @@ Here's a simple _virtual_ data model for this example, the function `getDataSlice()`. This function is called by your `` whenever it needs more data, with coordinate arguments, `(x0, y0)` to `(x1, y1)`. Only this region is needed to render the viewport, so `getDataSlice()` returns -this rectangular `slice` of `DATA`, as well as overall dimensions the overall -dimensions of `DATA` itself ( `num_rows`, `num_columns`), for sizing the -virtual scroll area: +this rectangular `slice` of `DATA`: ```javascript function getDataSlice(x0, y0, x1, y1) { @@ -126,6 +124,26 @@ function getDataSlice(x0, y0, x1, y1) { } ``` +For the window (0, 0) to (2, 2), `getDataSlice()` would generate an Object +like this, containing the `data` slice, as well as the overall dimensions of +`DATA` itself ( `num_rows`, `num_columns`), for sizing the scroll area, and +`column_indices` which generate `` of `
` column headers in a `fixed` position. + +```json +{ + "num_rows": 26, + "num_columns": 3, + "data": [ + [0, 1], + ["A", "B"] + ], + "column_indices": [ + ["Column 1 (number)"], + ["Column 2 (string)"] + ] +} +``` + To render this virtual data model to a regular HTML ``, all you need to do is register this data model via the `setDataModel()` method: diff --git a/examples/canvas_data_model.html b/examples/canvas_data_model.html index 933d1950..ec505dcf 100644 --- a/examples/canvas_data_model.html +++ b/examples/canvas_data_model.html @@ -40,16 +40,19 @@ max-width: 20px !important; padding: 0px; } - th { + thead tr:last-child th { transform: rotate(-90deg); - transform-origin: 30% 92%; - color: white; - font-family: monospace; - text-align: left !important; + transform-origin: 30% 90%; border-bottom-width: 0px !important; + border-right-width: 0px !important; height: 40px !important; + text-align: left !important; border-left: 1px solid white; } + th { + color: white; + font-family: monospace; + } regular-table { position: absolute; top: 0; @@ -94,45 +97,46 @@ diff --git a/examples/perspective.html b/examples/perspective.html index 199c0c5e..74f307cd 100644 --- a/examples/perspective.html +++ b/examples/perspective.html @@ -22,8 +22,8 @@ diff --git a/package.json b/package.json index 0e80d7fb..277822c1 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "build:less": "lessc src/less/material.less dist/css/material.css", "build": "npm-run-all build:static build:babel build:webpack build:less", "clean": "rimraf dist", - "lint": "eslint src", - "fix": "eslint src --fix", + "lint": "eslint src examples/*.html", + "fix": "eslint src examples/*.html --fix", "test": "yarn jest --verbose", "start": "http-server", "watch:babel": "babel src/js --source-maps --watch --out-dir dist/esm", @@ -56,6 +56,7 @@ "babel-plugin-transform-custom-element-classes": "^0.1.0", "cpx": "^1.5.0", "eslint": "^7.1.0", + "eslint-plugin-html": "^6.0.2", "eslint-plugin-prettier": "^3.1.3", "http-server": "^0.12.3", "jest": "^26.0.1", diff --git a/src/js/table.js b/src/js/table.js index 80186d89..6413bcfa 100644 --- a/src/js/table.js +++ b/src/js/table.js @@ -67,6 +67,7 @@ export class RegularTableViewModel { const {data, row_indices, column_indices, __id_column: id_column} = await view(viewport.start_col, viewport.start_row, viewport.end_col, viewport.end_row); const {start_row: ridx_offset = 0, start_col: cidx_offset = 0} = viewport; const depth = config.row_pivots.length; + view_cache.config.column_pivots = Array.from(Array(column_indices[0]?.length - 1 || 0).keys()); const view_state = { viewport_width: 0, selected_id, @@ -118,7 +119,7 @@ export class RegularTableViewModel { data[dcidx] = new_col.data[0]; column_indices[dcidx] = new_col.column_indices[0]; } - const column_name = column_indices[dcidx][column_indices[dcidx].length - 1]; + const column_name = column_indices[dcidx]; const type = column_path_2_type(schema, column_name); const column_data = data[dcidx]; const column_state = { diff --git a/src/js/thead.js b/src/js/thead.js index 4a44f505..83d0ead9 100644 --- a/src/js/thead.js +++ b/src/js/thead.js @@ -101,9 +101,8 @@ export class RegularHeaderViewModel extends ViewModel { _group_header_cache = []; _offset_cache = []; - draw(config, alias, column_path, type, cidx) { + draw(config, alias, parts, type, cidx) { const header_levels = config.column_pivots.length + 1; - let parts = column_path.split?.("|"); let th, column_name, is_new_group = false; @@ -117,7 +116,7 @@ export class RegularHeaderViewModel extends ViewModel { th.setAttribute("colspan", this._group_header_cache[d][2]); } else { th = this._draw_group_th(this._offset_cache, d, column_name, []); - const metadata = this._draw_group(column_path, column_name, type, th); + const metadata = this._draw_group(parts, column_name, type, th); this._group_header_cache[d] = [metadata, th, 1]; is_new_group = true; } @@ -132,7 +131,7 @@ export class RegularHeaderViewModel extends ViewModel { // Update the group header's metadata such that each group // header has the same metadata coordinates of its rightmost // column. - const metadata = this._draw_th(alias || column_path, column_name, type, th); + const metadata = this._draw_th(alias || parts, column_name, type, th); metadata.vcidx = vcidx; metadata.cidx = cidx; for (const [group_meta] of this._group_header_cache) { diff --git a/src/less/material.less b/src/less/material.less index 5b259401..b48a3bea 100644 --- a/src/less/material.less +++ b/src/less/material.less @@ -9,6 +9,8 @@ */ @import (css) url("https://fonts.googleapis.com/css?family=Open+Sans"); +@import (css) url("https://fonts.googleapis.com/css?family=Material+Icons"); +@import (css) url("https://fonts.googleapis.com/css?family=Roboto+Mono"); @row-height: 19px; diff --git a/test/two_billion_rows/metadata.test.js b/test/two_billion_rows/metadata.test.js index 5badfd61..8e1ecea4 100644 --- a/test/two_billion_rows/metadata.test.js +++ b/test/two_billion_rows/metadata.test.js @@ -23,7 +23,7 @@ describe("two_billion_rows.html Metadata", () => { }, table); expect(JSON.parse(meta)).toEqual({ cidx: 0, - column: "Column 0", + column: ["Column 0"], is_open: false, ridx: 0, size_key: "Column 0|undefined", @@ -48,7 +48,7 @@ describe("two_billion_rows.html Metadata", () => { }, table); expect(JSON.parse(meta)).toEqual({ cidx: 16, - column: "Column 16", + column: ["Column 16"], is_open: false, ridx: 0, size_key: "Column 16|undefined", @@ -74,7 +74,7 @@ describe("two_billion_rows.html Metadata", () => { }, table); expect(JSON.parse(meta)).toEqual({ cidx: 0, - column: "Column 0", + column: ["Column 0"], is_open: false, ridx: 200002, size_key: "Column 0|undefined", diff --git a/webpack.config.js b/webpack.config.js index 70d8477e..6ca6b48d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,7 @@ const path = require("path"); module.exports = { entry: "./src/js/index.js", - mode: "production", + mode: process.env.DEBUG ? "development" : "production", devtool: "source-map", module: { rules: [ diff --git a/yarn.lock b/yarn.lock index ad0a508e..0a2fe729 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1374,11 +1374,6 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= - ansi-escapes@^4.2.1: version "4.3.1" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" @@ -1528,11 +1523,6 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types@0.9.6: - version "0.9.6" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" - integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk= - astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -1565,18 +1555,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^6.3.1: - version "6.7.7" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" - integrity sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ= - dependencies: - browserslist "^1.7.6" - caniuse-db "^1.0.30000634" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^5.2.16" - postcss-value-parser "^3.2.3" - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -1758,11 +1736,6 @@ babylon@^6.18.0: resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== -balanced-match@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" - integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= - balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -1955,14 +1928,6 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" - integrity sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk= - dependencies: - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" - browserslist@^4.11.1, browserslist@^4.8.5: version "4.12.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d" @@ -2063,14 +2028,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -2081,21 +2038,6 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== -caniuse-api@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" - integrity sha1-tTTnxzTE+B7F++isoq0kNUuWLGw= - dependencies: - browserslist "^1.3.6" - caniuse-db "^1.0.30000529" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30001064" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001064.tgz#3f18d321f7c21d779d2ba915459bb3e39105b969" - integrity sha512-CnaMcXiC6QFvFv/UsNI/T9A7omMszNrueSoJ8RbIZmwx6v53xzjbfafSx4okDjp/LkFSMSL64gn/0aDPw6ox8g== - caniuse-lite@^1.0.30001043: version "1.0.30001064" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001064.tgz#a0f49689119ba08943b09968e118faf3f645add0" @@ -2234,13 +2176,6 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -clap@^1.0.9: - version "1.2.3" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" - integrity sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA== - dependencies: - chalk "^1.1.3" - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2251,13 +2186,6 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -clean-css@4.2.x: - version "4.2.3" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" - integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== - dependencies: - source-map "~0.6.0" - cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -2299,12 +2227,7 @@ clone-deep@^0.2.4: lazy-cache "^1.0.3" shallow-clone "^0.1.2" -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -clone@^2.1.1, clone@^2.1.2: +clone@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= @@ -2314,13 +2237,6 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= -coa@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" - integrity sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0= - dependencies: - q "^1.1.2" - collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -2334,7 +2250,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.3.0, color-convert@^1.9.0: +color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -2353,46 +2269,16 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0, color-name@~1.1.4: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" - integrity sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE= - dependencies: - color-name "^1.0.0" - -color@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" - integrity sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q= - dependencies: - clone "^1.0.2" - color-convert "^1.3.0" - color-string "^0.3.0" - -colormin@^1.0.5: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" - integrity sha1-6i90IKcrlogaOKrlnsEkpvcpgTM= - dependencies: - color "^0.11.0" - css-color-names "0.0.4" - has "^1.0.1" - colors@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= - combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2400,11 +2286,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@2.17.x: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== - commander@^2.11.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2420,11 +2301,6 @@ commander@^4.0.1: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2597,91 +2473,6 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -css-color-names@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= - -css-loader@^0.28.7: - version "0.28.11" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.11.tgz#c3f9864a700be2711bb5a2462b2389b1a392dab7" - integrity sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg== - dependencies: - babel-code-frame "^6.26.0" - css-selector-tokenizer "^0.7.0" - cssnano "^3.10.0" - icss-utils "^2.1.0" - loader-utils "^1.0.2" - lodash.camelcase "^4.3.0" - object-assign "^4.1.1" - postcss "^5.0.6" - postcss-modules-extract-imports "^1.2.0" - postcss-modules-local-by-default "^1.2.0" - postcss-modules-scope "^1.1.0" - postcss-modules-values "^1.3.0" - postcss-value-parser "^3.3.0" - source-list-map "^2.0.0" - -css-selector-tokenizer@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz#11e5e27c9a48d90284f22d45061c303d7a25ad87" - integrity sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw== - dependencies: - cssesc "^3.0.0" - fastparse "^1.1.2" - regexpu-core "^4.6.0" - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -cssnano@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" - integrity sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg= - dependencies: - autoprefixer "^6.3.1" - decamelize "^1.1.2" - defined "^1.0.0" - has "^1.0.1" - object-assign "^4.0.1" - postcss "^5.0.14" - postcss-calc "^5.2.0" - postcss-colormin "^2.1.8" - postcss-convert-values "^2.3.4" - postcss-discard-comments "^2.0.4" - postcss-discard-duplicates "^2.0.1" - postcss-discard-empty "^2.0.1" - postcss-discard-overridden "^0.1.1" - postcss-discard-unused "^2.2.1" - postcss-filter-plugins "^2.0.0" - postcss-merge-idents "^2.1.5" - postcss-merge-longhand "^2.0.1" - postcss-merge-rules "^2.0.3" - postcss-minify-font-values "^1.0.2" - postcss-minify-gradients "^1.0.1" - postcss-minify-params "^1.0.4" - postcss-minify-selectors "^2.0.4" - postcss-normalize-charset "^1.1.0" - postcss-normalize-url "^3.0.7" - postcss-ordered-values "^2.1.0" - postcss-reduce-idents "^2.2.2" - postcss-reduce-initial "^1.0.0" - postcss-reduce-transforms "^1.0.3" - postcss-svgo "^2.1.1" - postcss-unique-selectors "^2.0.2" - postcss-value-parser "^3.2.3" - postcss-zindex "^2.0.1" - -csso@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" - integrity sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U= - dependencies: - clap "^1.0.9" - source-map "^0.5.3" - cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" @@ -2749,7 +2540,7 @@ debug@^3.0.0, debug@^3.1.1: dependencies: ms "^2.1.1" -decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2803,11 +2594,6 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -2852,11 +2638,24 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-serializer@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + domexception@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" @@ -2864,6 +2663,22 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +domhandler@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.0.0.tgz#51cd13efca31da95bbb0c5bee3a48300e333b3e9" + integrity sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw== + dependencies: + domelementtype "^2.0.1" + +domutils@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.1.0.tgz#7ade3201af43703fde154952e3a868eb4b635f16" + integrity sha512-CD9M0Dm1iaHfQ1R/TI+z3/JWp/pgub0j4jIQKH89ARR4ATAV2nbaOQS5XxU9maJP5jHaPdDDQSEHuE2UmpUTKg== + dependencies: + dom-serializer "^0.2.1" + domelementtype "^2.0.1" + domhandler "^3.0.0" + duplexer@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" @@ -2904,7 +2719,7 @@ ejs@^3.0.2: dependencies: jake "^10.6.1" -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.413: +electron-to-chromium@^1.3.413: version "1.3.451" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.451.tgz#0c075af3e2f06d706670bde0279432802ca8c83f" integrity sha512-2fvco0F2bBIgqzO8GRP0Jt/91pdrf9KfZ5FsmkYkjERmIJG585cFeFZV4+CO6oTmU3HmCTgfcZuEa7kW8VUh3A== @@ -2967,6 +2782,11 @@ enhanced-resolve@^4.1.0: memory-fs "^0.5.0" tapable "^1.0.0" +entities@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.2.tgz#ac74db0bba8d33808bbf36809c3a5c3683531436" + integrity sha512-dmD3AvJQBUjKpcNkoqr+x+IF0SdRtPz9Vk0uTy4yWqga9ibB6s4v++QFWNohjiUGoMlF552ZvNyXDxz5iW0qmw== + errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -3007,14 +2827,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es6-templates@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/es6-templates/-/es6-templates-0.2.3.tgz#5cb9ac9fb1ded6eb1239342b81d792bbb4078ee4" - integrity sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ= - dependencies: - recast "~0.11.12" - through "~2.3.6" - escape-html@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -3042,6 +2854,13 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" +eslint-plugin-html@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-6.0.2.tgz#fcbd293e218d03dd72c147fc999d185c6f5989fe" + integrity sha512-Ik/z32UteKLo8GEfwNqVKcJ/WOz/be4h8N5mbMmxxnZ+9aL9XczOXQFz/bGu+nAGVoRg8CflldxJhONFpqlrxw== + dependencies: + htmlparser2 "^4.1.0" + eslint-plugin-prettier@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz#ae116a0fc0e598fdae48743a4430903de5b4e6ca" @@ -3128,21 +2947,11 @@ espree@^7.0.0: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" -esprima@^2.6.0: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= - esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esprima@~3.1.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= - esquery@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" @@ -3377,11 +3186,6 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fastparse@^1.1.1, fastparse@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" - integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== - fb-watchman@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" @@ -3544,11 +3348,6 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== -flatten@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" - integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== - flush-write-stream@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -3862,11 +3661,6 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3913,7 +3707,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1, has@^1.0.3: +has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -3937,7 +3731,7 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -he@1.2.x, he@^1.1.1: +he@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -3963,11 +3757,6 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -3980,36 +3769,15 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-loader-jest@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/html-loader-jest/-/html-loader-jest-0.2.1.tgz#1803c2bcd9e41ccc738a0979cc6de0acbabac3f8" - integrity sha512-Sq9eDpsr/8kI+kyiQAL8jawa+aGRphANCeIeoLyU05DEfHd9vCi4Zz8AXUQTbqnF0TRGfVn9qN69/ox378kyGg== - dependencies: - html-loader "^0.5.1" - -html-loader@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-0.5.5.tgz#6356dbeb0c49756d8ebd5ca327f16ff06ab5faea" - integrity sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog== - dependencies: - es6-templates "^0.2.3" - fastparse "^1.1.1" - html-minifier "^3.5.8" - loader-utils "^1.1.0" - object-assign "^4.1.1" - -html-minifier@^3.5.8: - version "3.5.21" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== +htmlparser2@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78" + integrity sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q== dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" + domelementtype "^2.0.1" + domhandler "^3.0.0" + domutils "^2.0.0" + entities "^2.0.0" http-proxy@^1.18.0: version "1.18.1" @@ -4070,18 +3838,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -icss-replace-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" - integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= - -icss-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" - integrity sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI= - dependencies: - postcss "^6.0.1" - ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" @@ -4131,11 +3887,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - infer-owner@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -4210,11 +3961,6 @@ ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= - is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -4401,11 +4147,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -4445,13 +4186,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-svg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" - integrity sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk= - dependencies: - html-comment-regex "^1.1.0" - is-symbol@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -4955,11 +4689,6 @@ jest@^26.0.1: import-local "^3.0.2" jest-cli "^26.0.1" -js-base64@^2.1.9: - version "2.5.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" - integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ== - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -4978,14 +4707,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" - integrity sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A= - dependencies: - argparse "^1.0.7" - esprima "^2.6.0" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -5135,15 +4856,6 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" -less-loader@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.1.0.tgz#2c1352c5b09a4f84101490274fd51674de41363e" - integrity sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg== - dependencies: - clone "^2.1.1" - loader-utils "^1.1.0" - pify "^3.0.0" - less@^3.9.0: version "3.11.1" resolved "https://registry.yarnpkg.com/less/-/less-3.11.1.tgz#c6bf08e39e02404fe6b307a3dfffafdc55bd36e2" @@ -5218,7 +4930,7 @@ loader-utils@1.2.3: emojis-list "^2.0.0" json5 "^1.0.1" -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: +loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -5250,26 +4962,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" @@ -5282,11 +4979,6 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5335,11 +5027,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -math-expression-evaluator@^1.2.14: - version "1.2.22" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.22.tgz#c14dcb3d8b4d150e5dcea9c68c8dad80309b0d5e" - integrity sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ== - math-random@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" @@ -5538,7 +5225,7 @@ mkdirp-classic@^0.5.2: resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -5609,13 +5296,6 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== - dependencies: - lower-case "^1.1.1" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -5694,21 +5374,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= - -normalize-url@^1.4.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - npm-run-all@^4.1.3: version "4.1.5" resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" @@ -5738,11 +5403,6 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= - nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" @@ -5753,7 +5413,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -5968,13 +5628,6 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= - dependencies: - no-case "^2.2.0" - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -6167,285 +5820,6 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-calc@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" - integrity sha1-d7rnypKK2FcW4v2kLyYb98HWW14= - dependencies: - postcss "^5.0.2" - postcss-message-helpers "^2.0.0" - reduce-css-calc "^1.2.6" - -postcss-colormin@^2.1.8: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" - integrity sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks= - dependencies: - colormin "^1.0.5" - postcss "^5.0.13" - postcss-value-parser "^3.2.3" - -postcss-convert-values@^2.3.4: - version "2.6.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" - integrity sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0= - dependencies: - postcss "^5.0.11" - postcss-value-parser "^3.1.2" - -postcss-discard-comments@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" - integrity sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0= - dependencies: - postcss "^5.0.14" - -postcss-discard-duplicates@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" - integrity sha1-uavye4isGIFYpesSq8riAmO5GTI= - dependencies: - postcss "^5.0.4" - -postcss-discard-empty@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" - integrity sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU= - dependencies: - postcss "^5.0.14" - -postcss-discard-overridden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" - integrity sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg= - dependencies: - postcss "^5.0.16" - -postcss-discard-unused@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" - integrity sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM= - dependencies: - postcss "^5.0.14" - uniqs "^2.0.0" - -postcss-filter-plugins@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz#82245fdf82337041645e477114d8e593aa18b8ec" - integrity sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ== - dependencies: - postcss "^5.0.4" - -postcss-merge-idents@^2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" - integrity sha1-TFUwMTwI4dWzu/PSu8dH4njuonA= - dependencies: - has "^1.0.1" - postcss "^5.0.10" - postcss-value-parser "^3.1.1" - -postcss-merge-longhand@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" - integrity sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg= - dependencies: - postcss "^5.0.4" - -postcss-merge-rules@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" - integrity sha1-0d9d+qexrMO+VT8OnhDofGG19yE= - dependencies: - browserslist "^1.5.2" - caniuse-api "^1.5.2" - postcss "^5.0.4" - postcss-selector-parser "^2.2.2" - vendors "^1.0.0" - -postcss-message-helpers@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" - integrity sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4= - -postcss-minify-font-values@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" - integrity sha1-S1jttWZB66fIR0qzUmyv17vey2k= - dependencies: - object-assign "^4.0.1" - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-minify-gradients@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" - integrity sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE= - dependencies: - postcss "^5.0.12" - postcss-value-parser "^3.3.0" - -postcss-minify-params@^1.0.4: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" - integrity sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM= - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.2" - postcss-value-parser "^3.0.2" - uniqs "^2.0.0" - -postcss-minify-selectors@^2.0.4: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" - integrity sha1-ssapjAByz5G5MtGkllCBFDEXNb8= - dependencies: - alphanum-sort "^1.0.2" - has "^1.0.1" - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" - -postcss-modules-extract-imports@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a" - integrity sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw== - dependencies: - postcss "^6.0.1" - -postcss-modules-local-by-default@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" - integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - -postcss-modules-scope@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" - integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - -postcss-modules-values@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" - integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= - dependencies: - icss-replace-symbols "^1.1.0" - postcss "^6.0.1" - -postcss-normalize-charset@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" - integrity sha1-757nEhLX/nWceO0WL2HtYrXLk/E= - dependencies: - postcss "^5.0.5" - -postcss-normalize-url@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" - integrity sha1-EI90s/L82viRov+j6kWSJ5/HgiI= - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^1.4.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - -postcss-ordered-values@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" - integrity sha1-7sbCpntsQSqNsgQud/6NpD+VwR0= - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.1" - -postcss-reduce-idents@^2.2.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" - integrity sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM= - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-reduce-initial@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" - integrity sha1-aPgGlfBF0IJjqHmtJA343WT2ROo= - dependencies: - postcss "^5.0.4" - -postcss-reduce-transforms@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" - integrity sha1-/3b02CEkN7McKYpC0uFEQCV3GuE= - dependencies: - has "^1.0.1" - postcss "^5.0.8" - postcss-value-parser "^3.0.1" - -postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" - integrity sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A= - dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-svgo@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" - integrity sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0= - dependencies: - is-svg "^2.0.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - svgo "^0.7.0" - -postcss-unique-selectors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" - integrity sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0= - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - -postcss-zindex@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" - integrity sha1-0hCd3AVbka9n/EyzsCWUZjnSryI= - dependencies: - has "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16: - version "5.2.18" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" - integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg== - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.2.3" - -postcss@^6.0.1: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -6456,11 +5830,6 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -6488,7 +5857,7 @@ pretty-format@^26.0.1: ansi-styles "^4.0.0" react-is "^16.12.0" -private@^0.1.8, private@~0.1.5: +private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -6611,11 +5980,6 @@ puppeteer@^3.1.0: unbzip2-stream "^1.3.3" ws "^7.2.3" -q@^1.1.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - qs@^6.4.0: version "6.9.4" resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" @@ -6626,14 +5990,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -6739,32 +6095,6 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" -recast@~0.11.12: - version "0.11.23" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" - integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM= - dependencies: - ast-types "0.9.6" - esprima "~3.1.0" - private "~0.1.5" - source-map "~0.5.0" - -reduce-css-calc@^1.2.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" - integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= - dependencies: - balanced-match "^0.4.2" - math-expression-evaluator "^1.2.14" - reduce-function-call "^1.0.1" - -reduce-function-call@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" - integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ== - dependencies: - balanced-match "^1.0.0" - regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -6815,7 +6145,7 @@ regexpp@^3.1.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== -regexpu-core@^4.6.0, regexpu-core@^4.7.0: +regexpu-core@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== @@ -6839,11 +6169,6 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" -relateurl@0.2.x: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -7086,11 +6411,6 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sax@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - saxes@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -7276,13 +6596,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -7338,7 +6651,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -7475,11 +6788,6 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - string-length@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" @@ -7632,14 +6940,7 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -supports-color@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0, supports-color@^5.4.0: +supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -7661,19 +6962,6 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" -svgo@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" - integrity sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U= - dependencies: - coa "~1.0.1" - colors "~1.1.2" - csso "~2.3.1" - js-yaml "~3.7.0" - mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" - symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -7781,7 +7069,7 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@^2.3.6, through@^2.3.8, through@~2.3.6: +through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -7949,14 +7237,6 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== - dependencies: - commander "~2.19.0" - source-map "~0.6.1" - unbzip2-stream@^1.3.3: version "1.4.2" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz#84eb9e783b186d8fb397515fbb656f312f1a7dbf" @@ -8005,16 +7285,6 @@ union@~0.5.0: dependencies: qs "^6.4.0" -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -8042,11 +7312,6 @@ upath@^1.1.1: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -8133,11 +7398,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -vendors@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" - integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== - verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -8296,11 +7556,6 @@ whatwg-url@^8.0.0: tr46 "^2.0.2" webidl-conversions "^5.0.0" -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" - integrity sha1-+HfVv2SMl+WqVC+twW1qJZucEaE= - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" From 7cda929fae0fc083bfb6736f649bfd19ebe091d3 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Wed, 27 May 2020 21:55:19 -0400 Subject: [PATCH 2/6] Removed perspective functions --- src/js/data.js | 58 ------------------ src/js/events.js | 125 +------------------------------------- src/js/table.js | 4 +- src/js/tbody.js | 17 ++---- src/js/tree_row_header.js | 52 ---------------- src/js/utils.js | 5 -- src/js/view_model.js | 55 ----------------- 7 files changed, 10 insertions(+), 306 deletions(-) delete mode 100644 src/js/data.js delete mode 100644 src/js/tree_row_header.js diff --git a/src/js/data.js b/src/js/data.js deleted file mode 100644 index b3c9b14a..00000000 --- a/src/js/data.js +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2020, the Regular Table Authors. - * - * This file is part of the Regular Table library, distributed under the terms - * of the Apache License 2.0. The full license can be found in the LICENSE - * file. - * - */ - -import Papa from "papaparse"; - -export class DataModel { - to_columns(idx_2d) { - return this.get_data_slice(idx_2d); - } - - // eslint-disable-next-line no-unused-vars - get_data_slice({start_row, end_row, start_col, end_col}) { - throw new TypeError("Must override method"); - } -} - -export class CsvDataModel extends DataModel { - constructor(csv, opt = {}) { - super(); - this.cols = []; - - const {data} = Papa.parse(csv, opt); - const paths = data.shift(); - for (let i = 0; i < paths.length; i++) { - const val = []; - for (let j = 0; j < data.length; j++) { - val.push(data[i][j]); - } - - this.cols.push({ - cidx: i, - paths: paths[i], - val, - }); - } - } - - get_data_slice({start_row, end_row, start_col, end_col}) { - const cols = []; - - for (let i = start_col; i < end_col; i++) { - cols.push({ - cidx: this.cols[i].cidx, - paths: this.cols[i].paths, - val: this.cols[i].val.slice(start_row, end_row), - }); - } - - return cols; - } -} diff --git a/src/js/events.js b/src/js/events.js index 211d78a9..8c40858c 100644 --- a/src/js/events.js +++ b/src/js/events.js @@ -10,7 +10,7 @@ import {METADATA_MAP} from "./constants"; import {RegularVirtualTableViewModel} from "./scroll_panel"; -import {getCellConfig, throttlePromise, isEqual} from "./utils"; +import {throttlePromise} from "./utils"; /** * @@ -117,17 +117,10 @@ export class RegularViewEventModel extends RegularVirtualTableViewModel { } } - const is_button = event.target.classList.contains("pd-row-header-icon"); const is_resize = event.target.classList.contains("pd-column-resize"); const metadata = METADATA_MAP.get(element); - if (is_button) { - await this._on_toggle(event, metadata); - } else if (is_resize) { + if (is_resize) { this._on_resize_column(event, element, metadata); - } else if (metadata?.is_column_header) { - await this._on_sort(event, metadata); - } else if (this.parentElement.hasAttribute("selectable")) { - await this._on_row_select(metadata); } } @@ -187,118 +180,4 @@ export class RegularViewEventModel extends RegularVirtualTableViewModel { } } } - /** - * Get the id of the selected row - * - * @memberof RegularVirtualTableViewModel - */ - _get_selected() { - return this._selected_id; - } - /** - * sets the selected row to the `selected_id`. The row for the id - * will be highlighted if it's in the viewport - * - * @param {*} selected_id - * @memberof RegularVirtualTableViewModel - */ - _set_selected(selected_id) { - this._selected_id = selected_id; - } - /** - * Clears selected row - * - * @memberof RegularVirtualTableViewModel - */ - _clear_selected() { - delete this._selected_id; - } - - /** - * Regular event which handles row selection. - * - * @param {*} metadata - * @returns - * @memberof RegularVirtualTableViewModel - */ - async _on_row_select(metadata) { - const is_deselect = isEqual(metadata.id, this._selected_id); - let filters = []; - if (is_deselect) { - this._clear_selected(); - await this.draw({invalid_viewport: true}); - } else { - this._set_selected(metadata.id); - await this.draw({invalid_viewport: true}); - filters = await getCellConfig(this._view_cache, metadata.ridx, metadata.cidx); - filters = filters.config.filters; - } - - this.dispatchEvent( - new CustomEvent("perspective-select", { - bubbles: true, - composed: true, - detail: { - selected: !is_deselect, - config: {filters}, - }, - }) - ); - } - - /** - * Toggles a tree row between 'open' and 'closed' states, or toggles all - * tree rows at this depth when the shift key is also pressed. - * - * @param {*} event - * @param {*} metadata - * @memberof RegularVirtualTableViewModel - */ - async _on_toggle(event, metadata) { - if (metadata.is_open) { - if (event.shiftKey) { - await this._view_cache.view.set_depth(metadata.row_path.length - 1); - } else { - await this._view_cache.view.collapse(metadata.ridx); - } - } else if (metadata.is_open === false) { - if (event.shiftKey) { - await this._view_cache.view.set_depth(metadata.row_path.length); - } else { - await this._view_cache.view.expand(metadata.ridx); - } - } - await this.draw({invalid_viewport: true}); - } - - /** - * Regular event which handles sorting. There are 3 control states: - * - * - Already sorted by `metadata.column_name`, increment sort clause to - * next sort state. - * - Not sorted, shift key, append new sort clause to existing. - * - Not sorted, set as new sort clause. - * - * @param {*} event - * @param {*} metadata - * @memberof RegularVirtualTableViewModel - */ - async _on_sort(event, metadata) { - let sort = this._view_cache.config.sort.slice(); - const current_idx = sort.findIndex((x) => x[0] === metadata.column_name); - if (current_idx > -1) { - const sort_dir = sort[current_idx][1]; - const new_sort = this.parentElement._increment_sort(sort_dir, false, event.altKey); - sort[current_idx] = [metadata.column_name, new_sort]; - } else { - let sort_dir = event.altKey ? "asc abs" : "asc"; - const new_sort = [metadata.column_name, sort_dir]; - if (event.shiftKey) { - sort.push(new_sort); - } else { - sort = [new_sort]; - } - } - this.parentElement.setAttribute("sort", JSON.stringify(sort)); - } } diff --git a/src/js/table.js b/src/js/table.js index 6413bcfa..95225672 100644 --- a/src/js/table.js +++ b/src/js/table.js @@ -10,7 +10,7 @@ import {RegularHeaderViewModel} from "./thead"; import {RegularBodyViewModel} from "./tbody"; -import {column_path_2_type, html} from "./utils"; +import {html} from "./utils"; /** *
view model. In order to handle unknown column width when `draw()` @@ -120,7 +120,7 @@ export class RegularTableViewModel { column_indices[dcidx] = new_col.column_indices[0]; } const column_name = column_indices[dcidx]; - const type = column_path_2_type(schema, column_name); + const type = "string"; const column_data = data[dcidx]; const column_state = { column_name, diff --git a/src/js/tbody.js b/src/js/tbody.js index efd0e123..430719ad 100644 --- a/src/js/tbody.js +++ b/src/js/tbody.js @@ -46,21 +46,16 @@ export class RegularBodyViewModel extends ViewModel { td.style.minWidth = ""; td.style.maxWidth = ""; } - const formatter = this._format(type); - if (val === undefined || val === null) { - td.textContent = "-"; - metadata.value = null; - metadata.row_path = null; - } else if (formatter) { - formatter.format(td, val, type, val.length === depth, is_open); - metadata.value = Array.isArray(val) ? val[val.length - 1] : val; - metadata.row_path = id; - metadata.is_open = is_open; + + if (val instanceof HTMLElement) { + td.textContent = ""; + td.appendChild(val); } else { td.textContent = val; - metadata.value = val; } + metadata.value = val; + metadata.row_path = id; return {td, metadata}; } diff --git a/src/js/tree_row_header.js b/src/js/tree_row_header.js deleted file mode 100644 index 9c44ec65..00000000 --- a/src/js/tree_row_header.js +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2020, the Regular Table Authors. - * - * This file is part of the Regular Table library, distributed under the terms - * of the Apache License 2.0. The full license can be found in the LICENSE - * file. - * - */ - -import {html} from "./utils"; - -function _tree_header_classes(name, type, is_leaf) { - const cls = this._format_class(type)(name); - const header_classes = ["pd-group-name"]; - if (is_leaf) { - header_classes.push("pd-group-leaf"); - } - - if (cls) { - header_classes.push(cls); - } - - return header_classes.join(" "); -} - -function _tree_header_levels(path, is_open, is_leaf) { - const tree_levels = path.map(() => ''); - if (!is_leaf) { - const group_icon = is_open ? "remove" : "add"; - const tree_button = `${group_icon}`; - tree_levels.push(tree_button); - } - - return tree_levels.join(""); -} - -export function tree_header(td, path, types, is_leaf, is_open) { - const type = types[path.length - 1]; - const name = path.length === 0 ? "TOTAL" : path[path.length - 1]; - const header_classes = _tree_header_classes.call(this, name, type, is_leaf); - const tree_levels = _tree_header_levels(path, is_open, is_leaf); - const header_text = this._format_text(type)(name); - - td.classList.add("pd-group-header"); - td.innerHTML = html` - - ${tree_levels} - ${header_text} - - `; -} diff --git a/src/js/utils.js b/src/js/utils.js index a2172b71..afb7d2ed 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -104,11 +104,6 @@ export function memoize(_target, _property, descriptor) { } } -export function column_path_2_type(schema, column) { - const parts = column.split("|"); - return schema[parts[parts.length - 1]]; -} - /** * Identical to a non-tagger template literal, this is only used to indicate to * babel that this string should be HTML-minified on production builds. diff --git a/src/js/view_model.js b/src/js/view_model.js index 00d4614c..80fd3a57 100644 --- a/src/js/view_model.js +++ b/src/js/view_model.js @@ -9,8 +9,6 @@ */ import {METADATA_MAP} from "./constants"; -import {get_type_config, memoize} from "./utils"; -import {tree_header} from "./tree_row_header"; /****************************************************************************** * @@ -45,59 +43,6 @@ export class ViewModel { } } - @memoize - _format_text(type) { - const config = get_type_config(type); - const real_type = config.type || type; - const format_function = { - float: Intl.NumberFormat, - integer: Intl.NumberFormat, - datetime: Intl.DateTimeFormat, - date: Intl.DateTimeFormat, - }[real_type]; - if (format_function) { - const func = new format_function("en-us", config.format); - return (path) => func.format(path); - } else { - return (path) => path; - } - } - - @memoize - _format_class(type) { - const config = get_type_config(type); - const real_type = config.type || type; - if (real_type === "integer" || real_type === "float") { - return (path) => { - if (path > 0) { - return "pd-positive"; - } else if (path < 0) { - return "pd-negative"; - } - }; - } else { - return () => ""; - } - } - - @memoize - _format(type) { - if (Array.isArray(type)) { - return {format: tree_header.bind(this)}; - } - const fmt = this._format_text(type); - const cls = this._format_class(type); - return { - format(td, path) { - td.textContent = fmt(path); - const c = cls(path); - if (c) { - td.classList.add(c); - } - }, - }; - } - _get_cell(tag = "td", row_container, cidx, tr) { let td = row_container[cidx]; if (!td) { From f5c115764b8dcf4a55b9642435da432ba719d7a3 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Wed, 27 May 2020 21:58:56 -0400 Subject: [PATCH 3/6] Fixes `row-indices` --- examples/2d_array.html | 24 ++--- examples/canvas_data_model.html | 24 ++--- examples/perspective.html | 33 ++++-- examples/perspective_indices.html | 143 +++++++++++++++++++++++++ examples/two_billion_rows.html | 12 +-- examples/virtual_indices.html | 69 ++++++++++++ examples/web_worker.html | 12 +-- package.json | 2 + scripts/sync_gist.js | 9 +- src/js/table.js | 33 ++++-- src/js/tbody.js | 49 +++++---- src/js/thead.js | 14 +-- src/js/view_model.js | 9 +- src/less/material.less | 12 ++- test/perspective.test.js | 7 +- test/two_billion_rows/metadata.test.js | 3 - yarn.lock | 94 +++++++++++++++- 17 files changed, 449 insertions(+), 100 deletions(-) create mode 100644 examples/perspective_indices.html create mode 100644 examples/virtual_indices.html diff --git a/examples/2d_array.html b/examples/2d_array.html index 2f4d2933..350da691 100644 --- a/examples/2d_array.html +++ b/examples/2d_array.html @@ -21,21 +21,16 @@ diff --git a/examples/canvas_data_model.html b/examples/canvas_data_model.html index ec505dcf..b2bdfd91 100644 --- a/examples/canvas_data_model.html +++ b/examples/canvas_data_model.html @@ -34,25 +34,22 @@ margin: 0; overflow: auto; } - th, td { + th:not(:first-child), td { height: 20px !important; min-width: 20px !important; max-width: 20px !important; padding: 0px; } - thead tr:last-child th { - transform: rotate(-90deg); - transform-origin: 30% 90%; - border-bottom-width: 0px !important; - border-right-width: 0px !important; - height: 40px !important; - text-align: left !important; - border-left: 1px solid white; - } th { color: white; font-family: monospace; } + tbody th:first-child { + vertical-align: top; + border-top: 1px solid white; + border-right: 0px !important; + text-align: left; + } regular-table { position: absolute; top: 0; @@ -70,7 +67,7 @@ bottom: 0; right: 0; border-top-width: 0; - box-shadow: 0px 15px 10px -10px rgba(0,0,0,1); + border-left-width: 0; } regular-table::-webkit-scrollbar-thumb { background-color: #fff !important; @@ -100,6 +97,8 @@ const ref_image = document.getElementById("ref_image"); const table = document.getElementsByTagName("regular-table")[0]; const canvas = document.createElement("canvas"); + const scroll_container = window.scroll_container; + const reticle = window.reticle; ref_image.onload = async function () { canvas.width = ref_image.width; @@ -133,7 +132,8 @@ } return { data, - column_indices: column_names.slice(x0, x1).map((x) => [clamp(x, 10), clamp(x, 1)]), + row_indices: y1 - y0 === 0 ? [] : Array.from(Array(Math.floor(y1 - y0)).keys()).map((z) => [clamp(y0 + z, 10), (y0 + z) % 10]), + column_indices: column_names.slice(x0, x1).map((x) => [clamp(x, 10), x % 10]), num_rows: canvas.height, num_columns: column_names.length, }; diff --git a/examples/perspective.html b/examples/perspective.html index 74f307cd..7784aa4d 100644 --- a/examples/perspective.html +++ b/examples/perspective.html @@ -12,7 +12,7 @@ - + @@ -22,7 +22,7 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/two_billion_rows.html b/examples/two_billion_rows.html index 9ef4bbe2..1b64231a 100644 --- a/examples/two_billion_rows.html +++ b/examples/two_billion_rows.html @@ -27,7 +27,6 @@ diff --git a/examples/virtual_indices.html b/examples/virtual_indices.html new file mode 100644 index 00000000..2918a81b --- /dev/null +++ b/examples/virtual_indices.html @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/web_worker.html b/examples/web_worker.html index 79065c88..d0e01f2e 100644 --- a/examples/web_worker.html +++ b/examples/web_worker.html @@ -61,24 +61,22 @@ diff --git a/package.json b/package.json index 277822c1..bfd7441c 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@babel/plugin-proposal-decorators": "^7.8.3", "@babel/plugin-proposal-optional-chaining": "^7.9.0", "@babel/preset-env": "^7.9.0", + "@finos/perspective": "=0.5.0", "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", "babel-plugin-lodash": "^3.3.4", @@ -67,6 +68,7 @@ "puppeteer": "^3.1.0", "source-map-explorer": "^2.4.2", "source-map-loader": "^0.2.4", + "superstore-arrow": "^1.0.0", "webpack": "^4.43.0", "webpack-cli": "^3.3.11" } diff --git a/scripts/sync_gist.js b/scripts/sync_gist.js index 49d8e8aa..fa234dac 100644 --- a/scripts/sync_gist.js +++ b/scripts/sync_gist.js @@ -14,8 +14,13 @@ for (const file in hashes) { child_process.execSync(`git clone https://gist.github.com/${hashes[file]}.git dist/${hashes[file]}`); fs.copyFileSync(`images/${file}.preview.png`, `dist/${hashes[file]}/preview.png`); fs.copyFileSync(`images/${file}.thumbnail.png`, `dist/${hashes[file]}/thumbnail.png`); - const source = fs.readFileSync(`examples/${file}.html`).toString(); - fs.writeFileSync(`dist/${hashes[file]}/index.html`, source.replace(/\.\.\//g, `https://cdn.jsdelivr.net/npm/regular-table@${pkg.version}/`)); + + // Retarget source assets to jsdelivr + let source = fs.readFileSync(`examples/${file}.html`).toString(); + source = source.replace(/\.\.\/node_modules\//g, `https://cdn.jsdelivr.net/npm/@${pkg.version}/`); + source = source.replace(/\.\.\//g, `https://cdn.jsdelivr.net/npm/regular-table@${pkg.version}/`); + + fs.writeFileSync(`dist/${hashes[file]}/index.html`, source); process.chdir(`dist/${hashes[file]}`); child_process.execSync(`git add thumbnail.png preview.png index.html`); console.log(child_process.execSync(`git status`).toString()); diff --git a/src/js/table.js b/src/js/table.js index 95225672..cf333ab5 100644 --- a/src/js/table.js +++ b/src/js/table.js @@ -66,12 +66,12 @@ export class RegularTableViewModel { const {view, config, schema} = view_cache; const {data, row_indices, column_indices, __id_column: id_column} = await view(viewport.start_col, viewport.start_row, viewport.end_col, viewport.end_row); const {start_row: ridx_offset = 0, start_col: cidx_offset = 0} = viewport; - const depth = config.row_pivots.length; - view_cache.config.column_pivots = Array.from(Array(column_indices[0]?.length - 1 || 0).keys()); + view_cache.config.column_pivots = Array.from(Array(column_indices?.[0]?.length - 1 || 0).keys()); + view_cache.config.row_pivots = Array.from(Array(row_indices?.[0]?.length || 0).keys()); + const view_state = { viewport_width: 0, selected_id, - depth, ridx_offset, cidx_offset, row_height: this._column_sizes.row_height, @@ -84,7 +84,15 @@ export class RegularTableViewModel { if (row_indices?.length > 0) { const column_name = config.row_pivots.join(","); const type = config.row_pivots.map((x) => schema[x]); - const column_data = row_indices; + + // pad row_indices for embedded renderer + // TODO maybe dont need this - perspective compat + const row_index_length = row_indices.reduce((max, x) => Math.max(max, x.length), 0); + const column_data = row_indices.map((x) => { + x.length = row_index_length; + return x; + }); + const column_state = { column_name, cidx: 0, @@ -93,15 +101,20 @@ export class RegularTableViewModel { type, first_col, }; - const cont_head = this.header.draw(config, column_name, "", type, 0); - cont_body = this.body.draw(container_height, column_state, { - ...view_state, - cidx_offset: 0, - }); + cont_body = this.body.draw( + container_height, + column_state, + { + ...view_state, + cidx_offset: 0, + }, + true + ); + const cont_head = this.header.draw(config, column_name, "", type, 0, row_index_length); first_col = false; view_state.viewport_width += this._column_sizes.indices[0] || cont_body.td?.offsetWidth || cont_head.th.offsetWidth; view_state.row_height = view_state.row_height || cont_body.row_height; - cidx++; + cidx = row_indices[0].length; if (!preserve_width) { last_cells.push([cont_body.td || cont_head.th, cont_body.metadata || cont_head.metadata]); } diff --git a/src/js/tbody.js b/src/js/tbody.js index 430719ad..9d6b905c 100644 --- a/src/js/tbody.js +++ b/src/js/tbody.js @@ -8,7 +8,6 @@ * */ -import {isEqual} from "./utils"; import {ViewModel} from "./view_model"; /** @@ -17,23 +16,13 @@ import {ViewModel} from "./view_model"; * @class RegularBodyViewModel */ export class RegularBodyViewModel extends ViewModel { - _draw_td(ridx, val, id, is_open, {cidx, column_name, type, first_col}, {selected_id, depth, ridx_offset, cidx_offset}) { - const {tr, row_container} = this._get_row(ridx); - - const td = this._get_cell("td", row_container, cidx, tr); - td.className = `pd-${type}`; - if (first_col && selected_id !== undefined) { - const is_selected = isEqual(id, selected_id); - const is_sub_selected = !is_selected && isEqual(id?.slice(0, selected_id?.length), selected_id); - tr.classList.toggle("pd-selected", !!id && is_selected); - tr.classList.toggle("pd-sub-selected", !!id && is_sub_selected); - } + _draw_td(tagName, ridx, val, id, cidx, {column_name}, {ridx_offset, cidx_offset}) { + const td = this._get_cell(tagName, ridx, cidx); const metadata = this._get_or_create_metadata(td); metadata.id = id; metadata.cidx = cidx + cidx_offset; - metadata.type = type; metadata.column = column_name; - metadata.size_key = `${column_name}|${type}`; + metadata.size_key = `${column_name}|undefined`; metadata.ridx = ridx + ridx_offset; const override_width = this._column_sizes.override[metadata.size_key]; if (override_width) { @@ -59,15 +48,37 @@ export class RegularBodyViewModel extends ViewModel { return {td, metadata}; } - draw(container_height, column_state, view_state) { + draw(container_height, column_state, view_state, th = false) { const {cidx, column_data, id_column} = column_state; let {row_height} = view_state; let ridx = 0; - let td, metadata; + let td, metadata, prev; for (const val of column_data) { - const next = column_data[ridx + 1]; const id = id_column?.[ridx]; - const obj = this._draw_td(ridx++, val, id, next?.length > val?.length, column_state, view_state); + const row = []; + let obj; + if (th) { + let cidx_ = cidx; + for (let i = 0; i < val.length; i++) { + const row_header = val[i]; + if (prev && prev[i][0] === row_header) { + obj = this._draw_td("TH", ridx, row_header, id, cidx_, column_state, view_state); + prev[i][1].setAttribute("rowspan", prev[i][2] + 1); + obj.td.style.display = "none"; + row.push([prev[i][0], prev[i][1], prev[i][2] + 1]); + } else { + obj = this._draw_td("TH", ridx, row_header, id, cidx_, column_state, view_state); + obj.td.style.display = ""; + obj.td.removeAttribute("rowspan"); + row.push([row_header, obj.td, 1]); + } + cidx_++; + } + prev = row; + ridx++; + } else { + obj = this._draw_td("TD", ridx++, val, id, cidx, column_state, view_state); + } td = obj.td; metadata = obj.metadata; row_height = row_height || td.offsetHeight; @@ -76,7 +87,7 @@ export class RegularBodyViewModel extends ViewModel { } } this._clean_rows(ridx); - return {td, cidx, ridx, metadata, row_height}; + return {td, ridx, metadata, row_height}; } clean({ridx, cidx}) { diff --git a/src/js/thead.js b/src/js/thead.js index 83d0ead9..50d979e1 100644 --- a/src/js/thead.js +++ b/src/js/thead.js @@ -21,8 +21,7 @@ import {html} from "./utils.js"; */ export class RegularHeaderViewModel extends ViewModel { _draw_group_th(offset_cache, d, column, sort_dir) { - const {tr, row_container} = this._get_row(d); - const th = this._get_cell("th", row_container, offset_cache[d], tr); + const th = this._get_cell("TH", d, offset_cache[d]); offset_cache[d] += 1; th.className = ""; th.removeAttribute("colspan"); @@ -50,12 +49,11 @@ export class RegularHeaderViewModel extends ViewModel { } _redraw_previous(offset_cache, d) { - const {tr, row_container} = this._get_row(d); const cidx = offset_cache[d] - 1; if (cidx < 0) { return; } - const th = this._get_cell("th", row_container, cidx, tr); + const th = this._get_cell("TH", d, cidx); if (!th) return; th.classList.add("pd-group-header"); return th; @@ -94,14 +92,13 @@ export class RegularHeaderViewModel extends ViewModel { } get_column_header(cidx) { - const {tr, row_container} = this._get_row(this.rows.length - 1); - return this._get_cell("th", row_container, cidx, tr); + return this._get_cell("TH", this.rows.length - 1, cidx); } _group_header_cache = []; _offset_cache = []; - draw(config, alias, parts, type, cidx) { + draw(config, alias, parts, type, cidx, colspan) { const header_levels = config.column_pivots.length + 1; let th, column_name, @@ -140,6 +137,9 @@ export class RegularHeaderViewModel extends ViewModel { group_meta.size_key = metadata.size_key; } } + if (colspan > 1) { + th.setAttribute("colspan", colspan); + } } if (header_levels === 1 && Array.isArray(type)) { diff --git a/src/js/view_model.js b/src/js/view_model.js index 80fd3a57..447fd8f7 100644 --- a/src/js/view_model.js +++ b/src/js/view_model.js @@ -43,12 +43,19 @@ export class ViewModel { } } - _get_cell(tag = "td", row_container, cidx, tr) { + _get_cell(tag = "TD", ridx, cidx) { + const {tr, row_container} = this._get_row(ridx); let td = row_container[cidx]; if (!td) { td = row_container[cidx] = document.createElement(tag); tr.appendChild(td); } + if (td.tagName !== tag) { + const new_td = document.createElement(tag); + tr.replaceChild(new_td, td); + this.cells[ridx].splice(cidx, 1, new_td); + td = new_td; + } return td; } diff --git a/src/less/material.less b/src/less/material.less index b48a3bea..d5236a9f 100644 --- a/src/less/material.less +++ b/src/less/material.less @@ -54,6 +54,10 @@ regular-table, :host { text-align: right; } + tbody th { + text-align: left; + } + .pd-positive { color: #1078d1; @@ -101,7 +105,7 @@ regular-table, :host { position: relative; } - tr td span.pd-tree-group { + tr th span.pd-tree-group { margin-left: 5px; margin-right: 15px; border-left: 1px solid #eee; @@ -193,8 +197,12 @@ regular-table, :host { flex: 1; height: 100%; } + + th span.pd-group-name { + text-align: left; + } - td span.pd-group-leaf { + td th span.pd-group-leaf, th span.pd-group-leaf { margin-left: 12px; height: 100%; } diff --git a/test/perspective.test.js b/test/perspective.test.js index 6ae0f246..e915a10e 100644 --- a/test/perspective.test.js +++ b/test/perspective.test.js @@ -8,13 +8,12 @@ * */ -describe("perspective,html", () => { +describe("perspective.html", () => { beforeAll(async () => { await page.setViewport({width: 200, height: 100}); }); - // TODO don't run these, they depend on unpkg.com - describe.skip("creates a `
` body when attached to `document`", () => { + describe("creates a `
` body when attached to `document`", () => { beforeAll(async () => { await page.goto("http://localhost:8081/examples/perspective.html"); await page.waitFor("regular-table table tbody tr td"); @@ -23,7 +22,7 @@ describe("perspective,html", () => { test("with the first row's cells from superstore.arrow", async () => { const first_tr = await page.$("regular-table tbody tr:first-child"); const cell_values = await page.evaluate((first_tr) => Array.from(first_tr.children).map((x) => x.textContent), first_tr); - expect(cell_values).toEqual(["1", "CA-2013-152156", "Second Class"]); + expect(cell_values).toEqual(["1", "CA-2016-152156", "11/8/2016"]); }); }); }); diff --git a/test/two_billion_rows/metadata.test.js b/test/two_billion_rows/metadata.test.js index 8e1ecea4..acb2e351 100644 --- a/test/two_billion_rows/metadata.test.js +++ b/test/two_billion_rows/metadata.test.js @@ -24,7 +24,6 @@ describe("two_billion_rows.html Metadata", () => { expect(JSON.parse(meta)).toEqual({ cidx: 0, column: ["Column 0"], - is_open: false, ridx: 0, size_key: "Column 0|undefined", value: "0", @@ -49,7 +48,6 @@ describe("two_billion_rows.html Metadata", () => { expect(JSON.parse(meta)).toEqual({ cidx: 16, column: ["Column 16"], - is_open: false, ridx: 0, size_key: "Column 16|undefined", value: "16", @@ -75,7 +73,6 @@ describe("two_billion_rows.html Metadata", () => { expect(JSON.parse(meta)).toEqual({ cidx: 0, column: ["Column 0"], - is_open: false, ridx: 200002, size_key: "Column 0|undefined", value: "200,002", diff --git a/yarn.lock b/yarn.lock index 0a2fe729..f0030385 100644 --- a/yarn.lock +++ b/yarn.lock @@ -829,6 +829,24 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@finos/perspective@=0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@finos/perspective/-/perspective-0.5.0.tgz#2ccd24cf0889e6b56d18591a46dfc07829c141e4" + integrity sha512-VHKBjB8Q6nHaQeGJdwX7wnhna4WSMDpVbWoEWbICe7b/ooV4T3kpYk8n8dpzIJpAMdPuN4TZjxRylaQdh4HiRw== + dependencies: + "@babel/runtime" "^7.8.4" + core-js "^3.6.4" + d3-array "^1.2.1" + detectie "1.0.0" + flatbuffers "^1.10.2" + jsverify "^0.8.4" + lodash "^4.17.4" + moment "^2.19.1" + papaparse "^5.2.0" + text-encoding-utf-8 "^1.0.2" + tslib "^1.9.3" + ws "^6.1.2" + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -1533,6 +1551,11 @@ async-each@^1.0.0, async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + async@0.9.x: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" @@ -2503,6 +2526,11 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= +d3-array@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -2617,6 +2645,11 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detectie@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detectie/-/detectie-1.0.0.tgz#66b2cae2236d4d29ef71161180957bf89fbe535d" + integrity sha1-ZrLK4iNtTSnvcRYRgJV7+J++U10= + diff-sequences@^26.0.0: version "26.0.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.0.0.tgz#0760059a5c287637b842bd7085311db7060e88a6" @@ -3343,6 +3376,11 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" +flatbuffers@^1.10.2: + version "1.12.0" + resolved "https://registry.yarnpkg.com/flatbuffers/-/flatbuffers-1.12.0.tgz#72e87d1726cb1b216e839ef02658aa87dcef68aa" + integrity sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ== + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" @@ -4803,6 +4841,16 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jsverify@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/jsverify/-/jsverify-0.8.4.tgz#b914ccc024103d946b503f18ee780ec43febeece" + integrity sha512-nUG73Sfi8L4eOkc7pv9sflgAm43v+z6XMuePGVdRoBUxBLJiVcMcf3Xgc4h19eHHF3JwsaagOkUu825UnPBLJw== + dependencies: + lazy-seq "^1.0.0" + rc4 "~0.1.5" + trampa "^1.0.0" + typify-parser "^1.1.0" + kind-of@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" @@ -4849,6 +4897,11 @@ lazy-cache@^1.0.3: resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= +lazy-seq@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazy-seq/-/lazy-seq-1.0.0.tgz#880cb8aab256026382e02f53ec089682a74c5b6a" + integrity sha1-iAy4qrJWAmOC4C9T7AiWgqdMW2o= + lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -5232,6 +5285,11 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3: dependencies: minimist "^1.2.5" +moment@^2.19.1: + version "2.26.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a" + integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -5614,7 +5672,7 @@ pako@~1.0.5: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== -papaparse@5.2.0: +papaparse@5.2.0, papaparse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/papaparse/-/papaparse-5.2.0.tgz#97976a1b135c46612773029153dc64995caa3b7b" integrity sha512-ylq1wgUSnagU+MKQtNeVqrPhZuMYBvOSL00DHycFTCxownF95gpLAk1HiHdUW77N8yxRq1qHXLdlIPyBSG9NSA== @@ -6024,6 +6082,11 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" +rc4@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/rc4/-/rc4-0.1.5.tgz#08c6e04a0168f6eb621c22ab6cb1151bd9f4a64d" + integrity sha1-CMbgSgFo9utiHCKrbLEVG9n0pk0= + react-is@^16.12.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -6928,6 +6991,11 @@ superscript-number@^1.0.0: resolved "https://registry.yarnpkg.com/superscript-number/-/superscript-number-1.0.0.tgz#763613e214891dadc188995d0c7485c8c0beb6ef" integrity sha1-djYT4hSJHa3BiJldDHSFyMC+tu8= +superstore-arrow@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/superstore-arrow/-/superstore-arrow-1.0.0.tgz#55a0ecdc872a31e8914c3502dd8e7790da44f849" + integrity sha512-kDG1JykWoNYi0CYv1NWEwqZoNl/Yc/i4GIzfVQSeNvMfnOdyzUw/3gIXrw8qZtSQQCf9yp5jnXvWkvsfqJlBqA== + supports-color@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" @@ -7051,6 +7119,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-encoding-utf-8@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -7164,12 +7237,17 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" +trampa@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trampa/-/trampa-1.0.1.tgz#b866bc192331f64b4f57a8acf4ab71d0e900b692" + integrity sha512-93WeyHNuRggPEsfCe+yHxCgM2s6H3Q8Wmlt6b6ObJL8qc7eZlRaFjQxwTrB+zbvGtlDRnAkMoYYo3+2uH/fEwA== + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -tslib@^1.10.0, tslib@^1.9.0: +tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== @@ -7237,6 +7315,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typify-parser@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/typify-parser/-/typify-parser-1.1.0.tgz#ac73bfa5f25343468e2d0f3346c6117bc03d3c99" + integrity sha1-rHO/pfJTQ0aOLQ8zRsYRe8A9PJk= + unbzip2-stream@^1.3.3: version "1.4.2" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz#84eb9e783b186d8fb397515fbb656f312f1a7dbf" @@ -7627,6 +7710,13 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" +ws@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + ws@^7.2.3: version "7.3.0" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.0.tgz#4b2f7f219b3d3737bc1a2fbf145d825b94d38ffd" From f562df06bf2403b87dc04df7f53867fb2e5b3377 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Thu, 28 May 2020 18:52:06 -0400 Subject: [PATCH 4/6] Updated perspective.html examples to use indices --- examples/canvas_data_model.html | 4 +- examples/perspective.html | 116 +++++++++++++++---- examples/perspective_indices.html | 151 +++++++++++++++++-------- src/js/custom_element.js | 4 + src/js/scroll_panel.js | 3 +- src/js/table.js | 18 ++- src/js/tbody.js | 5 +- src/js/thead.js | 13 ++- src/less/material.less | 18 +-- test/perspective_indices.test.js | 59 ++++++++++ test/two_billion_rows/metadata.test.js | 9 +- 11 files changed, 288 insertions(+), 112 deletions(-) create mode 100644 test/perspective_indices.test.js diff --git a/examples/canvas_data_model.html b/examples/canvas_data_model.html index b2bdfd91..95a116f5 100644 --- a/examples/canvas_data_model.html +++ b/examples/canvas_data_model.html @@ -46,7 +46,7 @@ } tbody th:first-child { vertical-align: top; - border-top: 1px solid white; + border-bottom: 1px solid white; border-right: 0px !important; text-align: left; } @@ -111,7 +111,7 @@ table.addEventListener("regular-table-after-update", () => { const tds = table.querySelectorAll("td"); for (const td of tds) { - td.style.backgroundColor = td.innerHTML; + td.style.backgroundColor = td.textContent; td.innerHTML = " "; } }); diff --git a/examples/perspective.html b/examples/perspective.html index 7784aa4d..af032dff 100644 --- a/examples/perspective.html +++ b/examples/perspective.html @@ -15,6 +15,25 @@ + @@ -22,37 +41,49 @@ + + diff --git a/examples/perspective_indices.html b/examples/perspective_indices.html index 56b052fb..deacc2da 100644 --- a/examples/perspective_indices.html +++ b/examples/perspective_indices.html @@ -15,6 +15,25 @@ + @@ -22,63 +41,49 @@ + + diff --git a/src/js/custom_element.js b/src/js/custom_element.js index be01c177..ce10963b 100644 --- a/src/js/custom_element.js +++ b/src/js/custom_element.js @@ -90,6 +90,10 @@ export class RegularViewModel extends RegularViewEventModel { this.reset_viewport(); } + async addStyleModel(view) { + return this.addEventListener("regular-table-after-update", view); + } + async setDataModel(view) { let schema = {}; let config = { diff --git a/src/js/scroll_panel.js b/src/js/scroll_panel.js index 1768e67d..614491dc 100644 --- a/src/js/scroll_panel.js +++ b/src/js/scroll_panel.js @@ -204,8 +204,7 @@ export class RegularVirtualTableViewModel extends HTMLElement { max_scroll_column--; width += this._column_sizes.indices[max_scroll_column] || 60; } - const psp_offset = this._view_cache.config.row_pivots.length > 0; - return Math.min(num_columns - (psp_offset ? 2 : 1), max_scroll_column + (psp_offset ? 0 : 1)); + return Math.min(num_columns - 1, max_scroll_column + 1); } /** diff --git a/src/js/table.js b/src/js/table.js index cf333ab5..c0b1bdaa 100644 --- a/src/js/table.js +++ b/src/js/table.js @@ -63,7 +63,7 @@ export class RegularTableViewModel { async draw(container_size, view_cache, selected_id, preserve_width, viewport, num_columns) { const {width: container_width, height: container_height} = container_size; - const {view, config, schema} = view_cache; + const {view, config} = view_cache; const {data, row_indices, column_indices, __id_column: id_column} = await view(viewport.start_col, viewport.start_row, viewport.end_col, viewport.end_row); const {start_row: ridx_offset = 0, start_col: cidx_offset = 0} = viewport; view_cache.config.column_pivots = Array.from(Array(column_indices?.[0]?.length - 1 || 0).keys()); @@ -83,7 +83,6 @@ export class RegularTableViewModel { first_col = true; if (row_indices?.length > 0) { const column_name = config.row_pivots.join(","); - const type = config.row_pivots.map((x) => schema[x]); // pad row_indices for embedded renderer // TODO maybe dont need this - perspective compat @@ -98,7 +97,6 @@ export class RegularTableViewModel { cidx: 0, column_data, id_column, - type, first_col, }; cont_body = this.body.draw( @@ -110,7 +108,7 @@ export class RegularTableViewModel { }, true ); - const cont_head = this.header.draw(config, column_name, "", type, 0, row_index_length); + const cont_head = this.header.draw(config, column_name, Array(view_cache.config.column_pivots.length + 1).fill(""), undefined, 0, row_index_length, undefined); first_col = false; view_state.viewport_width += this._column_sizes.indices[0] || cont_body.td?.offsetWidth || cont_head.th.offsetWidth; view_state.row_height = view_state.row_height || cont_body.row_height; @@ -130,21 +128,21 @@ export class RegularTableViewModel { viewport.end_col = missing_cidx + 1; const new_col = await view(viewport.start_col, viewport.start_row, viewport.end_col, viewport.end_row); data[dcidx] = new_col.data[0]; - column_indices[dcidx] = new_col.column_indices[0]; + if (column_indices) { + column_indices[dcidx] = new_col.column_indices?.[0]; + } } - const column_name = column_indices[dcidx]; - const type = "string"; + const column_name = column_indices?.[dcidx] || ""; const column_data = data[dcidx]; const column_state = { column_name, cidx, column_data, id_column, - type, first_col, }; - const cont_head = this.header.draw(config, undefined, column_name, type, cidx + cidx_offset); - cont_body = this.body.draw(container_height, column_state, view_state); + const cont_head = this.header.draw(config, undefined, column_name, undefined, dcidx + cidx_offset, undefined, dcidx); + cont_body = this.body.draw(container_height, column_state, view_state, false, dcidx); first_col = false; view_state.viewport_width += this._column_sizes.indices[cidx + cidx_offset] || cont_body.td?.offsetWidth || cont_head.th.offsetWidth; view_state.row_height = view_state.row_height || cont_body.row_height; diff --git a/src/js/tbody.js b/src/js/tbody.js index 9d6b905c..8dba850b 100644 --- a/src/js/tbody.js +++ b/src/js/tbody.js @@ -23,7 +23,7 @@ export class RegularBodyViewModel extends ViewModel { metadata.cidx = cidx + cidx_offset; metadata.column = column_name; metadata.size_key = `${column_name}|undefined`; - metadata.ridx = ridx + ridx_offset; + metadata.y = ridx + ridx_offset; const override_width = this._column_sizes.override[metadata.size_key]; if (override_width) { const auto_width = this._column_sizes.auto[metadata.size_key]; @@ -48,7 +48,7 @@ export class RegularBodyViewModel extends ViewModel { return {td, metadata}; } - draw(container_height, column_state, view_state, th = false) { + draw(container_height, column_state, view_state, th = false, dcidx = 0) { const {cidx, column_data, id_column} = column_state; let {row_height} = view_state; let ridx = 0; @@ -81,6 +81,7 @@ export class RegularBodyViewModel extends ViewModel { } td = obj.td; metadata = obj.metadata; + metadata.x = dcidx; row_height = row_height || td.offsetHeight; if (ridx * row_height > container_height) { break; diff --git a/src/js/thead.js b/src/js/thead.js index 50d979e1..dad87716 100644 --- a/src/js/thead.js +++ b/src/js/thead.js @@ -55,7 +55,7 @@ export class RegularHeaderViewModel extends ViewModel { } const th = this._get_cell("TH", d, cidx); if (!th) return; - th.classList.add("pd-group-header"); + th.setAttribute("colspan", "1"); return th; } @@ -78,7 +78,6 @@ export class RegularHeaderViewModel extends ViewModel { metadata.size_key = `${column}|${type}`; const auto_width = this._column_sizes.auto[metadata.size_key]; const override_width = this._column_sizes.override[metadata.size_key]; - th.classList.add(`pd-${type}`); if (override_width) { th.classList.toggle("pd-cell-clip", auto_width > override_width); th.style.minWidth = override_width + "px"; @@ -98,8 +97,9 @@ export class RegularHeaderViewModel extends ViewModel { _group_header_cache = []; _offset_cache = []; - draw(config, alias, parts, type, cidx, colspan) { - const header_levels = config.column_pivots.length + 1; + draw(config, alias, parts, type, cidx, colspan, dcidx) { + const header_levels = parts?.length; //config.column_pivots.length + 1; + if (header_levels === 0) return {}; let th, column_name, is_new_group = false; @@ -131,6 +131,7 @@ export class RegularHeaderViewModel extends ViewModel { const metadata = this._draw_th(alias || parts, column_name, type, th); metadata.vcidx = vcidx; metadata.cidx = cidx; + metadata.x = dcidx; for (const [group_meta] of this._group_header_cache) { group_meta.cidx = cidx; group_meta.vcidx = vcidx; @@ -142,8 +143,8 @@ export class RegularHeaderViewModel extends ViewModel { } } - if (header_levels === 1 && Array.isArray(type)) { - th.classList.add("pd-group-header"); + if (header_levels === 1 && dcidx === undefined) { + th.setAttribute("colspan", 1); } const metadata = this._get_or_create_metadata(th); this._clean_rows(this._offset_cache.length); diff --git a/src/less/material.less b/src/less/material.less index d5236a9f..e2e60011 100644 --- a/src/less/material.less +++ b/src/less/material.less @@ -85,19 +85,9 @@ regular-table, :host { // frozen rows - tr td.pd-group-header, - tr th { - border-right: 1px solid #ddd; - } - - - tr:last-child th:not(.pd-group-header), - tr th:last-child { - border-right: none; - } - tr:last-child th { + thead tr:last-child th { border-bottom: 1px solid #ddd; } @@ -123,9 +113,6 @@ regular-table, :host { } - tbody { - transition: opacity 0.2s ease-in; - } tbody:hover tr:hover td { background: #eee; @@ -136,9 +123,6 @@ regular-table, :host { color: #333; } - tr { - transition: background-color 0.2s ease-in, color 0.2s ease-in; - } table * { box-sizing: border-box; diff --git a/test/perspective_indices.test.js b/test/perspective_indices.test.js new file mode 100644 index 00000000..1aa87959 --- /dev/null +++ b/test/perspective_indices.test.js @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Copyright (c) 2020, the Regular Table Authors. + * + * This file is part of the Regular Table library, distributed under the terms + * of the Apache License 2.0. The full license can be found in the LICENSE + * file. + * + */ + +describe("perspective_indices.html", () => { + beforeAll(async () => { + await page.setViewport({width: 200, height: 100}); + }); + + describe("Loads a regular-table with perspective backend superstore example", () => { + beforeAll(async () => { + await page.goto("http://localhost:8081/examples/perspective_indices.html"); + await page.waitFor("regular-table table tbody tr td"); + }); + + describe("grouped column headers", () => { + test("with the correct top grouped header", async () => { + const first_tr = await page.$("regular-table thead tr:first-child"); + const cell_values = await page.evaluate((first_tr) => Array.from(first_tr.children).map((x) => x.textContent), first_tr); + expect(cell_values).toEqual([" ", " Furniture "]); + }); + + test("with the correct middle grouped header", async () => { + const first_tr = await page.$("regular-table thead tr:nth-child(2)"); + const cell_values = await page.evaluate((first_tr) => Array.from(first_tr.children).map((x) => x.textContent), first_tr); + expect(cell_values).toEqual([" ", " Bookcases "]); + }); + + test("with the correct bottom grouped header", async () => { + const first_tr = await page.$("regular-table thead tr:last-child"); + const cell_values = await page.evaluate((first_tr) => Array.from(first_tr.children).map((x) => x.textContent), first_tr); + expect(cell_values).toEqual([" ", " Sales "]); + }); + }); + + describe("grouped row headers", () => { + test("with the correct first row's cells", async () => { + const first_tr = await page.$$("regular-table tbody th"); + const cell_values = []; + for (const tr of first_tr) { + cell_values.push(await page.evaluate((tr) => tr.innerHTML, tr)); + } + expect(cell_values).toEqual([ + 'removeTOTAL', + 'removeCentral', + 'removeIllinois', + 'Arlington Heights', + 'Aurora', + ]); + }); + }); + }); +}); diff --git a/test/two_billion_rows/metadata.test.js b/test/two_billion_rows/metadata.test.js index acb2e351..cbeba7d1 100644 --- a/test/two_billion_rows/metadata.test.js +++ b/test/two_billion_rows/metadata.test.js @@ -24,7 +24,8 @@ describe("two_billion_rows.html Metadata", () => { expect(JSON.parse(meta)).toEqual({ cidx: 0, column: ["Column 0"], - ridx: 0, + x: 0, + y: 0, size_key: "Column 0|undefined", value: "0", }); @@ -48,7 +49,8 @@ describe("two_billion_rows.html Metadata", () => { expect(JSON.parse(meta)).toEqual({ cidx: 16, column: ["Column 16"], - ridx: 0, + x: 0, + y: 0, size_key: "Column 16|undefined", value: "16", }); @@ -73,7 +75,8 @@ describe("two_billion_rows.html Metadata", () => { expect(JSON.parse(meta)).toEqual({ cidx: 0, column: ["Column 0"], - ridx: 200002, + x: 0, + y: 200002, size_key: "Column 0|undefined", value: "200,002", }); From 79b3ded02fd6653920bd3e27e2261f5bca9c0e35 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Fri, 29 May 2020 02:17:06 -0400 Subject: [PATCH 5/6] Add minesweeper.html example --- examples/minesweeper.html | 290 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 examples/minesweeper.html diff --git a/examples/minesweeper.html b/examples/minesweeper.html new file mode 100644 index 00000000..31784b40 --- /dev/null +++ b/examples/minesweeper.html @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 0a27c93b1b43e1d3dbfe61438c77021040328656 Mon Sep 17 00:00:00 2001 From: Andrew Stein Date: Fri, 29 May 2020 03:05:01 -0400 Subject: [PATCH 6/6] Added documentation for headers --- README.md | 227 ++++++++++++++++-- examples/2d_array.html | 4 +- examples/canvas_data_model.html | 4 +- examples/minesweeper.html | 109 ++++----- examples/perspective.html | 8 +- ..._indices.html => perspective_headers.html} | 8 +- examples/two_billion_rows.html | 6 +- examples/virtual_indices.html | 12 +- examples/web_worker.html | 6 +- src/js/table.js | 24 +- src/js/tbody.js | 2 +- ...es.test.js => perspective_headers.test.js} | 4 +- test/two_billion_rows/metadata.test.js | 2 +- 13 files changed, 298 insertions(+), 118 deletions(-) rename examples/{perspective_indices.html => perspective_headers.html} (97%) rename test/{perspective_indices.test.js => perspective_headers.test.js} (97%) diff --git a/README.md b/README.md index aaf5f20c..c2264658 100644 --- a/README.md +++ b/README.md @@ -89,12 +89,6 @@ to write a simple _virtual_ data model to access `DATA` and `COLUMN_NAMES` indirectly. ```javascript -const COLUMN_NAMES = [ - "Column 1 (number)", - "Column 2 (string)", - "Column 3 (boolean)", -]; - const DATA = [ [0, 1, 2, 3, 4, 5], ["A", "B", "C", "D", "E", "F"], @@ -102,6 +96,22 @@ const DATA = [ ]; ``` +When clipped by the scrollable viewport, you may end up with a `
` of just +a rectangular region of `DATA`: + +
+ + + + + + + + + + +
0A
1B
+ Here's a simple _virtual_ data model for this example, the function `getDataSlice()`. This function is called by your `` whenever it needs more data, with coordinate arguments, `(x0, y0)` to `(x1, y1)`. Only @@ -111,14 +121,12 @@ this rectangular `slice` of `DATA`: ```javascript function getDataSlice(x0, y0, x1, y1) { const data = DATA.slice(x0, x1).map(col => col.slice(y0, y1)); - const column_indices = COLUMN_NAMES.slice(x0, x1); const num_columns = DATA.length; const num_rows = DATA[0].length; return { num_rows, num_columns, - column_indices, data }; } @@ -126,8 +134,7 @@ function getDataSlice(x0, y0, x1, y1) { For the window (0, 0) to (2, 2), `getDataSlice()` would generate an Object like this, containing the `data` slice, as well as the overall dimensions of -`DATA` itself ( `num_rows`, `num_columns`), for sizing the scroll area, and -`column_indices` which generate `
` column headers in a `fixed` position. +`DATA` itself ( `num_rows`, `num_columns`), for sizing the scroll area. ```json { @@ -136,10 +143,6 @@ like this, containing the `data` slice, as well as the overall dimensions of "data": [ [0, 1], ["A", "B"] - ], - "column_indices": [ - ["Column 1 (number)"], - ["Column 2 (string)"] ] } ``` @@ -161,12 +164,6 @@ scroll, more data will be fetched from `getDataSlice()`, and parts of the - - - - - - @@ -221,6 +218,196 @@ self.addEventListener("message", async (event) => { }); ``` +## Column and Row Headers + +`regular-table` can also generate Hierarchial Row and Column Headers, using +``), or Row Headers (the first +children of each `tbody tr`), via the `column_headers` and `row_headers` +properties (respectively) of your data model's `Response` object. + + +
Column 1 (number)Column 2 (string)
0` elements which layout in a `fixed` position within the virtual table. +It can generate Column Headers (within the `
+ + + + + + + + + + + + + + + + +
Column 1 (number)Column 2 (string)
0A
1B
+ +This can be renderered with `column_headers`, a two dimensional `Array` which +must be of length `x1 - x0`. +one `Array` for every column in your `data` window. A modified +`getDataSlice()` which describes this ``: + +```javascript +const COLUMN_HEADERS = [ + ["Column 1 (number)"], + ["Column 2 (string)"], + ["Column 3 (boolean)"], +]; + +function getDataSlice(x0, y0, x1, y1) { + const data = DATA.slice(x0, x1).map(col => col.slice(y0, y1)); + const column_headers = COLUMN_NAMES.slice(x0, x1); + const num_columns = DATA.length; + const num_rows = DATA[0].length; + + return { + column_headers, + num_rows, + num_columns, + data + }; +} +``` + +Samples response: + +```json +{ + "num_rows": 26, + "num_columns": 3, + "data": [ + [0, 1], + ["A", "B"] + ], + "column_headers": [ + ["Column 1 (number)"], + ["Column 2 (string)"] + ] +} +``` + +Resulting HTML: + +```html + + +
+ + + + + + + + + + + + + + + + +
Column 1 (number)Column 2 (string)
0A
1B
+ +
+``` + +## Hierarchial/Group Headers + +`regular-table` supports multiple `
`, and also uses `colspan` and +`rowspan` to merge simple consecutive names, which allows description of simple +Row and Column Group Hierarchies such as this: + + + + + + + + + + + + + + + + + + + + + + + + + + +
Colgroup 1
Column 1Column 2
Rowgroup 1Row 10A
Row 21B
+ +A sample response object that renders this `` would look like this: + +```json +{ + "num_rows": 26, + "num_columns": 3, + "data": [ + [0, 1], + ["A", "B"] + ], + "row_headers": [ + ["Rowgroup 1", "Row 1"], + ["Rowgroup 1", "Row 2"] + ], + "column_headers": [ + ["Colgroup 1", "Column 1"], + ["Colgroup 1", "Column 2"] + ] +} +``` + +Note that in the rendered HTML below, for these Row and Column `Array`, +repeated elements in a sequence will be automatically merged via `rowspan` and +`colspan` attributes. In this example, e.g. `"Rowgroup 1"` will only output +to one `
` node in the resulting ``: + +```html + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
Colgroup 1
Column 1Column 2
Rowgroup 1Row 10A
Row 21B
+ + +``` + ## Development First install `dev_dependencies`: diff --git a/examples/2d_array.html b/examples/2d_array.html index 350da691..c4d654e7 100644 --- a/examples/2d_array.html +++ b/examples/2d_array.html @@ -31,14 +31,14 @@ function getDataSlice(x0, y0, x1, y1) { const data = DATA.slice(x0, x1).map((col) => col.slice(y0, y1)); - const column_indices = COLUMN_NAMES.slice(x0, x1); + const column_headers = COLUMN_NAMES.slice(x0, x1); const num_columns = DATA.length; const num_rows = DATA[0].length; return { num_rows, num_columns, - column_indices, + column_headers, data, }; } diff --git a/examples/canvas_data_model.html b/examples/canvas_data_model.html index 95a116f5..df5410c4 100644 --- a/examples/canvas_data_model.html +++ b/examples/canvas_data_model.html @@ -132,8 +132,8 @@ } return { data, - row_indices: y1 - y0 === 0 ? [] : Array.from(Array(Math.floor(y1 - y0)).keys()).map((z) => [clamp(y0 + z, 10), (y0 + z) % 10]), - column_indices: column_names.slice(x0, x1).map((x) => [clamp(x, 10), x % 10]), + row_headers: y1 - y0 === 0 ? [] : Array.from(Array(Math.floor(y1 - y0)).keys()).map((z) => [clamp(y0 + z, 10), (y0 + z) % 10]), + column_headers: column_names.slice(x0, x1).map((x) => [clamp(x, 10), x % 10]), num_rows: canvas.height, num_columns: column_names.length, }; diff --git a/examples/minesweeper.html b/examples/minesweeper.html index 31784b40..536e632a 100644 --- a/examples/minesweeper.html +++ b/examples/minesweeper.html @@ -113,59 +113,63 @@