From 02a3bb73cdb5c7d81f5771430a299949cda380e4 Mon Sep 17 00:00:00 2001 From: swistach Date: Tue, 12 Sep 2017 15:19:41 +0200 Subject: [PATCH 1/2] Change: latest Handsontable version. #16 --- package-lock.json | 991 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 529 insertions(+), 464 deletions(-) diff --git a/package-lock.json b/package-lock.json index d963b44..8ae2c24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "angular-handsontable", - "version": "0.0.2", + "version": "1.0.0-beta1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -22,6 +22,17 @@ "tslib": "1.7.1" } }, + "@angular/compiler-cli": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-4.2.6.tgz", + "integrity": "sha1-iiE1Ipnz69Hj8XWBBUFkVmyjBr4=", + "dev": true, + "requires": { + "@angular/tsc-wrapped": "4.2.6", + "minimist": "1.2.0", + "reflect-metadata": "0.1.10" + } + }, "@angular/core": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/@angular/core/-/core-4.2.6.tgz", @@ -76,6 +87,15 @@ "tslib": "1.7.1" } }, + "@angular/tsc-wrapped": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@angular/tsc-wrapped/-/tsc-wrapped-4.2.6.tgz", + "integrity": "sha1-YORLWzjzNA7hTFSlinoHEzxk6Jg=", + "dev": true, + "requires": { + "tsickle": "0.21.6" + } + }, "@types/jasmine": { "version": "2.5.36", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.36.tgz", @@ -189,16 +209,19 @@ "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } }, "anymatch": { "version": "1.3.2", @@ -254,12 +277,6 @@ "is-extglob": "1.0.0" } }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -403,10 +420,10 @@ "enhanced-resolve": "3.3.0", "loader-utils": "1.1.0", "lodash": "4.17.4", - "micromatch": "3.0.4", + "micromatch": "3.1.0", "mkdirp": "0.5.1", "object-assign": "4.1.1", - "source-map-support": "0.4.17" + "source-map-support": "0.4.18" }, "dependencies": { "loader-utils": { @@ -431,6 +448,48 @@ "chalk": "1.1.3", "esutils": "2.0.2", "js-tokens": "3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } } }, "babel-generator": { @@ -529,57 +588,18 @@ "dev": true }, "base": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.1.tgz", - "integrity": "sha1-s2p/ERE4U6NCoVaR2Y4tzIpswnA=", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "cache-base": "0.8.5", + "cache-base": "1.0.1", "class-utils": "0.3.5", "component-emitter": "1.2.1", - "define-property": "0.2.5", - "isobject": "2.1.0", - "lazy-cache": "2.0.2", + "define-property": "1.0.0", + "isobject": "3.0.1", "mixin-deep": "1.2.0", "pascalcase": "0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true - } } }, "base64-arraybuffer": { @@ -640,31 +660,28 @@ "dev": true }, "body-parser": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", - "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.0.tgz", + "integrity": "sha1-07Ik1Gf6LOjUNYnAJFBDJnwJNjQ=", "dev": true, "requires": { - "bytes": "2.4.0", - "content-type": "1.0.2", - "debug": "2.6.7", + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.8", "depd": "1.1.1", "http-errors": "1.6.2", - "iconv-lite": "0.4.15", + "iconv-lite": "0.4.18", "on-finished": "2.3.0", - "qs": "6.4.0", - "raw-body": "2.2.0", + "qs": "6.5.0", + "raw-body": "2.3.1", "type-is": "1.6.15" }, "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "iconv-lite": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", + "dev": true } } }, @@ -809,27 +826,26 @@ "dev": true }, "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, "cache-base": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-0.8.5.tgz", - "integrity": "sha1-YM6zUEAh7O7HAR/TOEt/TpVym/o=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "0.2.3", + "collection-visit": "1.0.0", "component-emitter": "1.2.1", "get-value": "2.0.6", - "has-value": "0.3.1", + "has-value": "1.0.0", "isobject": "3.0.1", - "lazy-cache": "2.0.2", - "set-value": "0.4.3", + "set-value": "2.0.0", "to-object-path": "0.3.0", - "union-value": "0.2.4", - "unset-value": "0.1.2" + "union-value": "1.0.0", + "unset-value": "1.0.0" } }, "callsite": { @@ -844,7 +860,7 @@ "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", "dev": true, "requires": { - "no-case": "2.3.1", + "no-case": "2.3.2", "upper-case": "1.1.3" } }, @@ -873,16 +889,14 @@ } }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "dev": true, "requires": { - "ansi-styles": "2.2.1", + "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "supports-color": "4.4.0" } }, "chokidar": { @@ -944,12 +958,6 @@ "is-data-descriptor": "0.1.4", "kind-of": "5.0.2" } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true } } }, @@ -1009,14 +1017,13 @@ "dev": true }, "collection-visit": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-0.2.3.tgz", - "integrity": "sha1-L2JIPK7MlfCDuaRUo+6eYTmteVc=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "lazy-cache": "2.0.2", - "map-visit": "0.1.5", - "object-visit": "0.3.4" + "map-visit": "1.0.0", + "object-visit": "1.0.1" } }, "color-convert": { @@ -1087,7 +1094,7 @@ "requires": { "debug": "2.6.8", "finalhandler": "1.0.4", - "parseurl": "1.3.1", + "parseurl": "1.3.2", "utils-merge": "1.0.0" } }, @@ -1107,9 +1114,9 @@ "dev": true }, "content-type": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", - "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, "cookie": { @@ -1206,7 +1213,7 @@ "create-hmac": "1.1.6", "diffie-hellman": "5.0.2", "inherits": "2.0.3", - "pbkdf2": "3.0.13", + "pbkdf2": "3.0.14", "public-encrypt": "4.0.0", "randombytes": "2.0.5" } @@ -1697,12 +1704,6 @@ "is-data-descriptor": "0.1.4", "kind-of": "5.0.2" } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true } } }, @@ -1778,80 +1779,25 @@ "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", "dev": true, "requires": { - "iconv-lite": "0.4.18", + "iconv-lite": "0.4.19", "jschardet": "1.5.1", "tmp": "0.0.31" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", - "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", - "dev": true - } } }, "extglob": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-1.1.0.tgz", - "integrity": "sha1-Bni04s5FwOTlD15er7Gw2rW05CQ=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.2.tgz", + "integrity": "sha512-I0+eZBH+jFGL8F5BnIz2ON2nKCjTS3AS3H/5PeSmCp7UVC70Ym8IhdRiQly2juKYQ//f7z1aj1BRpQniFJoU1w==", "dev": true, "requires": { "array-unique": "0.3.2", - "define-property": "0.2.5", + "define-property": "1.0.0", "expand-brackets": "2.1.4", "extend-shallow": "2.0.1", "fragment-cache": "0.2.1", "regex-not": "1.0.0", "snapdragon": "0.8.1", - "to-regex": "2.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.0.2" - } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true - }, - "to-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-2.1.0.tgz", - "integrity": "sha1-4606QM/hGVWaBa6kPkyu+sxekB0=", - "dev": true, - "requires": { - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "regex-not": "0.1.2" - }, - "dependencies": { - "regex-not": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-0.1.2.tgz", - "integrity": "sha1-vH8cSUSxGINT0H3uuRK5TgreJds=", - "dev": true - } - } - } + "to-regex": "3.0.1" } }, "extract-text-webpack-plugin": { @@ -1947,7 +1893,7 @@ "encodeurl": "1.0.1", "escape-html": "1.0.3", "on-finished": "2.3.0", - "parseurl": "1.3.1", + "parseurl": "1.3.2", "statuses": "1.3.1", "unpipe": "1.0.0" } @@ -2770,14 +2716,6 @@ } } }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, "string-width": { "version": "1.0.2", "bundled": true, @@ -2788,6 +2726,14 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, "stringstream": { "version": "0.0.5", "bundled": true, @@ -2916,14 +2862,6 @@ "rmdir": "1.2.0", "temp": "0.8.3", "xtend": "4.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "get-caller-file": { @@ -3034,9 +2972,9 @@ } }, "handsontable": { - "version": "0.34.1", - "resolved": "https://registry.npmjs.org/handsontable/-/handsontable-0.34.1.tgz", - "integrity": "sha512-l53NOw9BRoSNcAZ8H+Zr0hPF5VYIHB8eOhunIjfXVOLWUumhYGpqH5rmcYqhD7tRDsVDVUroADkmKkFUASwicQ==", + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/handsontable/-/handsontable-0.34.3.tgz", + "integrity": "sha512-xhTfJa1DqmhLYffs33QChwVd4YZ7m935nC+Q+dseM3HRIXm2ArhP2PM8o33r9fxPGXbsaPoJqDEzhL3BEo9MXQ==", "requires": { "moment": "2.18.1", "numbro": "1.11.0", @@ -3050,6 +2988,14 @@ "dev": true, "requires": { "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } } }, "has-binary": { @@ -3076,39 +3022,43 @@ "dev": true }, "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "has-values": "1.0.0", + "isobject": "3.0.1" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "isarray": "1.0.0" + "is-buffer": "1.1.5" } } } }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, "hash-base": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", @@ -3159,7 +3109,7 @@ "requires": { "es6-templates": "0.2.3", "fastparse": "1.1.1", - "html-minifier": "3.5.3", + "html-minifier": "3.5.4", "loader-utils": "1.1.0", "object-assign": "4.1.1" }, @@ -3178,9 +3128,9 @@ } }, "html-minifier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.3.tgz", - "integrity": "sha512-iKRzQQDuTCsq0Ultbi/mfJJnR0D3AdZKTq966Gsp92xkmAPCV4Xi08qhJ0Dl3ZAWemSgJ7qZK+UsZc0gFqK6wg==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.4.tgz", + "integrity": "sha512-kzvy0Lvs4anPdqWgeXiLisMqAKyHwgajAQaarzwZJHkTU40/Cbqup873U2WtPem8uPbGddVnPes3wtfzQz3+hg==", "dev": true, "requires": { "camel-case": "3.0.0", @@ -3190,7 +3140,7 @@ "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.0.28" + "uglify-js": "3.1.0" } }, "html-webpack-plugin": { @@ -3200,7 +3150,7 @@ "dev": true, "requires": { "bluebird": "3.5.0", - "html-minifier": "3.5.3", + "html-minifier": "3.5.4", "loader-utils": "0.2.17", "lodash": "4.17.4", "pretty-error": "2.1.1", @@ -3283,9 +3233,9 @@ "dev": true }, "iconv-lite": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", "dev": true }, "ieee754": { @@ -3342,74 +3292,6 @@ "string-width": "2.1.1", "strip-ansi": "4.0.0", "through": "2.3.8" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } } }, "interpret": { @@ -3518,14 +3400,6 @@ "is-accessor-descriptor": "0.1.6", "is-data-descriptor": "0.1.4", "kind-of": "5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true - } } }, "is-dotfile": { @@ -3550,9 +3424,9 @@ "dev": true }, "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-finite": { @@ -3565,13 +3439,10 @@ } }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, "is-glob": { "version": "2.0.1", @@ -3580,14 +3451,6 @@ "dev": true, "requires": { "is-extglob": "1.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - } } }, "is-number": { @@ -3696,7 +3559,7 @@ "istanbul-lib-report": "1.1.1", "istanbul-lib-source-maps": "1.2.1", "istanbul-reports": "1.1.2", - "js-yaml": "3.9.1", + "js-yaml": "3.10.0", "mkdirp": "0.5.1", "once": "1.4.0" } @@ -3751,6 +3614,12 @@ "supports-color": "3.2.3" }, "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -3771,7 +3640,7 @@ "debug": "2.6.8", "istanbul-lib-coverage": "1.1.1", "mkdirp": "0.5.1", - "rimraf": "2.6.1", + "rimraf": "2.6.2", "source-map": "0.5.7" } }, @@ -3797,9 +3666,9 @@ "dev": true }, "js-yaml": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", - "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", "dev": true, "requires": { "argparse": "1.0.9", @@ -3872,7 +3741,7 @@ "dev": true, "requires": { "bluebird": "3.5.0", - "body-parser": "1.17.2", + "body-parser": "1.18.0", "chokidar": "1.7.0", "colors": "1.1.2", "combine-lists": "1.0.1", @@ -3892,7 +3761,7 @@ "optimist": "0.6.1", "qjobs": "1.1.5", "range-parser": "1.2.0", - "rimraf": "2.6.1", + "rimraf": "2.6.2", "safe-buffer": "5.1.1", "socket.io": "1.7.3", "source-map": "0.5.7", @@ -3995,13 +3864,10 @@ } }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", + "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", + "dev": true }, "lazy-cache": { "version": "2.0.2", @@ -4132,13 +3998,12 @@ "dev": true }, "map-visit": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-0.1.5.tgz", - "integrity": "sha1-2+Q5J85VJbgN/BVzpE1oxR8mgWs=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "lazy-cache": "2.0.2", - "object-visit": "0.3.4" + "object-visit": "1.0.1" } }, "md5.js": { @@ -4180,9 +4045,9 @@ } }, "micromatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.0.4.tgz", - "integrity": "sha1-FUPx0EgTRHrIUgAcX1qTNAF4bR0=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.0.tgz", + "integrity": "sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==", "dev": true, "requires": { "arr-diff": "4.0.0", @@ -4190,10 +4055,10 @@ "braces": "2.2.2", "define-property": "1.0.0", "extend-shallow": "2.0.1", - "extglob": "1.1.0", + "extglob": "2.0.2", "fragment-cache": "0.2.1", - "kind-of": "4.0.0", - "nanomatch": "1.2.0", + "kind-of": "5.0.2", + "nanomatch": "1.2.1", "object.pick": "1.3.0", "regex-not": "1.0.0", "snapdragon": "0.8.1", @@ -4259,9 +4124,9 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "mixin-deep": { @@ -4281,6 +4146,14 @@ "dev": true, "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } } }, "moment": { @@ -4308,9 +4181,9 @@ "optional": true }, "nanomatch": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.0.tgz", - "integrity": "sha1-dv2z1K52F+N3GeekBHuECFfAyxw=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.1.tgz", + "integrity": "sha512-yZFZy8D7hJnki1+6+Ky7nJThbPUW6M6aQW4CVk+pgPcU69VdCwLWVIP7Tb5E+xAWROp+HOdjNkp5rnAfCM0XbA==", "dev": true, "requires": { "arr-diff": "4.0.0", @@ -4318,9 +4191,8 @@ "define-property": "1.0.0", "extend-shallow": "2.0.1", "fragment-cache": "0.2.1", - "is-extglob": "2.1.1", "is-odd": "1.0.0", - "kind-of": "4.0.0", + "kind-of": "5.0.2", "object.pick": "1.3.0", "regex-not": "1.0.0", "snapdragon": "0.8.1", @@ -4343,9 +4215,9 @@ "dev": true }, "no-case": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.1.tgz", - "integrity": "sha1-euuhxzpSGEJlVUt9wDuvcg34AIE=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "dev": true, "requires": { "lower-case": "1.1.4" @@ -4531,23 +4403,12 @@ "dev": true }, "object-visit": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-0.3.4.tgz", - "integrity": "sha1-rhXPhvCy/dVRdxY2RIRSxUw9qCk=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "2.1.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } + "isobject": "3.0.1" } }, "object.omit": { @@ -4586,11 +4447,51 @@ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, "lodash": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, @@ -4627,8 +4528,16 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8", + "minimist": "0.0.10", "wordwrap": "0.0.3" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } } }, "options": { @@ -4670,7 +4579,7 @@ "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", "dev": true, "requires": { - "no-case": "2.3.1" + "no-case": "2.3.2" } }, "parse-asn1": { @@ -4683,7 +4592,7 @@ "browserify-aes": "1.0.8", "create-hash": "1.1.3", "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.13" + "pbkdf2": "3.0.14" } }, "parse-glob": { @@ -4696,14 +4605,6 @@ "is-dotfile": "1.0.3", "is-extglob": "1.0.0", "is-glob": "2.0.1" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - } } }, "parse-json": { @@ -4743,9 +4644,9 @@ } }, "parseurl": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", "dev": true }, "pascalcase": { @@ -4793,9 +4694,9 @@ } }, "pbkdf2": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.13.tgz", - "integrity": "sha512-+dCHxDH+djNtjgWmvVC/my3SYBAKpKNqKSjLkp+GtWWYe4XPE+e/PSD2aCanlEZZnqPk2uekTKNC/ccbwd2X2Q==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", "dev": true, "requires": { "create-hash": "1.1.3", @@ -4912,9 +4813,9 @@ "dev": true }, "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", + "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==", "dev": true }, "querystring": { @@ -4937,6 +4838,17 @@ "requires": { "is-number": "3.0.0", "kind-of": "4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } } }, "randombytes": { @@ -4955,14 +4867,23 @@ "dev": true }, "raw-body": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", - "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.1.tgz", + "integrity": "sha512-sxkd1uqaSj41SG5Vet9sNAxBMCMsmZ3LVhRkDlK8SbCpelTUB7JiMGHG70AZS6cFiCRgfNQhU2eLnTHYRFf7LA==", "dev": true, "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.15", + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.18", "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", + "dev": true + } } }, "raw-loader": { @@ -5031,6 +4952,12 @@ "source-map": "0.5.7" } }, + "reflect-metadata": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.10.tgz", + "integrity": "sha1-tPg3BEFqytiZiMmxVjXUfgO5NEo=", + "dev": true + }, "regenerator-runtime": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", @@ -5080,6 +5007,21 @@ "utila": "0.3.3" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, "utila": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", @@ -5153,9 +5095,9 @@ } }, "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "7.1.2" @@ -5256,15 +5198,26 @@ "dev": true }, "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { "extend-shallow": "2.0.1", "is-extendable": "0.1.1", "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "split-string": "3.0.2" + }, + "dependencies": { + "split-string": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.0.2.tgz", + "integrity": "sha512-d6myUSfwmBz1izkY4r7r7I0PL41rh21qUDYK1OgclmGHeoqQoujduGxMbzw6BlF3HKmJR4sMpbWVo7/Xzg4YBQ==", + "dev": true, + "requires": { + "extend-shallow": "2.0.1" + } + } } }, "setimmediate": { @@ -5315,7 +5268,7 @@ "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", "dev": true, "requires": { - "base": "0.11.1", + "base": "0.11.2", "debug": "2.6.8", "define-property": "0.2.5", "extend-shallow": "2.0.1", @@ -5344,12 +5297,6 @@ "is-data-descriptor": "0.1.4", "kind-of": "5.0.2" } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true } } }, @@ -5551,9 +5498,9 @@ } }, "source-map-support": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.17.tgz", - "integrity": "sha512-30c1Ch8FSjV0FwC253iftbbj0dU/OXoSg1LAEGZJUlGgjTNj6cu+DVqJWWIZJY5RXLWV4eFtR+4ouo0VIOYOTg==", + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { "source-map": "0.5.7" @@ -5630,12 +5577,6 @@ "is-data-descriptor": "0.1.4", "kind-of": "5.0.2" } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true } } }, @@ -5668,6 +5609,16 @@ "xtend": "4.0.1" } }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", @@ -5677,24 +5628,13 @@ "safe-buffer": "5.1.1" } }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "3.0.0" } }, "strip-bom": { @@ -5707,10 +5647,13 @@ } }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } }, "symbol-observable": { "version": "1.0.4", @@ -5840,12 +5783,6 @@ "is-data-descriptor": "0.1.4", "kind-of": "5.0.2" } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true } } }, @@ -5871,6 +5808,18 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "tsickle": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.21.6.tgz", + "integrity": "sha1-U7Abl5xcE/2xOvs/uVgXflmRWI0=", + "dev": true, + "requires": { + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "source-map": "0.5.7", + "source-map-support": "0.4.18" + } + }, "tslib": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz", @@ -5900,9 +5849,9 @@ "dev": true }, "uglify-js": { - "version": "3.0.28", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.0.28.tgz", - "integrity": "sha512-0h/qGay016GG2lVav3Kz174F3T2Vjlz2v6HCt+WDQpoXfco0hWwF5gHK9yh88mUYvIC+N7Z8NT8WpjSp1yoqGA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.0.tgz", + "integrity": "sha512-PGUXuTJ5AkrfPsyg0L9/LD+BWYm9feVngbWpW5bg7Q3B7hqDM3xz00tNby4yY0CqjrLTF6CP9wpb/aNITRuSXg==", "dev": true, "requires": { "commander": "2.11.0", @@ -5923,15 +5872,29 @@ "dev": true }, "union-value": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-0.2.4.tgz", - "integrity": "sha1-c3UVJ4ZnkFfns3qmdug0aPwCdPA=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { "arr-union": "3.1.0", "get-value": "2.0.6", "is-extendable": "0.1.1", "set-value": "0.4.3" + }, + "dependencies": { + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } } }, "unpipe": { @@ -5941,13 +5904,43 @@ "dev": true }, "unset-value": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz", - "integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { "has-value": "0.3.1", "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } } }, "upper-case": { @@ -6010,12 +6003,6 @@ "is-data-descriptor": "0.1.4", "kind-of": "5.0.2" } - }, - "kind-of": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.0.2.tgz", - "integrity": "sha512-ru8+TQHbN8956c7ZlkgK5Imjx0GMat3jN45GNIthpPeb+SzLrqSg/NG7llQtIqUTbrdu5Oi0lSnIoJmDTwwSzw==", - "dev": true } } }, @@ -6147,6 +6134,47 @@ "json-stable-stringify": "1.0.1" } }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -6281,6 +6309,43 @@ "requires": { "string-width": "1.0.2", "strip-ansi": "3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } } }, "wrappy": { diff --git a/package.json b/package.json index 6538272..03b0dc7 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@angular/core": "^2.4.7 || ^4.0.0" }, "dependencies": { - "handsontable": "0.34.1" + "handsontable": "0.34.3" }, "devDependencies": { "@angular/common": "~4.2.0", From a87fa1516f29a05b0e59a373b8bbb2666bd583c0 Mon Sep 17 00:00:00 2001 From: swistach Date: Tue, 12 Sep 2017 15:33:21 +0200 Subject: [PATCH 2/2] Release 1.0.0-beta2 --- bundles/index.umd.js | 56024 +++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 28124 insertions(+), 27902 deletions(-) diff --git a/bundles/index.umd.js b/bundles/index.umd.js index a55a031..8c76afe 100644 --- a/bundles/index.umd.js +++ b/bundles/index.umd.js @@ -17665,8 +17665,8 @@ var HotHelper = /** @class */ (function () { * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * Version: 0.34.1 - * Release date: 06/09/2017 (built at 05/09/2017 13:02:28) + * Version: 0.34.3 + * Release date: 12/09/2017 (built at 12/09/2017 13:23:01) */ (function webpackUniversalModuleDefinition(root, factory) { if(true) @@ -17677,7 +17677,7 @@ var HotHelper = /** @class */ (function () { exports["Handsontable"] = factory(require("moment"), require("numbro"), require("pikaday")); else root["Handsontable"] = factory(root["moment"], root["numbro"], root["Pikaday"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_61__, __WEBPACK_EXTERNAL_MODULE_87__, __WEBPACK_EXTERNAL_MODULE_304__) { +})(this, function(__WEBPACK_EXTERNAL_MODULE_63__, __WEBPACK_EXTERNAL_MODULE_80__, __WEBPACK_EXTERNAL_MODULE_213__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -17713,9 +17713,6 @@ return /******/ (function(modules) { // webpackBootstrap /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; -/******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { @@ -17743,7 +17740,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 210); +/******/ return __webpack_require__(__webpack_require__.s = 180); /******/ }) /************************************************************************/ /******/ ([ @@ -17800,7 +17797,7 @@ exports.resetCssTransform = resetCssTransform; exports.isInput = isInput; exports.isOutsideInput = isOutsideInput; -var _browser = __webpack_require__(25); +var _browser = __webpack_require__(26); var _feature = __webpack_require__(34); @@ -18084,7 +18081,7 @@ if (classListSupport) { _hasClass = function _hasClass(element, className) { // http://snipplr.com/view/3561/addclass-removeclass-hasclass/ - return element.className !== void 0 && element.className.test(createClassNameRegExp(className)); + return element.className !== void 0 && createClassNameRegExp(className).test(element.className); }; _addClass = function _addClass(element, className) { @@ -18406,10 +18403,11 @@ function getScrollableElement(element) { } } - if (el.clientHeight <= el.scrollHeight && (props.indexOf(overflowY) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowY) !== -1)) { + // The '+ 1' after the scrollHeight/scrollWidth is to prevent problems with zoomed out Chrome. + if (el.clientHeight <= el.scrollHeight + 1 && (props.indexOf(overflowY) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowY) !== -1)) { return el; } - if (el.clientWidth <= el.scrollWidth && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowX) !== -1)) { + if (el.clientWidth <= el.scrollWidth + 1 && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowX) !== -1)) { return el; } el = el.parentNode; @@ -19396,25 +19394,25 @@ function arrayUnique(array) { /* 3 */ /***/ (function(module, exports, __webpack_require__) { -var global = __webpack_require__(13) - , core = __webpack_require__(44) - , hide = __webpack_require__(32) - , redefine = __webpack_require__(33) - , ctx = __webpack_require__(29) - , PROTOTYPE = 'prototype'; - -var $export = function(type, name, source){ - var IS_FORCED = type & $export.F - , IS_GLOBAL = type & $export.G - , IS_STATIC = type & $export.S - , IS_PROTO = type & $export.P - , IS_BIND = type & $export.B - , target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE] - , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) - , expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}) - , key, own, out, exp; - if(IS_GLOBAL)source = name; - for(key in source){ +var global = __webpack_require__(11); +var core = __webpack_require__(44); +var hide = __webpack_require__(29); +var redefine = __webpack_require__(28); +var ctx = __webpack_require__(30); +var PROTOTYPE = 'prototype'; + +var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]; + var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); + var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}); + var key, own, out, exp; + if (IS_GLOBAL) source = name; + for (key in source) { // contains in native own = !IS_FORCED && target && target[key] !== undefined; // export native or passed @@ -19422,10 +19420,10 @@ var $export = function(type, name, source){ // bind timers to global for call from export context exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; // extend global - if(target)redefine(target, key, out, type & $export.U); + if (target) redefine(target, key, out, type & $export.U); // export - if(exports[key] != out)hide(exports, key, exp); - if(IS_PROTO && expProto[key] != out)expProto[key] = out; + if (exports[key] != out) hide(exports, key, exp); + if (IS_PROTO && expProto[key] != out) expProto[key] = out; } }; global.core = core; @@ -19437,9 +19435,10 @@ $export.P = 8; // proto $export.B = 16; // bind $export.W = 32; // wrap $export.U = 64; // safe -$export.R = 128; // real proto method for `library` +$export.R = 128; // real proto method for `library` module.exports = $export; + /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { @@ -19459,7 +19458,7 @@ var _object = __webpack_require__(1); var _feature = __webpack_require__(34); -var _event = __webpack_require__(7); +var _event = __webpack_require__(8); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -19759,13 +19758,13 @@ function getListenersCounter() { exports.__esModule = true; exports.getPluginName = exports.getRegistredPluginNames = exports.getPlugin = exports.registerPlugin = undefined; -var _pluginHooks = __webpack_require__(8); +var _pluginHooks = __webpack_require__(7); var _pluginHooks2 = _interopRequireDefault(_pluginHooks); var _object = __webpack_require__(1); -var _string = __webpack_require__(27); +var _string = __webpack_require__(32); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -19954,107 +19953,6 @@ function valueAccordingPercent(value, percent) { "use strict"; -exports.__esModule = true; -exports.stopImmediatePropagation = stopImmediatePropagation; -exports.isImmediatePropagationStopped = isImmediatePropagationStopped; -exports.stopPropagation = stopPropagation; -exports.pageX = pageX; -exports.pageY = pageY; -exports.isRightClick = isRightClick; -exports.isLeftClick = isLeftClick; - -var _element = __webpack_require__(0); - -/** - * Prevent other listeners of the same event from being called. - * - * @param {Event} event - */ -function stopImmediatePropagation(event) { - event.isImmediatePropagationEnabled = false; - event.cancelBubble = true; -} - -/** - * Check if event was stopped by `stopImmediatePropagation`. - * - * @param event {Event} - * @returns {Boolean} - */ -function isImmediatePropagationStopped(event) { - return event.isImmediatePropagationEnabled === false; -} - -/** - * Prevent further propagation of the current event (prevent bubbling). - * - * @param event {Event} - */ -function stopPropagation(event) { - // ie8 - // http://msdn.microsoft.com/en-us/library/ie/ff975462(v=vs.85).aspx - if (typeof event.stopPropagation === 'function') { - event.stopPropagation(); - } else { - event.cancelBubble = true; - } -} - -/** - * Get horizontal coordinate of the event object relative to the whole document. - * - * @param {Event} event - * @returns {Number} - */ -function pageX(event) { - if (event.pageX) { - return event.pageX; - } - - return event.clientX + (0, _element.getWindowScrollLeft)(); -} - -/** - * Get vertical coordinate of the event object relative to the whole document. - * - * @param {Event} event - * @returns {Number} - */ -function pageY(event) { - if (event.pageY) { - return event.pageY; - } - - return event.clientY + (0, _element.getWindowScrollTop)(); -} - -/** - * Check if provided event was triggered by clicking the right mouse button. - * - * @param {Event} event DOM Event. - * @returns {Boolean} - */ -function isRightClick(event) { - return event.button === 2; -} - -/** - * Check if provided event was triggered by clicking the left mouse button. - * - * @param {Event} event DOM Event. - * @returns {Boolean} - */ -function isLeftClick(event) { - return event.button === 0; -} - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); @@ -21979,6 +21877,107 @@ var globalSingleton = new Hooks(); exports.default = Hooks; +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; +exports.stopImmediatePropagation = stopImmediatePropagation; +exports.isImmediatePropagationStopped = isImmediatePropagationStopped; +exports.stopPropagation = stopPropagation; +exports.pageX = pageX; +exports.pageY = pageY; +exports.isRightClick = isRightClick; +exports.isLeftClick = isLeftClick; + +var _element = __webpack_require__(0); + +/** + * Prevent other listeners of the same event from being called. + * + * @param {Event} event + */ +function stopImmediatePropagation(event) { + event.isImmediatePropagationEnabled = false; + event.cancelBubble = true; +} + +/** + * Check if event was stopped by `stopImmediatePropagation`. + * + * @param event {Event} + * @returns {Boolean} + */ +function isImmediatePropagationStopped(event) { + return event.isImmediatePropagationEnabled === false; +} + +/** + * Prevent further propagation of the current event (prevent bubbling). + * + * @param event {Event} + */ +function stopPropagation(event) { + // ie8 + // http://msdn.microsoft.com/en-us/library/ie/ff975462(v=vs.85).aspx + if (typeof event.stopPropagation === 'function') { + event.stopPropagation(); + } else { + event.cancelBubble = true; + } +} + +/** + * Get horizontal coordinate of the event object relative to the whole document. + * + * @param {Event} event + * @returns {Number} + */ +function pageX(event) { + if (event.pageX) { + return event.pageX; + } + + return event.clientX + (0, _element.getWindowScrollLeft)(); +} + +/** + * Get vertical coordinate of the event object relative to the whole document. + * + * @param {Event} event + * @returns {Number} + */ +function pageY(event) { + if (event.pageY) { + return event.pageY; + } + + return event.clientY + (0, _element.getWindowScrollTop)(); +} + +/** + * Check if provided event was triggered by clicking the right mouse button. + * + * @param {Event} event DOM Event. + * @returns {Boolean} + */ +function isRightClick(event) { + return event.button === 2; +} + +/** + * Check if provided event was triggered by clicking the left mouse button. + * + * @param {Event} event DOM Event. + * @returns {Boolean} + */ +function isLeftClick(event) { + return event.button === 0; +} + /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { @@ -21989,35 +21988,35 @@ exports.default = Hooks; exports.__esModule = true; exports.getRegisteredRenderers = exports.getRegisteredRendererNames = exports.hasRenderer = exports.getRenderer = exports.registerRenderer = undefined; -var _staticRegister2 = __webpack_require__(50); +var _staticRegister2 = __webpack_require__(62); var _staticRegister3 = _interopRequireDefault(_staticRegister2); -var _cellDecorator = __webpack_require__(264); +var _cellDecorator = __webpack_require__(220); var _cellDecorator2 = _interopRequireDefault(_cellDecorator); -var _autocompleteRenderer = __webpack_require__(265); +var _autocompleteRenderer = __webpack_require__(221); var _autocompleteRenderer2 = _interopRequireDefault(_autocompleteRenderer); -var _checkboxRenderer = __webpack_require__(266); +var _checkboxRenderer = __webpack_require__(222); var _checkboxRenderer2 = _interopRequireDefault(_checkboxRenderer); -var _htmlRenderer = __webpack_require__(267); +var _htmlRenderer = __webpack_require__(223); var _htmlRenderer2 = _interopRequireDefault(_htmlRenderer); -var _numericRenderer = __webpack_require__(268); +var _numericRenderer = __webpack_require__(224); var _numericRenderer2 = _interopRequireDefault(_numericRenderer); -var _passwordRenderer = __webpack_require__(269); +var _passwordRenderer = __webpack_require__(225); var _passwordRenderer2 = _interopRequireDefault(_passwordRenderer); -var _textRenderer = __webpack_require__(270); +var _textRenderer = __webpack_require__(226); var _textRenderer2 = _interopRequireDefault(_textRenderer); @@ -22065,20 +22064,33 @@ exports.getRegisteredRenderers = getValues; /* 10 */ /***/ (function(module, exports, __webpack_require__) { -var store = __webpack_require__(83)('wks') - , uid = __webpack_require__(49) - , Symbol = __webpack_require__(13).Symbol - , USE_SYMBOL = typeof Symbol == 'function'; +var store = __webpack_require__(69)('wks'); +var uid = __webpack_require__(42); +var Symbol = __webpack_require__(11).Symbol; +var USE_SYMBOL = typeof Symbol == 'function'; -var $exports = module.exports = function(name){ +var $exports = module.exports = function (name) { return store[name] || (store[name] = USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); }; $exports.store = store; + /***/ }), /* 11 */ +/***/ (function(module, exports) { + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); +if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef + + +/***/ }), +/* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22087,171 +22099,171 @@ $exports.store = store; exports.__esModule = true; exports.Viewport = exports.TableRenderer = exports.Table = exports.Settings = exports.Selection = exports.Scroll = exports.Overlays = exports.Event = exports.Core = exports.default = exports.Border = exports.TopLeftCornerOverlay = exports.TopOverlay = exports.LeftOverlay = exports.DebugOverlay = exports.RowFilter = exports.ColumnFilter = exports.CellRange = exports.CellCoords = exports.ViewportRowsCalculator = exports.ViewportColumnsCalculator = undefined; -__webpack_require__(98); +__webpack_require__(89); -__webpack_require__(115); +__webpack_require__(103); -__webpack_require__(124); +__webpack_require__(104); -__webpack_require__(125); +__webpack_require__(108); __webpack_require__(109); -__webpack_require__(123); +__webpack_require__(111); -__webpack_require__(106); +__webpack_require__(113); -__webpack_require__(107); +__webpack_require__(114); -__webpack_require__(108); +__webpack_require__(115); -__webpack_require__(97); +__webpack_require__(116); -__webpack_require__(120); +__webpack_require__(117); __webpack_require__(118); -__webpack_require__(116); +__webpack_require__(119); -__webpack_require__(121); +__webpack_require__(120); __webpack_require__(122); -__webpack_require__(117); +__webpack_require__(124); -__webpack_require__(119); +__webpack_require__(125); -__webpack_require__(110); +__webpack_require__(126); -__webpack_require__(111); +__webpack_require__(127); -__webpack_require__(112); +__webpack_require__(128); -__webpack_require__(114); +__webpack_require__(129); -__webpack_require__(113); +__webpack_require__(130); -__webpack_require__(95); +__webpack_require__(131); -__webpack_require__(96); +__webpack_require__(132); -__webpack_require__(91); +__webpack_require__(133); -__webpack_require__(94); +__webpack_require__(134); -__webpack_require__(93); +__webpack_require__(135); -__webpack_require__(92); +__webpack_require__(136); -__webpack_require__(67); +__webpack_require__(78); -__webpack_require__(100); +__webpack_require__(137); -__webpack_require__(101); +__webpack_require__(138); -__webpack_require__(103); +__webpack_require__(140); -__webpack_require__(102); +__webpack_require__(141); -__webpack_require__(99); +__webpack_require__(142); -__webpack_require__(105); +__webpack_require__(143); -__webpack_require__(104); +__webpack_require__(144); -__webpack_require__(126); +__webpack_require__(145); -__webpack_require__(129); +__webpack_require__(146); -__webpack_require__(127); +__webpack_require__(148); -__webpack_require__(128); +__webpack_require__(149); -__webpack_require__(131); +__webpack_require__(150); -__webpack_require__(130); +__webpack_require__(152); -__webpack_require__(133); +__webpack_require__(153); -__webpack_require__(132); +__webpack_require__(154); -var _viewportColumns = __webpack_require__(137); +var _viewportColumns = __webpack_require__(155); var _viewportColumns2 = _interopRequireDefault(_viewportColumns); -var _viewportRows = __webpack_require__(138); +var _viewportRows = __webpack_require__(156); var _viewportRows2 = _interopRequireDefault(_viewportRows); -var _coords = __webpack_require__(42); +var _coords = __webpack_require__(49); var _coords2 = _interopRequireDefault(_coords); -var _range = __webpack_require__(68); +var _range = __webpack_require__(79); var _range2 = _interopRequireDefault(_range); -var _column = __webpack_require__(141); +var _column = __webpack_require__(157); var _column2 = _interopRequireDefault(_column); -var _row = __webpack_require__(142); +var _row = __webpack_require__(158); var _row2 = _interopRequireDefault(_row); -var _debug = __webpack_require__(185); +var _debug = __webpack_require__(204); var _debug2 = _interopRequireDefault(_debug); -var _left = __webpack_require__(186); +var _left = __webpack_require__(206); var _left2 = _interopRequireDefault(_left); -var _top = __webpack_require__(187); +var _top = __webpack_require__(207); var _top2 = _interopRequireDefault(_top); -var _topLeftCorner = __webpack_require__(188); +var _topLeftCorner = __webpack_require__(208); var _topLeftCorner2 = _interopRequireDefault(_topLeftCorner); -var _border = __webpack_require__(136); +var _border = __webpack_require__(167); var _border2 = _interopRequireDefault(_border); -var _core = __webpack_require__(139); +var _core = __webpack_require__(159); var _core2 = _interopRequireDefault(_core); -var _event = __webpack_require__(140); +var _event = __webpack_require__(160); var _event2 = _interopRequireDefault(_event); -var _overlays = __webpack_require__(143); +var _overlays = __webpack_require__(161); var _overlays2 = _interopRequireDefault(_overlays); -var _scroll = __webpack_require__(144); +var _scroll = __webpack_require__(162); var _scroll2 = _interopRequireDefault(_scroll); -var _selection = __webpack_require__(189); +var _selection = __webpack_require__(209); var _selection2 = _interopRequireDefault(_selection); -var _settings = __webpack_require__(145); +var _settings = __webpack_require__(163); var _settings2 = _interopRequireDefault(_settings); -var _table = __webpack_require__(146); +var _table = __webpack_require__(164); var _table2 = _interopRequireDefault(_table); -var _tableRenderer = __webpack_require__(147); +var _tableRenderer = __webpack_require__(165); var _tableRenderer2 = _interopRequireDefault(_tableRenderer); -var _viewport = __webpack_require__(148); +var _viewport = __webpack_require__(166); var _viewport2 = _interopRequireDefault(_viewport); @@ -22280,7 +22292,7 @@ exports.TableRenderer = _tableRenderer2.default; exports.Viewport = _viewport2.default; /***/ }), -/* 12 */ +/* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22294,7 +22306,7 @@ var _object = __webpack_require__(1); var _array = __webpack_require__(2); -var _recordTranslator = __webpack_require__(154); +var _recordTranslator = __webpack_require__(172); var _plugins = __webpack_require__(5); @@ -22538,16 +22550,16 @@ var BasePlugin = function () { exports.default = BasePlugin; /***/ }), -/* 13 */ +/* 14 */ /***/ (function(module, exports) { -// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 -var global = module.exports = typeof window != 'undefined' && window.Math == Math - ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); -if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef +module.exports = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; +}; + /***/ }), -/* 14 */ +/* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22558,55 +22570,55 @@ exports.getRegisteredEditors = exports.getRegisteredEditorNames = exports.hasEdi exports.RegisteredEditor = RegisteredEditor; exports._getEditorInstance = _getEditorInstance; -var _staticRegister2 = __webpack_require__(50); +var _staticRegister2 = __webpack_require__(62); var _staticRegister3 = _interopRequireDefault(_staticRegister2); -var _pluginHooks = __webpack_require__(8); +var _pluginHooks = __webpack_require__(7); var _pluginHooks2 = _interopRequireDefault(_pluginHooks); -var _baseEditor = __webpack_require__(36); +var _baseEditor = __webpack_require__(41); var _baseEditor2 = _interopRequireDefault(_baseEditor); -var _autocompleteEditor = __webpack_require__(149); +var _autocompleteEditor = __webpack_require__(168); var _autocompleteEditor2 = _interopRequireDefault(_autocompleteEditor); -var _checkboxEditor = __webpack_require__(202); +var _checkboxEditor = __webpack_require__(211); var _checkboxEditor2 = _interopRequireDefault(_checkboxEditor); -var _dateEditor = __webpack_require__(203); +var _dateEditor = __webpack_require__(212); var _dateEditor2 = _interopRequireDefault(_dateEditor); -var _dropdownEditor = __webpack_require__(204); +var _dropdownEditor = __webpack_require__(215); var _dropdownEditor2 = _interopRequireDefault(_dropdownEditor); -var _handsontableEditor = __webpack_require__(150); +var _handsontableEditor = __webpack_require__(169); var _handsontableEditor2 = _interopRequireDefault(_handsontableEditor); -var _mobileTextEditor = __webpack_require__(205); +var _mobileTextEditor = __webpack_require__(216); var _mobileTextEditor2 = _interopRequireDefault(_mobileTextEditor); -var _numericEditor = __webpack_require__(206); +var _numericEditor = __webpack_require__(217); var _numericEditor2 = _interopRequireDefault(_numericEditor); -var _passwordEditor = __webpack_require__(207); +var _passwordEditor = __webpack_require__(218); var _passwordEditor2 = _interopRequireDefault(_passwordEditor); -var _selectEditor = __webpack_require__(208); +var _selectEditor = __webpack_require__(219); var _selectEditor2 = _interopRequireDefault(_selectEditor); -var _textEditor = __webpack_require__(43); +var _textEditor = __webpack_require__(50); var _textEditor2 = _interopRequireDefault(_textEditor); @@ -22721,15 +22733,18 @@ exports.getRegisteredEditorNames = getNames; exports.getRegisteredEditors = getValues; /***/ }), -/* 15 */ -/***/ (function(module, exports) { +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = function(it){ - return typeof it === 'object' ? it !== null : typeof it === 'function'; +var isObject = __webpack_require__(14); +module.exports = function (it) { + if (!isObject(it)) throw TypeError(it + ' is not an object!'); + return it; }; + /***/ }), -/* 16 */ +/* 17 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22844,7 +22859,29 @@ function isKey(keyCode, baseCode) { } /***/ }), -/* 17 */ +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +var anObject = __webpack_require__(16); +var IE8_DOM_DEFINE = __webpack_require__(91); +var toPrimitive = __webpack_require__(65); +var dP = Object.defineProperty; + +exports.f = __webpack_require__(20) ? Object.defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; + + +/***/ }), +/* 19 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22870,7 +22907,7 @@ var _array = __webpack_require__(2); var _element = __webpack_require__(0); -var _separator = __webpack_require__(71); +var _separator = __webpack_require__(86); function normalizeSelection(selRange) { return { @@ -23049,38 +23086,29 @@ function filterSeparators(items) { } /***/ }), -/* 18 */ +/* 20 */ /***/ (function(module, exports, __webpack_require__) { -var isObject = __webpack_require__(15); -module.exports = function(it){ - if(!isObject(it))throw TypeError(it + ' is not an object!'); - return it; -}; +// Thank's IE8 for his funny defineProperty +module.exports = !__webpack_require__(23)(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; +}); + /***/ }), -/* 19 */ +/* 21 */ /***/ (function(module, exports, __webpack_require__) { -var anObject = __webpack_require__(18) - , IE8_DOM_DEFINE = __webpack_require__(161) - , toPrimitive = __webpack_require__(86) - , dP = Object.defineProperty; - -exports.f = __webpack_require__(21) ? Object.defineProperty : function defineProperty(O, P, Attributes){ - anObject(O); - P = toPrimitive(P, true); - anObject(Attributes); - if(IE8_DOM_DEFINE)try { - return dP(O, P, Attributes); - } catch(e){ /* empty */ } - if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); - if('value' in Attributes)O[P] = Attributes.value; - return O; +// 7.1.15 ToLength +var toInteger = __webpack_require__(51); +var min = Math.min; +module.exports = function (it) { + return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 }; + /***/ }), -/* 20 */ +/* 22 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23101,7 +23129,7 @@ exports._injectProductInfo = _injectProductInfo; var _element = __webpack_require__(0); -var _templateLiteralTag = __webpack_require__(209); +var _templateLiteralTag = __webpack_require__(205); function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } @@ -23189,7 +23217,7 @@ var _cp = function _cp(v) { return v['\x63\x6F\x64\x65\x50\x6F\x69\x6E\x74\x41\x74'](0) - 65; }; var _norm = function _norm(v) { - return v.replace(/\-/g, ''); + return ('' + v).replace(/\-/g, ''); }; var _extractTime = function _extractTime(v) { return _hd(_ss(_norm(v), _hd('12'), _cp('\x46'))) / (_hd(_ss(_norm(v), _cp('\x42'), ~~![][_m])) || 9); @@ -23210,7 +23238,7 @@ function _injectProductInfo(key, element) { if (trial || schemaValidity) { if (schemaValidity) { - var releaseTime = Math.floor(moment('06/09/2017', 'DD/MM/YYYY').toDate().getTime() / 8.64e7); + var releaseTime = Math.floor(moment('12/09/2017', 'DD/MM/YYYY').toDate().getTime() / 8.64e7); var keyGenTime = _extractTime(key); if (keyGenTime > 45000 || keyGenTime !== parseInt(keyGenTime, 10)) { @@ -23241,7 +23269,7 @@ function _injectProductInfo(key, element) { if (showDomMessage && element.parentNode) { var message = document.createElement('div'); - (0, _element.addClass)(message, 'display-license-info'); + message.id = 'hot-display-license-info'; message.appendChild(document.createTextNode('Evaluation version of Handsontable Pro.')); message.appendChild(document.createElement('br')); message.appendChild(document.createTextNode('Not licensed for production use.')); @@ -23267,47 +23295,42 @@ function _checkKeySchema(v) { /* eslint-enable */ /***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { +/* 23 */ +/***/ (function(module, exports) { + +module.exports = function (exec) { + try { + return !!exec(); + } catch (e) { + return true; + } +}; -// Thank's IE8 for his funny defineProperty -module.exports = !__webpack_require__(31)(function(){ - return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; -}); /***/ }), -/* 22 */ +/* 24 */ /***/ (function(module, exports) { var hasOwnProperty = {}.hasOwnProperty; -module.exports = function(it, key){ +module.exports = function (it, key) { return hasOwnProperty.call(it, key); }; + /***/ }), -/* 23 */ +/* 25 */ /***/ (function(module, exports, __webpack_require__) { // to indexed object, toObject with fallback for non-array-like ES3 strings -var IObject = __webpack_require__(77) - , defined = __webpack_require__(30); -module.exports = function(it){ +var IObject = __webpack_require__(67); +var defined = __webpack_require__(33); +module.exports = function (it) { return IObject(defined(it)); }; -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -// 7.1.15 ToLength -var toInteger = __webpack_require__(60) - , min = Math.min; -module.exports = function(it){ - return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 -}; /***/ }), -/* 25 */ +/* 26 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23354,7 +23377,7 @@ function isMobileBrowser(userAgent) { } /***/ }), -/* 26 */ +/* 27 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23363,23 +23386,23 @@ function isMobileBrowser(userAgent) { exports.__esModule = true; exports.getRegisteredValidators = exports.getRegisteredValidatorNames = exports.hasValidator = exports.getValidator = exports.registerValidator = undefined; -var _staticRegister2 = __webpack_require__(50); +var _staticRegister2 = __webpack_require__(62); var _staticRegister3 = _interopRequireDefault(_staticRegister2); -var _autocompleteValidator = __webpack_require__(275); +var _autocompleteValidator = __webpack_require__(227); var _autocompleteValidator2 = _interopRequireDefault(_autocompleteValidator); -var _dateValidator = __webpack_require__(276); +var _dateValidator = __webpack_require__(228); var _dateValidator2 = _interopRequireDefault(_dateValidator); -var _numericValidator = __webpack_require__(277); +var _numericValidator = __webpack_require__(229); var _numericValidator2 = _interopRequireDefault(_numericValidator); -var _timeValidator = __webpack_require__(278); +var _timeValidator = __webpack_require__(230); var _timeValidator2 = _interopRequireDefault(_timeValidator); @@ -23421,120 +23444,84 @@ exports.getRegisteredValidatorNames = getNames; exports.getRegisteredValidators = getValues; /***/ }), -/* 27 */ +/* 28 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var global = __webpack_require__(11); +var hide = __webpack_require__(29); +var has = __webpack_require__(24); +var SRC = __webpack_require__(42)('src'); +var TO_STRING = 'toString'; +var $toString = Function[TO_STRING]; +var TPL = ('' + $toString).split(TO_STRING); +__webpack_require__(44).inspectSource = function (it) { + return $toString.call(it); +}; -exports.__esModule = true; -exports.toUpperCaseFirst = toUpperCaseFirst; -exports.equalsIgnoreCase = equalsIgnoreCase; -exports.randomString = randomString; -exports.isPercentValue = isPercentValue; -exports.substitute = substitute; -exports.stripTags = stripTags; - -var _mixed = __webpack_require__(20); - -var _number = __webpack_require__(6); - -/** - * Convert string to upper case first letter. - * - * @param {String} string String to convert. - * @returns {String} - */ -function toUpperCaseFirst(string) { - return string[0].toUpperCase() + string.substr(1); -} - -/** - * Compare strings case insensitively. - * - * @param {...String} strings Strings to compare. - * @returns {Boolean} - */ -function equalsIgnoreCase() { - var unique = []; - - for (var _len = arguments.length, strings = Array(_len), _key = 0; _key < _len; _key++) { - strings[_key] = arguments[_key]; - } - - var length = strings.length; - - while (length--) { - var string = (0, _mixed.stringify)(strings[length]).toLowerCase(); - - if (unique.indexOf(string) === -1) { - unique.push(string); - } - } - - return unique.length === 1; -} - -/** - * Generates a random hex string. Used as namespace for Handsontable instance events. - * - * @return {String} Returns 16-long character random string (eq. `'92b1bfc74ec4'`). - */ -function randomString() { - function s4() { - return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); +(module.exports = function (O, key, val, safe) { + var isFunction = typeof val == 'function'; + if (isFunction) has(val, 'name') || hide(val, 'name', key); + if (O[key] === val) return; + if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); + if (O === global) { + O[key] = val; + } else if (!safe) { + delete O[key]; + hide(O, key, val); + } else if (O[key]) { + O[key] = val; + } else { + hide(O, key, val); } +// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative +})(Function.prototype, TO_STRING, function toString() { + return typeof this == 'function' && this[SRC] || $toString.call(this); +}); - return s4() + s4() + s4() + s4(); -} -/** - * Checks if value is valid percent. - * - * @param {String} value - * @returns {Boolean} - */ -function isPercentValue(value) { - return (/^([0-9][0-9]?%$)|(^100%$)/.test(value) - ); -} - -/** - * Substitute strings placed beetwen square brackets into value defined in `variables` object. String names defined in - * square brackets must be the same as property name of `variables` object. - * - * @param {String} template Template string. - * @param {Object} variables Object which contains all available values which can be injected into template. - * @returns {String} - */ -function substitute(template) { - var variables = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { - return ('' + template).replace(/(?:\\)?\[([^[\]]+)]/g, function (match, name) { - if (match.charAt(0) === '\\') { - return match.substr(1, match.length - 1); - } +var dP = __webpack_require__(18); +var createDesc = __webpack_require__(43); +module.exports = __webpack_require__(20) ? function (object, key, value) { + return dP.f(object, key, createDesc(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; - return variables[name] === void 0 ? '' : variables[name]; - }); -} -var STRIP_TAGS_REGEX = /<\/?\w+\/?>|<\w+[\s|/][^>]*>/gi; +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Strip any HTML tag from the string. - * - * @param {String} string String to cut HTML from. - * @return {String} - */ -function stripTags(string) { - string += ''; +// optional / simple context binding +var aFunction = __webpack_require__(54); +module.exports = function (fn, that, length) { + aFunction(fn); + if (that === undefined) return fn; + switch (length) { + case 1: return function (a) { + return fn.call(that, a); + }; + case 2: return function (a, b) { + return fn.call(that, a, b); + }; + case 3: return function (a, b, c) { + return fn.call(that, a, b, c); + }; + } + return function (/* ...args */) { + return fn.apply(that, arguments); + }; +}; - return string.replace(STRIP_TAGS_REGEX, ''); -} /***/ }), -/* 28 */ +/* 31 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23554,7 +23541,7 @@ var _eventManager = __webpack_require__(4); var _eventManager2 = _interopRequireDefault(_eventManager); -var _core = __webpack_require__(139); +var _core = __webpack_require__(159); var _core2 = _interopRequireDefault(_core); @@ -23890,101 +23877,128 @@ var Overlay = function () { exports.default = Overlay; /***/ }), -/* 29 */ +/* 32 */ /***/ (function(module, exports, __webpack_require__) { -// optional / simple context binding -var aFunction = __webpack_require__(72); -module.exports = function(fn, that, length){ - aFunction(fn); - if(that === undefined)return fn; - switch(length){ - case 1: return function(a){ - return fn.call(that, a); - }; - case 2: return function(a, b){ - return fn.call(that, a, b); - }; - case 3: return function(a, b, c){ - return fn.call(that, a, b, c); - }; +"use strict"; + + +exports.__esModule = true; +exports.toUpperCaseFirst = toUpperCaseFirst; +exports.equalsIgnoreCase = equalsIgnoreCase; +exports.randomString = randomString; +exports.isPercentValue = isPercentValue; +exports.substitute = substitute; +exports.stripTags = stripTags; + +var _mixed = __webpack_require__(22); + +var _number = __webpack_require__(6); + +/** + * Convert string to upper case first letter. + * + * @param {String} string String to convert. + * @returns {String} + */ +function toUpperCaseFirst(string) { + return string[0].toUpperCase() + string.substr(1); +} + +/** + * Compare strings case insensitively. + * + * @param {...String} strings Strings to compare. + * @returns {Boolean} + */ +function equalsIgnoreCase() { + var unique = []; + + for (var _len = arguments.length, strings = Array(_len), _key = 0; _key < _len; _key++) { + strings[_key] = arguments[_key]; } - return function(/* ...args */){ - return fn.apply(that, arguments); - }; -}; -/***/ }), -/* 30 */ -/***/ (function(module, exports) { + var length = strings.length; -// 7.2.1 RequireObjectCoercible(argument) -module.exports = function(it){ - if(it == undefined)throw TypeError("Can't call method on " + it); - return it; -}; + while (length--) { + var string = (0, _mixed.stringify)(strings[length]).toLowerCase(); -/***/ }), -/* 31 */ -/***/ (function(module, exports) { + if (unique.indexOf(string) === -1) { + unique.push(string); + } + } -module.exports = function(exec){ - try { - return !!exec(); - } catch(e){ - return true; + return unique.length === 1; +} + +/** + * Generates a random hex string. Used as namespace for Handsontable instance events. + * + * @return {String} Returns 16-long character random string (eq. `'92b1bfc74ec4'`). + */ +function randomString() { + function s4() { + return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); } -}; -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { + return s4() + s4() + s4() + s4(); +} -var dP = __webpack_require__(19) - , createDesc = __webpack_require__(40); -module.exports = __webpack_require__(21) ? function(object, key, value){ - return dP.f(object, key, createDesc(1, value)); -} : function(object, key, value){ - object[key] = value; - return object; -}; +/** + * Checks if value is valid percent. + * + * @param {String} value + * @returns {Boolean} + */ +function isPercentValue(value) { + return (/^([0-9][0-9]?%$)|(^100%$)/.test(value) + ); +} + +/** + * Substitute strings placed beetwen square brackets into value defined in `variables` object. String names defined in + * square brackets must be the same as property name of `variables` object. + * + * @param {String} template Template string. + * @param {Object} variables Object which contains all available values which can be injected into template. + * @returns {String} + */ +function substitute(template) { + var variables = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + return ('' + template).replace(/(?:\\)?\[([^[\]]+)]/g, function (match, name) { + if (match.charAt(0) === '\\') { + return match.substr(1, match.length - 1); + } + + return variables[name] === void 0 ? '' : variables[name]; + }); +} + +var STRIP_TAGS_REGEX = /<\/?\w+\/?>|<\w+[\s|/][^>]*>/gi; + +/** + * Strip any HTML tag from the string. + * + * @param {String} string String to cut HTML from. + * @return {String} + */ +function stripTags(string) { + string += ''; + + return string.replace(STRIP_TAGS_REGEX, ''); +} /***/ }), /* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -var global = __webpack_require__(13) - , hide = __webpack_require__(32) - , has = __webpack_require__(22) - , SRC = __webpack_require__(49)('src') - , TO_STRING = 'toString' - , $toString = Function[TO_STRING] - , TPL = ('' + $toString).split(TO_STRING); +/***/ (function(module, exports) { -__webpack_require__(44).inspectSource = function(it){ - return $toString.call(it); +// 7.2.1 RequireObjectCoercible(argument) +module.exports = function (it) { + if (it == undefined) throw TypeError("Can't call method on " + it); + return it; }; -(module.exports = function(O, key, val, safe){ - var isFunction = typeof val == 'function'; - if(isFunction)has(val, 'name') || hide(val, 'name', key); - if(O[key] === val)return; - if(isFunction)has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); - if(O === global){ - O[key] = val; - } else { - if(!safe){ - delete O[key]; - hide(O, key, val); - } else { - if(O[key])O[key] = val; - else hide(O, key, val); - } - } -// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative -})(Function.prototype, TO_STRING, function toString(){ - return typeof this == 'function' && this[SRC] || $toString.call(this); -}); /***/ }), /* 34 */ @@ -24422,15 +24436,74 @@ function curryRight(func) { /* 36 */ /***/ (function(module, exports, __webpack_require__) { +// 19.1.2.14 / 15.2.3.14 Object.keys(O) +var $keys = __webpack_require__(92); +var enumBugKeys = __webpack_require__(70); + +module.exports = Object.keys || function keys(O) { + return $keys(O, enumBugKeys); +}; + + +/***/ }), +/* 37 */ +/***/ (function(module, exports) { + +var toString = {}.toString; + +module.exports = function (it) { + return toString.call(it).slice(8, -1); +}; + + +/***/ }), +/* 38 */ +/***/ (function(module, exports, __webpack_require__) { + +// 7.1.13 ToObject(argument) +var defined = __webpack_require__(33); +module.exports = function (it) { + return Object(defined(it)); +}; + + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + +var isObject = __webpack_require__(14); +module.exports = function (it, TYPE) { + if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!'); + return it; +}; + + +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { + +// 22.1.3.31 Array.prototype[@@unscopables] +var UNSCOPABLES = __webpack_require__(10)('unscopables'); +var ArrayProto = Array.prototype; +if (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(29)(ArrayProto, UNSCOPABLES, {}); +module.exports = function (key) { + ArrayProto[UNSCOPABLES][key] = true; +}; + + +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { + "use strict"; exports.__esModule = true; exports.EditorState = undefined; -var _src = __webpack_require__(11); +var _src = __webpack_require__(12); -var _mixed = __webpack_require__(20); +var _mixed = __webpack_require__(22); var EditorState = exports.EditorState = { VIRGIN: 'STATE_VIRGIN', // before editing @@ -24686,64 +24759,126 @@ BaseEditor.prototype.checkEditorSection = function () { exports.default = BaseEditor; /***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { +/* 42 */ +/***/ (function(module, exports) { -// 22.1.3.31 Array.prototype[@@unscopables] -var UNSCOPABLES = __webpack_require__(10)('unscopables') - , ArrayProto = Array.prototype; -if(ArrayProto[UNSCOPABLES] == undefined)__webpack_require__(32)(ArrayProto, UNSCOPABLES, {}); -module.exports = function(key){ - ArrayProto[UNSCOPABLES][key] = true; +var id = 0; +var px = Math.random(); +module.exports = function (key) { + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); }; + /***/ }), -/* 38 */ +/* 43 */ /***/ (function(module, exports) { -var toString = {}.toString; - -module.exports = function(it){ - return toString.call(it).slice(8, -1); +module.exports = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; }; + /***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { +/* 44 */ +/***/ (function(module, exports) { -// 19.1.2.14 / 15.2.3.14 Object.keys(O) -var $keys = __webpack_require__(170) - , enumBugKeys = __webpack_require__(75); +var core = module.exports = { version: '2.5.1' }; +if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef -module.exports = Object.keys || function keys(O){ - return $keys(O, enumBugKeys); -}; /***/ }), -/* 40 */ +/* 45 */ /***/ (function(module, exports) { -module.exports = function(bitmap, value){ - return { - enumerable : !(bitmap & 1), - configurable: !(bitmap & 2), - writable : !(bitmap & 4), - value : value - }; +module.exports = {}; + + +/***/ }), +/* 46 */ +/***/ (function(module, exports, __webpack_require__) { + +var def = __webpack_require__(18).f; +var has = __webpack_require__(24); +var TAG = __webpack_require__(10)('toStringTag'); + +module.exports = function (it, tag, stat) { + if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); }; + /***/ }), -/* 41 */ +/* 47 */ /***/ (function(module, exports, __webpack_require__) { -// 7.1.13 ToObject(argument) -var defined = __webpack_require__(30); -module.exports = function(it){ - return Object(defined(it)); +var META = __webpack_require__(42)('meta'); +var isObject = __webpack_require__(14); +var has = __webpack_require__(24); +var setDesc = __webpack_require__(18).f; +var id = 0; +var isExtensible = Object.isExtensible || function () { + return true; +}; +var FREEZE = !__webpack_require__(23)(function () { + return isExtensible(Object.preventExtensions({})); +}); +var setMeta = function (it) { + setDesc(it, META, { value: { + i: 'O' + ++id, // object ID + w: {} // weak collections IDs + } }); +}; +var fastKey = function (it, create) { + // return primitive with prefix + if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; + if (!has(it, META)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return 'F'; + // not necessary to add metadata + if (!create) return 'E'; + // add missing metadata + setMeta(it); + // return object ID + } return it[META].i; +}; +var getWeak = function (it, create) { + if (!has(it, META)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return true; + // not necessary to add metadata + if (!create) return false; + // add missing metadata + setMeta(it); + // return hash weak collections IDs + } return it[META].w; +}; +// add metadata on freeze-family methods calling +var onFreeze = function (it) { + if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it); + return it; +}; +var meta = module.exports = { + KEY: META, + NEED: false, + fastKey: fastKey, + getWeak: getWeak, + onFreeze: onFreeze }; + /***/ }), -/* 42 */ +/* 48 */ +/***/ (function(module, exports) { + +exports.f = {}.propertyIsEnumerable; + + +/***/ }), +/* 49 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24877,7 +25012,7 @@ var CellCoords = function () { exports.default = CellCoords; /***/ }), -/* 43 */ +/* 50 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24887,11 +25022,11 @@ exports.__esModule = true; var _element = __webpack_require__(0); -var _autoResize = __webpack_require__(184); +var _autoResize = __webpack_require__(210); var _autoResize2 = _interopRequireDefault(_autoResize); -var _baseEditor = __webpack_require__(36); +var _baseEditor = __webpack_require__(41); var _baseEditor2 = _interopRequireDefault(_baseEditor); @@ -24899,9 +25034,9 @@ var _eventManager = __webpack_require__(4); var _eventManager2 = _interopRequireDefault(_eventManager); -var _unicode = __webpack_require__(16); +var _unicode = __webpack_require__(17); -var _event = __webpack_require__(7); +var _event = __webpack_require__(8); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -25271,106 +25406,286 @@ TextEditor.prototype.destroy = function () { exports.default = TextEditor; /***/ }), -/* 44 */ +/* 51 */ /***/ (function(module, exports) { -var core = module.exports = {version: '2.4.0'}; -if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef +// 7.1.4 ToInteger +var ceil = Math.ceil; +var floor = Math.floor; +module.exports = function (it) { + return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); +}; + /***/ }), -/* 45 */ -/***/ (function(module, exports) { +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { + +var toInteger = __webpack_require__(51); +var max = Math.max; +var min = Math.min; +module.exports = function (index, length) { + index = toInteger(index); + return index < 0 ? max(index + length, 0) : min(index, length); +}; -module.exports = {}; /***/ }), -/* 46 */ +/* 53 */ /***/ (function(module, exports, __webpack_require__) { -var META = __webpack_require__(49)('meta') - , isObject = __webpack_require__(15) - , has = __webpack_require__(22) - , setDesc = __webpack_require__(19).f - , id = 0; -var isExtensible = Object.isExtensible || function(){ - return true; -}; -var FREEZE = !__webpack_require__(31)(function(){ - return isExtensible(Object.preventExtensions({})); -}); -var setMeta = function(it){ - setDesc(it, META, {value: { - i: 'O' + ++id, // object ID - w: {} // weak collections IDs - }}); -}; -var fastKey = function(it, create){ - // return primitive with prefix - if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; - if(!has(it, META)){ - // can't set metadata to uncaught frozen object - if(!isExtensible(it))return 'F'; - // not necessary to add metadata - if(!create)return 'E'; - // add missing metadata - setMeta(it); - // return object ID - } return it[META].i; -}; -var getWeak = function(it, create){ - if(!has(it, META)){ - // can't set metadata to uncaught frozen object - if(!isExtensible(it))return true; - // not necessary to add metadata - if(!create)return false; - // add missing metadata - setMeta(it); - // return hash weak collections IDs - } return it[META].w; +var redefine = __webpack_require__(28); +module.exports = function (target, src, safe) { + for (var key in src) redefine(target, key, src[key], safe); + return target; }; -// add metadata on freeze-family methods calling -var onFreeze = function(it){ - if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it); + + +/***/ }), +/* 54 */ +/***/ (function(module, exports) { + +module.exports = function (it) { + if (typeof it != 'function') throw TypeError(it + ' is not a function!'); return it; }; -var meta = module.exports = { - KEY: META, - NEED: false, - fastKey: fastKey, - getWeak: getWeak, - onFreeze: onFreeze + + +/***/ }), +/* 55 */ +/***/ (function(module, exports) { + +module.exports = function (it, Constructor, name, forbiddenField) { + if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) { + throw TypeError(name + ': incorrect invocation!'); + } return it; }; + /***/ }), -/* 47 */ +/* 56 */ +/***/ (function(module, exports, __webpack_require__) { + +var ctx = __webpack_require__(30); +var call = __webpack_require__(95); +var isArrayIter = __webpack_require__(96); +var anObject = __webpack_require__(16); +var toLength = __webpack_require__(21); +var getIterFn = __webpack_require__(97); +var BREAK = {}; +var RETURN = {}; +var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) { + var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable); + var f = ctx(fn, that, entries ? 2 : 1); + var index = 0; + var length, step, iterator, result; + if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!'); + // fast case for arrays with default iterator + if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) { + result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); + if (result === BREAK || result === RETURN) return result; + } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) { + result = call(iterator, f, step.value, entries); + if (result === BREAK || result === RETURN) return result; + } +}; +exports.BREAK = BREAK; +exports.RETURN = RETURN; + + +/***/ }), +/* 57 */ /***/ (function(module, exports) { -exports.f = {}.propertyIsEnumerable; +module.exports = false; + /***/ }), -/* 48 */ +/* 58 */ /***/ (function(module, exports, __webpack_require__) { -var def = __webpack_require__(19).f - , has = __webpack_require__(22) - , TAG = __webpack_require__(10)('toStringTag'); +"use strict"; + +var global = __webpack_require__(11); +var $export = __webpack_require__(3); +var redefine = __webpack_require__(28); +var redefineAll = __webpack_require__(53); +var meta = __webpack_require__(47); +var forOf = __webpack_require__(56); +var anInstance = __webpack_require__(55); +var isObject = __webpack_require__(14); +var fails = __webpack_require__(23); +var $iterDetect = __webpack_require__(71); +var setToStringTag = __webpack_require__(46); +var inheritIfRequired = __webpack_require__(184); + +module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) { + var Base = global[NAME]; + var C = Base; + var ADDER = IS_MAP ? 'set' : 'add'; + var proto = C && C.prototype; + var O = {}; + var fixMethod = function (KEY) { + var fn = proto[KEY]; + redefine(proto, KEY, + KEY == 'delete' ? function (a) { + return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); + } : KEY == 'has' ? function has(a) { + return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); + } : KEY == 'get' ? function get(a) { + return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a); + } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; } + : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; } + ); + }; + if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () { + new C().entries().next(); + }))) { + // create collection constructor + C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER); + redefineAll(C.prototype, methods); + meta.NEED = true; + } else { + var instance = new C(); + // early implementations not supports chaining + var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance; + // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false + var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); }); + // most early implementations doesn't supports iterables, most modern - not close it correctly + var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new + // for early implementations -0 and +0 not the same + var BUGGY_ZERO = !IS_WEAK && fails(function () { + // V8 ~ Chromium 42- fails only with 5+ elements + var $instance = new C(); + var index = 5; + while (index--) $instance[ADDER](index, index); + return !$instance.has(-0); + }); + if (!ACCEPT_ITERABLES) { + C = wrapper(function (target, iterable) { + anInstance(target, C, NAME); + var that = inheritIfRequired(new Base(), target, C); + if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that); + return that; + }); + C.prototype = proto; + proto.constructor = C; + } + if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) { + fixMethod('delete'); + fixMethod('has'); + IS_MAP && fixMethod('get'); + } + if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER); + // weak collections should not contains .clear method + if (IS_WEAK && proto.clear) delete proto.clear; + } + + setToStringTag(C, NAME); + + O[NAME] = C; + $export($export.G + $export.W + $export.F * (C != Base), O); -module.exports = function(it, tag, stat){ - if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); + if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP); + + return C; }; + /***/ }), -/* 49 */ +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +// 0 -> Array#forEach +// 1 -> Array#map +// 2 -> Array#filter +// 3 -> Array#some +// 4 -> Array#every +// 5 -> Array#find +// 6 -> Array#findIndex +var ctx = __webpack_require__(30); +var IObject = __webpack_require__(67); +var toObject = __webpack_require__(38); +var toLength = __webpack_require__(21); +var asc = __webpack_require__(185); +module.exports = function (TYPE, $create) { + var IS_MAP = TYPE == 1; + var IS_FILTER = TYPE == 2; + var IS_SOME = TYPE == 3; + var IS_EVERY = TYPE == 4; + var IS_FIND_INDEX = TYPE == 6; + var NO_HOLES = TYPE == 5 || IS_FIND_INDEX; + var create = $create || asc; + return function ($this, callbackfn, that) { + var O = toObject($this); + var self = IObject(O); + var f = ctx(callbackfn, that, 3); + var length = toLength(self.length); + var index = 0; + var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined; + var val, res; + for (;length > index; index++) if (NO_HOLES || index in self) { + val = self[index]; + res = f(val, index, O); + if (TYPE) { + if (IS_MAP) result[index] = res; // map + else if (res) switch (TYPE) { + case 3: return true; // some + case 5: return val; // find + case 6: return index; // findIndex + case 2: result.push(val); // filter + } else if (IS_EVERY) return false; // every + } + } + return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result; + }; +}; + + +/***/ }), +/* 60 */ /***/ (function(module, exports) { -var id = 0 - , px = Math.random(); -module.exports = function(key){ - return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); +exports.f = Object.getOwnPropertySymbols; + + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var hide = __webpack_require__(29); +var redefine = __webpack_require__(28); +var fails = __webpack_require__(23); +var defined = __webpack_require__(33); +var wks = __webpack_require__(10); + +module.exports = function (KEY, length, exec) { + var SYMBOL = wks(KEY); + var fns = exec(defined, SYMBOL, ''[KEY]); + var strfn = fns[0]; + var rxfn = fns[1]; + if (fails(function () { + var O = {}; + O[SYMBOL] = function () { return 7; }; + return ''[KEY](O) != 7; + })) { + redefine(String.prototype, KEY, strfn); + hide(RegExp.prototype, SYMBOL, length == 2 + // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue) + // 21.2.5.11 RegExp.prototype[@@split](string, limit) + ? function (string, arg) { return rxfn.call(string, this, arg); } + // 21.2.5.6 RegExp.prototype[@@match](string) + // 21.2.5.9 RegExp.prototype[@@search](string) + : function (string) { return rxfn.call(string, this); } + ); + } }; + /***/ }), -/* 50 */ +/* 62 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25449,470 +25764,1112 @@ function staticRegister() { } /***/ }), -/* 51 */ +/* 63 */ /***/ (function(module, exports) { -module.exports = function(it, Constructor, name, forbiddenField){ - if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){ - throw TypeError(name + ': incorrect invocation!'); - } return it; -}; +module.exports = __WEBPACK_EXTERNAL_MODULE_63__; /***/ }), -/* 52 */ +/* 64 */ /***/ (function(module, exports, __webpack_require__) { -// 0 -> Array#forEach -// 1 -> Array#map -// 2 -> Array#filter -// 3 -> Array#some -// 4 -> Array#every -// 5 -> Array#find -// 6 -> Array#findIndex -var ctx = __webpack_require__(29) - , IObject = __webpack_require__(77) - , toObject = __webpack_require__(41) - , toLength = __webpack_require__(24) - , asc = __webpack_require__(282); -module.exports = function(TYPE, $create){ - var IS_MAP = TYPE == 1 - , IS_FILTER = TYPE == 2 - , IS_SOME = TYPE == 3 - , IS_EVERY = TYPE == 4 - , IS_FIND_INDEX = TYPE == 6 - , NO_HOLES = TYPE == 5 || IS_FIND_INDEX - , create = $create || asc; - return function($this, callbackfn, that){ - var O = toObject($this) - , self = IObject(O) - , f = ctx(callbackfn, that, 3) - , length = toLength(self.length) - , index = 0 - , result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined - , val, res; - for(;length > index; index++)if(NO_HOLES || index in self){ - val = self[index]; - res = f(val, index, O); - if(TYPE){ - if(IS_MAP)result[index] = res; // map - else if(res)switch(TYPE){ - case 3: return true; // some - case 5: return val; // find - case 6: return index; // findIndex - case 2: result.push(val); // filter - } else if(IS_EVERY)return false; // every - } - } - return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result; - }; +var isObject = __webpack_require__(14); +var document = __webpack_require__(11).document; +// typeof document.createElement is 'object' in old IE +var is = isObject(document) && isObject(document.createElement); +module.exports = function (it) { + return is ? document.createElement(it) : {}; }; + /***/ }), -/* 53 */ +/* 65 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// 7.1.1 ToPrimitive(input [, PreferredType]) +var isObject = __webpack_require__(14); +// instead of the ES6 spec version, we didn't implement @@toPrimitive case +// and the second argument - flag - preferred type is a string +module.exports = function (it, S) { + if (!isObject(it)) return it; + var fn, val; + if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; + if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; + if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; + throw TypeError("Can't convert object to primitive value"); +}; -var global = __webpack_require__(13) - , $export = __webpack_require__(3) - , redefine = __webpack_require__(33) - , redefineAll = __webpack_require__(58) - , meta = __webpack_require__(46) - , forOf = __webpack_require__(55) - , anInstance = __webpack_require__(51) - , isObject = __webpack_require__(15) - , fails = __webpack_require__(31) - , $iterDetect = __webpack_require__(78) - , setToStringTag = __webpack_require__(48) - , inheritIfRequired = __webpack_require__(285); - -module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ - var Base = global[NAME] - , C = Base - , ADDER = IS_MAP ? 'set' : 'add' - , proto = C && C.prototype - , O = {}; - var fixMethod = function(KEY){ - var fn = proto[KEY]; - redefine(proto, KEY, - KEY == 'delete' ? function(a){ - return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); - } : KEY == 'has' ? function has(a){ - return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); - } : KEY == 'get' ? function get(a){ - return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a); - } : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; } - : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; } - ); - }; - if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){ - new C().entries().next(); - }))){ - // create collection constructor - C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER); - redefineAll(C.prototype, methods); - meta.NEED = true; - } else { - var instance = new C - // early implementations not supports chaining - , HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance - // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false - , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); }) - // most early implementations doesn't supports iterables, most modern - not close it correctly - , ACCEPT_ITERABLES = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new - // for early implementations -0 and +0 not the same - , BUGGY_ZERO = !IS_WEAK && fails(function(){ - // V8 ~ Chromium 42- fails only with 5+ elements - var $instance = new C() - , index = 5; - while(index--)$instance[ADDER](index, index); - return !$instance.has(-0); - }); - if(!ACCEPT_ITERABLES){ - C = wrapper(function(target, iterable){ - anInstance(target, C, NAME); - var that = inheritIfRequired(new Base, target, C); - if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that); - return that; - }); - C.prototype = proto; - proto.constructor = C; - } - if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){ - fixMethod('delete'); - fixMethod('has'); - IS_MAP && fixMethod('get'); - } - if(BUGGY_ZERO || HASNT_CHAINING)fixMethod(ADDER); - // weak collections should not contains .clear method - if(IS_WEAK && proto.clear)delete proto.clear; - } - setToStringTag(C, NAME); +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { - O[NAME] = C; - $export($export.G + $export.W + $export.F * (C != Base), O); +// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) +var anObject = __webpack_require__(16); +var dPs = __webpack_require__(181); +var enumBugKeys = __webpack_require__(70); +var IE_PROTO = __webpack_require__(68)('IE_PROTO'); +var Empty = function () { /* empty */ }; +var PROTOTYPE = 'prototype'; - if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP); +// Create object with fake `null` prototype: use iframe Object with cleared prototype +var createDict = function () { + // Thrash, waste and sodomy: IE GC bug + var iframe = __webpack_require__(64)('iframe'); + var i = enumBugKeys.length; + var lt = '<'; + var gt = '>'; + var iframeDocument; + iframe.style.display = 'none'; + __webpack_require__(94).appendChild(iframe); + iframe.src = 'javascript:'; // eslint-disable-line no-script-url + // createDict = iframe.contentWindow.Object; + // html.removeChild(iframe); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; + return createDict(); +}; - return C; +module.exports = Object.create || function create(O, Properties) { + var result; + if (O !== null) { + Empty[PROTOTYPE] = anObject(O); + result = new Empty(); + Empty[PROTOTYPE] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO] = O; + } else result = createDict(); + return Properties === undefined ? result : dPs(result, Properties); }; + /***/ }), -/* 54 */ +/* 67 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -var hide = __webpack_require__(32) - , redefine = __webpack_require__(33) - , fails = __webpack_require__(31) - , defined = __webpack_require__(30) - , wks = __webpack_require__(10); - -module.exports = function(KEY, length, exec){ - var SYMBOL = wks(KEY) - , fns = exec(defined, SYMBOL, ''[KEY]) - , strfn = fns[0] - , rxfn = fns[1]; - if(fails(function(){ - var O = {}; - O[SYMBOL] = function(){ return 7; }; - return ''[KEY](O) != 7; - })){ - redefine(String.prototype, KEY, strfn); - hide(RegExp.prototype, SYMBOL, length == 2 - // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue) - // 21.2.5.11 RegExp.prototype[@@split](string, limit) - ? function(string, arg){ return rxfn.call(string, this, arg); } - // 21.2.5.6 RegExp.prototype[@@match](string) - // 21.2.5.9 RegExp.prototype[@@search](string) - : function(string){ return rxfn.call(string, this); } - ); - } +// fallback for non-array-like ES3 and non-enumerable old V8 strings +var cof = __webpack_require__(37); +// eslint-disable-next-line no-prototype-builtins +module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { + return cof(it) == 'String' ? it.split('') : Object(it); }; + /***/ }), -/* 55 */ +/* 68 */ /***/ (function(module, exports, __webpack_require__) { -var ctx = __webpack_require__(29) - , call = __webpack_require__(166) - , isArrayIter = __webpack_require__(162) - , anObject = __webpack_require__(18) - , toLength = __webpack_require__(24) - , getIterFn = __webpack_require__(177) - , BREAK = {} - , RETURN = {}; -var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){ - var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable) - , f = ctx(fn, that, entries ? 2 : 1) - , index = 0 - , length, step, iterator, result; - if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!'); - // fast case for arrays with default iterator - if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){ - result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); - if(result === BREAK || result === RETURN)return result; - } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){ - result = call(iterator, f, step.value, entries); - if(result === BREAK || result === RETURN)return result; - } +var shared = __webpack_require__(69)('keys'); +var uid = __webpack_require__(42); +module.exports = function (key) { + return shared[key] || (shared[key] = uid(key)); }; -exports.BREAK = BREAK; -exports.RETURN = RETURN; + /***/ }), -/* 56 */ -/***/ (function(module, exports) { +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(11); +var SHARED = '__core-js_shared__'; +var store = global[SHARED] || (global[SHARED] = {}); +module.exports = function (key) { + return store[key] || (store[key] = {}); +}; -module.exports = false; /***/ }), -/* 57 */ +/* 70 */ /***/ (function(module, exports) { -exports.f = Object.getOwnPropertySymbols; +// IE 8- don't enum bug keys +module.exports = ( + 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' +).split(','); + /***/ }), -/* 58 */ +/* 71 */ /***/ (function(module, exports, __webpack_require__) { -var redefine = __webpack_require__(33); -module.exports = function(target, src, safe){ - for(var key in src)redefine(target, key, src[key], safe); - return target; +var ITERATOR = __webpack_require__(10)('iterator'); +var SAFE_CLOSING = false; + +try { + var riter = [7][ITERATOR](); + riter['return'] = function () { SAFE_CLOSING = true; }; + // eslint-disable-next-line no-throw-literal + Array.from(riter, function () { throw 2; }); +} catch (e) { /* empty */ } + +module.exports = function (exec, skipClosing) { + if (!skipClosing && !SAFE_CLOSING) return false; + var safe = false; + try { + var arr = [7]; + var iter = arr[ITERATOR](); + iter.next = function () { return { done: safe = true }; }; + arr[ITERATOR] = function () { return iter; }; + exec(arr); + } catch (e) { /* empty */ } + return safe; }; + /***/ }), -/* 59 */ +/* 72 */ /***/ (function(module, exports, __webpack_require__) { -var toInteger = __webpack_require__(60) - , max = Math.max - , min = Math.min; -module.exports = function(index, length){ - index = toInteger(index); - return index < 0 ? max(index + length, 0) : min(index, length); +var pIE = __webpack_require__(48); +var createDesc = __webpack_require__(43); +var toIObject = __webpack_require__(25); +var toPrimitive = __webpack_require__(65); +var has = __webpack_require__(24); +var IE8_DOM_DEFINE = __webpack_require__(91); +var gOPD = Object.getOwnPropertyDescriptor; + +exports.f = __webpack_require__(20) ? gOPD : function getOwnPropertyDescriptor(O, P) { + O = toIObject(O); + P = toPrimitive(P, true); + if (IE8_DOM_DEFINE) try { + return gOPD(O, P); + } catch (e) { /* empty */ } + if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]); }; + /***/ }), -/* 60 */ -/***/ (function(module, exports) { +/* 73 */ +/***/ (function(module, exports, __webpack_require__) { -// 7.1.4 ToInteger -var ceil = Math.ceil - , floor = Math.floor; -module.exports = function(it){ - return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); +var ctx = __webpack_require__(30); +var invoke = __webpack_require__(188); +var html = __webpack_require__(94); +var cel = __webpack_require__(64); +var global = __webpack_require__(11); +var process = global.process; +var setTask = global.setImmediate; +var clearTask = global.clearImmediate; +var MessageChannel = global.MessageChannel; +var Dispatch = global.Dispatch; +var counter = 0; +var queue = {}; +var ONREADYSTATECHANGE = 'onreadystatechange'; +var defer, channel, port; +var run = function () { + var id = +this; + // eslint-disable-next-line no-prototype-builtins + if (queue.hasOwnProperty(id)) { + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; +var listener = function (event) { + run.call(event.data); +}; +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if (!setTask || !clearTask) { + setTask = function setImmediate(fn) { + var args = []; + var i = 1; + while (arguments.length > i) args.push(arguments[i++]); + queue[++counter] = function () { + // eslint-disable-next-line no-new-func + invoke(typeof fn == 'function' ? fn : Function(fn), args); + }; + defer(counter); + return counter; + }; + clearTask = function clearImmediate(id) { + delete queue[id]; + }; + // Node.js 0.8- + if (__webpack_require__(37)(process) == 'process') { + defer = function (id) { + process.nextTick(ctx(run, id, 1)); + }; + // Sphere (JS game engine) Dispatch API + } else if (Dispatch && Dispatch.now) { + defer = function (id) { + Dispatch.now(ctx(run, id, 1)); + }; + // Browsers with MessageChannel, includes WebWorkers + } else if (MessageChannel) { + channel = new MessageChannel(); + port = channel.port2; + channel.port1.onmessage = listener; + defer = ctx(port.postMessage, port, 1); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) { + defer = function (id) { + global.postMessage(id + '', '*'); + }; + global.addEventListener('message', listener, false); + // IE8- + } else if (ONREADYSTATECHANGE in cel('script')) { + defer = function (id) { + html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () { + html.removeChild(this); + run.call(id); + }; + }; + // Rest old browsers + } else { + defer = function (id) { + setTimeout(ctx(run, id, 1), 0); + }; + } +} +module.exports = { + set: setTask, + clear: clearTask }; -/***/ }), -/* 61 */ -/***/ (function(module, exports) { - -module.exports = __WEBPACK_EXTERNAL_MODULE_61__; /***/ }), -/* 62 */ +/* 74 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) +var $keys = __webpack_require__(92); +var hiddenKeys = __webpack_require__(70).concat('length', 'prototype'); +exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return $keys(O, hiddenKeys); +}; -exports.__esModule = true; -exports.getRegisteredCellTypes = exports.getRegisteredCellTypeNames = exports.hasCellType = exports.getCellType = exports.registerCellType = undefined; -var _staticRegister2 = __webpack_require__(50); +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { -var _staticRegister3 = _interopRequireDefault(_staticRegister2); +// helper for String#{startsWith, endsWith, includes} +var isRegExp = __webpack_require__(123); +var defined = __webpack_require__(33); -var _editors = __webpack_require__(14); +module.exports = function (that, searchString, NAME) { + if (isRegExp(searchString)) throw TypeError('String#' + NAME + " doesn't accept regex!"); + return String(defined(that)); +}; -var _renderers = __webpack_require__(9); -var _validators = __webpack_require__(26); +/***/ }), +/* 76 */ +/***/ (function(module, exports, __webpack_require__) { -var _autocompleteType = __webpack_require__(190); +var MATCH = __webpack_require__(10)('match'); +module.exports = function (KEY) { + var re = /./; + try { + '/./'[KEY](re); + } catch (e) { + try { + re[MATCH] = false; + return !'/./'[KEY](re); + } catch (f) { /* empty */ } + } return true; +}; -var _autocompleteType2 = _interopRequireDefault(_autocompleteType); -var _checkboxType = __webpack_require__(191); +/***/ }), +/* 77 */ +/***/ (function(module, exports, __webpack_require__) { -var _checkboxType2 = _interopRequireDefault(_checkboxType); +"use strict"; -var _dateType = __webpack_require__(192); +var $defineProperty = __webpack_require__(18); +var createDesc = __webpack_require__(43); -var _dateType2 = _interopRequireDefault(_dateType); +module.exports = function (object, index, value) { + if (index in object) $defineProperty.f(object, index, createDesc(0, value)); + else object[index] = value; +}; -var _dropdownType = __webpack_require__(193); -var _dropdownType2 = _interopRequireDefault(_dropdownType); +/***/ }), +/* 78 */ +/***/ (function(module, exports, __webpack_require__) { -var _handsontableType = __webpack_require__(194); +"use strict"; -var _handsontableType2 = _interopRequireDefault(_handsontableType); +var addToUnscopables = __webpack_require__(40); +var step = __webpack_require__(100); +var Iterators = __webpack_require__(45); +var toIObject = __webpack_require__(25); -var _numericType = __webpack_require__(195); +// 22.1.3.4 Array.prototype.entries() +// 22.1.3.13 Array.prototype.keys() +// 22.1.3.29 Array.prototype.values() +// 22.1.3.30 Array.prototype[@@iterator]() +module.exports = __webpack_require__(99)(Array, 'Array', function (iterated, kind) { + this._t = toIObject(iterated); // target + this._i = 0; // next index + this._k = kind; // kind +// 22.1.5.2.1 %ArrayIteratorPrototype%.next() +}, function () { + var O = this._t; + var kind = this._k; + var index = this._i++; + if (!O || index >= O.length) { + this._t = undefined; + return step(1); + } + if (kind == 'keys') return step(0, index); + if (kind == 'values') return step(0, O[index]); + return step(0, [index, O[index]]); +}, 'values'); -var _numericType2 = _interopRequireDefault(_numericType); +// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) +Iterators.Arguments = Iterators.Array; -var _passwordType = __webpack_require__(196); +addToUnscopables('keys'); +addToUnscopables('values'); +addToUnscopables('entries'); -var _passwordType2 = _interopRequireDefault(_passwordType); -var _textType = __webpack_require__(197); +/***/ }), +/* 79 */ +/***/ (function(module, exports, __webpack_require__) { -var _textType2 = _interopRequireDefault(_textType); +"use strict"; -var _timeType = __webpack_require__(198); -var _timeType2 = _interopRequireDefault(_timeType); +exports.__esModule = true; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _staticRegister = (0, _staticRegister3.default)('cellTypes'), - register = _staticRegister.register, - getItem = _staticRegister.getItem, - hasItem = _staticRegister.hasItem, - getNames = _staticRegister.getNames, - getValues = _staticRegister.getValues; +var _coords = __webpack_require__(49); -_register('autocomplete', _autocompleteType2.default); -_register('checkbox', _checkboxType2.default); -_register('date', _dateType2.default); -_register('dropdown', _dropdownType2.default); -_register('handsontable', _handsontableType2.default); -_register('numeric', _numericType2.default); -_register('password', _passwordType2.default); -_register('text', _textType2.default); -_register('time', _timeType2.default); +var _coords2 = _interopRequireDefault(_coords); -/** - * Retrieve cell type object. - * - * @param {String} name Cell type identification. - * @returns {Object} Returns cell type object. - */ -function _getItem(name) { - if (!hasItem(name)) { - throw Error('You declared cell type "' + name + '" as a string that is not mapped to a known object.\n Cell type must be an object or a string mapped to an object registered by "Handsontable.cellTypes.registerCellType" method'); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return getItem(name); -} +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * Register cell type under specified name. + * A cell range is a set of exactly two CellCoords (that can be the same or different) * - * @param {String} name Cell type identification. - * @param {Object} type An object with contains keys (eq: `editor`, `renderer`, `validator`) which describes specified behaviour of the cell. + * @class CellRange */ -function _register(name, type) { - var editor = type.editor, - renderer = type.renderer, - validator = type.validator; - +var CellRange = function () { + /** + * @param {CellCoords} highlight Used to draw bold border around a cell where selection was + * started and to edit the cell when you press Enter + * @param {CellCoords} from Usually the same as highlight, but in Excel there is distinction - one can change + * highlight within a selection + * @param {CellCoords} to End selection + */ + function CellRange(highlight, from, to) { + _classCallCheck(this, CellRange); - if (editor) { - (0, _editors.registerEditor)(name, editor); - } - if (renderer) { - (0, _renderers.registerRenderer)(name, renderer); - } - if (validator) { - (0, _validators.registerValidator)(name, validator); + this.highlight = highlight; + this.from = from; + this.to = to; } - register(name, type); -} - -exports.registerCellType = _register; -exports.getCellType = _getItem; -exports.hasCellType = hasItem; -exports.getRegisteredCellTypeNames = getNames; -exports.getRegisteredCellTypes = getValues; - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + /** + * Checks if given coords are valid in context of a given Walkontable instance + * + * @param {Walkontable} wotInstance + * @returns {Boolean} + */ -exports.__esModule = true; + _createClass(CellRange, [{ + key: 'isValid', + value: function isValid(wotInstance) { + return this.from.isValid(wotInstance) && this.to.isValid(wotInstance); + } -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + /** + * Checks if this cell range is restricted to one cell + * + * @returns {Boolean} + */ -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + }, { + key: 'isSingle', + value: function isSingle() { + return this.from.row === this.to.row && this.from.col === this.to.col; + } -exports.default = Core; + /** + * Returns selected range height (in number of rows) + * + * @returns {Number} + */ -var _numbro = __webpack_require__(87); + }, { + key: 'getHeight', + value: function getHeight() { + return Math.max(this.from.row, this.to.row) - Math.min(this.from.row, this.to.row) + 1; + } -var _numbro2 = _interopRequireDefault(_numbro); + /** + * Returns selected range width (in number of columns) + * + * @returns {Number} + */ -var _element = __webpack_require__(0); + }, { + key: 'getWidth', + value: function getWidth() { + return Math.max(this.from.col, this.to.col) - Math.min(this.from.col, this.to.col) + 1; + } -var _setting = __webpack_require__(65); + /** + * Checks if given cell coords is within `from` and `to` cell coords of this range + * + * @param {CellCoords} cellCoords + * @returns {Boolean} + */ -var _function = __webpack_require__(35); + }, { + key: 'includes', + value: function includes(cellCoords) { + var row = cellCoords.row, + col = cellCoords.col; -var _mixed = __webpack_require__(20); + var topLeft = this.getTopLeftCorner(); + var bottomRight = this.getBottomRightCorner(); -var _browser = __webpack_require__(25); + return topLeft.row <= row && bottomRight.row >= row && topLeft.col <= col && bottomRight.col >= col; + } -var _dataMap = __webpack_require__(199); + /** + * Checks if given range is within of this range + * + * @param {CellRange} testedRange + * @returns {Boolean} + */ -var _dataMap2 = _interopRequireDefault(_dataMap); + }, { + key: 'includesRange', + value: function includesRange(testedRange) { + return this.includes(testedRange.getTopLeftCorner()) && this.includes(testedRange.getBottomRightCorner()); + } -var _editorManager = __webpack_require__(201); + /** + * Checks if given range is equal to this range + * + * @param {CellRange} testedRange + * @returns {Boolean} + */ -var _editorManager2 = _interopRequireDefault(_editorManager); + }, { + key: 'isEqual', + value: function isEqual(testedRange) { + return Math.min(this.from.row, this.to.row) == Math.min(testedRange.from.row, testedRange.to.row) && Math.max(this.from.row, this.to.row) == Math.max(testedRange.from.row, testedRange.to.row) && Math.min(this.from.col, this.to.col) == Math.min(testedRange.from.col, testedRange.to.col) && Math.max(this.from.col, this.to.col) == Math.max(testedRange.from.col, testedRange.to.col); + } -var _eventManager = __webpack_require__(4); + /** + * Checks if tested range overlaps with the range. + * Range A is considered to to be overlapping with range B if intersection of A and B or B and A is not empty. + * + * @param {CellRange} testedRange + * @returns {Boolean} + */ -var _eventManager2 = _interopRequireDefault(_eventManager); + }, { + key: 'overlaps', + value: function overlaps(testedRange) { + return testedRange.isSouthEastOf(this.getTopLeftCorner()) && testedRange.isNorthWestOf(this.getBottomRightCorner()); + } -var _object = __webpack_require__(1); + /** + * @param {CellRange} testedCoords + * @returns {Boolean} + */ -var _array = __webpack_require__(2); + }, { + key: 'isSouthEastOf', + value: function isSouthEastOf(testedCoords) { + return this.getTopLeftCorner().isSouthEastOf(testedCoords) || this.getBottomRightCorner().isSouthEastOf(testedCoords); + } -var _plugins = __webpack_require__(5); + /** + * @param {CellRange} testedCoords + * @returns {Boolean} + */ -var _renderers = __webpack_require__(9); + }, { + key: 'isNorthWestOf', + value: function isNorthWestOf(testedCoords) { + return this.getTopLeftCorner().isNorthWestOf(testedCoords) || this.getBottomRightCorner().isNorthWestOf(testedCoords); + } -var _validators = __webpack_require__(26); + /** + * Adds a cell to a range (only if exceeds corners of the range). Returns information if range was expanded + * + * @param {CellCoords} cellCoords + * @returns {Boolean} + */ -var _string = __webpack_require__(27); + }, { + key: 'expand', + value: function expand(cellCoords) { + var topLeft = this.getTopLeftCorner(); + var bottomRight = this.getBottomRightCorner(); -var _number = __webpack_require__(6); + if (cellCoords.row < topLeft.row || cellCoords.col < topLeft.col || cellCoords.row > bottomRight.row || cellCoords.col > bottomRight.col) { + this.from = new _coords2.default(Math.min(topLeft.row, cellCoords.row), Math.min(topLeft.col, cellCoords.col)); + this.to = new _coords2.default(Math.max(bottomRight.row, cellCoords.row), Math.max(bottomRight.col, cellCoords.col)); -var _tableView = __webpack_require__(271); + return true; + } -var _tableView2 = _interopRequireDefault(_tableView); + return false; + } -var _dataSource = __webpack_require__(200); + /** + * @param {CellRange} expandingRange + * @returns {Boolean} + */ -var _dataSource2 = _interopRequireDefault(_dataSource); + }, { + key: 'expandByRange', + value: function expandByRange(expandingRange) { + if (this.includesRange(expandingRange) || !this.overlaps(expandingRange)) { + return false; + } -var _data = __webpack_require__(64); + var topLeft = this.getTopLeftCorner(); + var bottomRight = this.getBottomRightCorner(); + var topRight = this.getTopRightCorner(); + var bottomLeft = this.getBottomLeftCorner(); -var _recordTranslator = __webpack_require__(154); + var expandingTopLeft = expandingRange.getTopLeftCorner(); + var expandingBottomRight = expandingRange.getBottomRightCorner(); -var _rootInstance = __webpack_require__(90); + var resultTopRow = Math.min(topLeft.row, expandingTopLeft.row); + var resultTopCol = Math.min(topLeft.col, expandingTopLeft.col); + var resultBottomRow = Math.max(bottomRight.row, expandingBottomRight.row); + var resultBottomCol = Math.max(bottomRight.col, expandingBottomRight.col); -var _src = __webpack_require__(11); + var finalFrom = new _coords2.default(resultTopRow, resultTopCol), + finalTo = new _coords2.default(resultBottomRow, resultBottomCol); + var isCorner = new CellRange(finalFrom, finalFrom, finalTo).isCorner(this.from, expandingRange), + onlyMerge = expandingRange.isEqual(new CellRange(finalFrom, finalFrom, finalTo)); + + if (isCorner && !onlyMerge) { + if (this.from.col > finalFrom.col) { + finalFrom.col = resultBottomCol; + finalTo.col = resultTopCol; + } + if (this.from.row > finalFrom.row) { + finalFrom.row = resultBottomRow; + finalTo.row = resultTopRow; + } + } + this.from = finalFrom; + this.to = finalTo; + + return true; + } + + /** + * @returns {String} + */ + + }, { + key: 'getDirection', + value: function getDirection() { + if (this.from.isNorthWestOf(this.to)) { + // NorthWest - SouthEast + return 'NW-SE'; + } else if (this.from.isNorthEastOf(this.to)) { + // NorthEast - SouthWest + return 'NE-SW'; + } else if (this.from.isSouthEastOf(this.to)) { + // SouthEast - NorthWest + return 'SE-NW'; + } else if (this.from.isSouthWestOf(this.to)) { + // SouthWest - NorthEast + return 'SW-NE'; + } + } + + /** + * @param {String} direction + */ + + }, { + key: 'setDirection', + value: function setDirection(direction) { + switch (direction) { + case 'NW-SE': + var _ref = [this.getTopLeftCorner(), this.getBottomRightCorner()]; + this.from = _ref[0]; + this.to = _ref[1]; + + break; + case 'NE-SW': + var _ref2 = [this.getTopRightCorner(), this.getBottomLeftCorner()]; + this.from = _ref2[0]; + this.to = _ref2[1]; + + break; + case 'SE-NW': + var _ref3 = [this.getBottomRightCorner(), this.getTopLeftCorner()]; + this.from = _ref3[0]; + this.to = _ref3[1]; + + break; + case 'SW-NE': + var _ref4 = [this.getBottomLeftCorner(), this.getTopRightCorner()]; + this.from = _ref4[0]; + this.to = _ref4[1]; + + break; + default: + break; + } + } + + /** + * Get top left corner of this range + * + * @returns {CellCoords} + */ + + }, { + key: 'getTopLeftCorner', + value: function getTopLeftCorner() { + return new _coords2.default(Math.min(this.from.row, this.to.row), Math.min(this.from.col, this.to.col)); + } + + /** + * Get bottom right corner of this range + * + * @returns {CellCoords} + */ + + }, { + key: 'getBottomRightCorner', + value: function getBottomRightCorner() { + return new _coords2.default(Math.max(this.from.row, this.to.row), Math.max(this.from.col, this.to.col)); + } + + /** + * Get top right corner of this range + * + * @returns {CellCoords} + */ + + }, { + key: 'getTopRightCorner', + value: function getTopRightCorner() { + return new _coords2.default(Math.min(this.from.row, this.to.row), Math.max(this.from.col, this.to.col)); + } + + /** + * Get bottom left corner of this range + * + * @returns {CellCoords} + */ + + }, { + key: 'getBottomLeftCorner', + value: function getBottomLeftCorner() { + return new _coords2.default(Math.max(this.from.row, this.to.row), Math.min(this.from.col, this.to.col)); + } + + /** + * @param {CellCoords} coords + * @param {CellRange} expandedRange + * @returns {*} + */ + + }, { + key: 'isCorner', + value: function isCorner(coords, expandedRange) { + if (expandedRange) { + if (expandedRange.includes(coords)) { + if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col)) || this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col)) || this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col)) || this.getBottomRightCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.to.col))) { + return true; + } + } + } + + return coords.isEqual(this.getTopLeftCorner()) || coords.isEqual(this.getTopRightCorner()) || coords.isEqual(this.getBottomLeftCorner()) || coords.isEqual(this.getBottomRightCorner()); + } + + /** + * @param {CellCoords} coords + * @param {CellRange} expandedRange + * @returns {CellCoords} + */ + + }, { + key: 'getOppositeCorner', + value: function getOppositeCorner(coords, expandedRange) { + if (!(coords instanceof _coords2.default)) { + return false; + } + + if (expandedRange) { + if (expandedRange.includes(coords)) { + if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col))) { + return this.getBottomRightCorner(); + } + if (this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col))) { + return this.getBottomLeftCorner(); + } + if (this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col))) { + return this.getTopRightCorner(); + } + if (this.getBottomRightCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.to.col))) { + return this.getTopLeftCorner(); + } + } + } + + if (coords.isEqual(this.getBottomRightCorner())) { + return this.getTopLeftCorner(); + } else if (coords.isEqual(this.getTopLeftCorner())) { + return this.getBottomRightCorner(); + } else if (coords.isEqual(this.getTopRightCorner())) { + return this.getBottomLeftCorner(); + } else if (coords.isEqual(this.getBottomLeftCorner())) { + return this.getTopRightCorner(); + } + } + + /** + * @param {CellRange} range + * @returns {Array} + */ + + }, { + key: 'getBordersSharedWith', + value: function getBordersSharedWith(range) { + if (!this.includesRange(range)) { + return []; + } + + var thisBorders = { + top: Math.min(this.from.row, this.to.row), + bottom: Math.max(this.from.row, this.to.row), + left: Math.min(this.from.col, this.to.col), + right: Math.max(this.from.col, this.to.col) + }; + var rangeBorders = { + top: Math.min(range.from.row, range.to.row), + bottom: Math.max(range.from.row, range.to.row), + left: Math.min(range.from.col, range.to.col), + right: Math.max(range.from.col, range.to.col) + }; + var result = []; + + if (thisBorders.top == rangeBorders.top) { + result.push('top'); + } + if (thisBorders.right == rangeBorders.right) { + result.push('right'); + } + if (thisBorders.bottom == rangeBorders.bottom) { + result.push('bottom'); + } + if (thisBorders.left == rangeBorders.left) { + result.push('left'); + } + + return result; + } + + /** + * Get inner selected cell coords defined by this range + * + * @returns {Array} + */ + + }, { + key: 'getInner', + value: function getInner() { + var topLeft = this.getTopLeftCorner(); + var bottomRight = this.getBottomRightCorner(); + var out = []; + + for (var r = topLeft.row; r <= bottomRight.row; r++) { + for (var c = topLeft.col; c <= bottomRight.col; c++) { + if (!(this.from.row === r && this.from.col === c) && !(this.to.row === r && this.to.col === c)) { + out.push(new _coords2.default(r, c)); + } + } + } + return out; + } + + /** + * Get all selected cell coords defined by this range + * + * @returns {Array} + */ + + }, { + key: 'getAll', + value: function getAll() { + var topLeft = this.getTopLeftCorner(); + var bottomRight = this.getBottomRightCorner(); + var out = []; + + for (var r = topLeft.row; r <= bottomRight.row; r++) { + for (var c = topLeft.col; c <= bottomRight.col; c++) { + if (topLeft.row === r && topLeft.col === c) { + out.push(topLeft); + } else if (bottomRight.row === r && bottomRight.col === c) { + out.push(bottomRight); + } else { + out.push(new _coords2.default(r, c)); + } + } + } + + return out; + } + + /** + * Runs a callback function against all cells in the range. You can break the iteration by returning + * `false` in the callback function + * + * @param callback {Function} + */ + + }, { + key: 'forAll', + value: function forAll(callback) { + var topLeft = this.getTopLeftCorner(); + var bottomRight = this.getBottomRightCorner(); + + for (var r = topLeft.row; r <= bottomRight.row; r++) { + for (var c = topLeft.col; c <= bottomRight.col; c++) { + var breakIteration = callback(r, c); + + if (breakIteration === false) { + return; + } + } + } + } + }]); + + return CellRange; +}(); + +exports.default = CellRange; + +/***/ }), +/* 80 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_80__; + +/***/ }), +/* 81 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; +exports.getRegisteredCellTypes = exports.getRegisteredCellTypeNames = exports.hasCellType = exports.getCellType = exports.registerCellType = undefined; + +var _staticRegister2 = __webpack_require__(62); + +var _staticRegister3 = _interopRequireDefault(_staticRegister2); + +var _editors = __webpack_require__(15); + +var _renderers = __webpack_require__(9); + +var _validators = __webpack_require__(27); + +var _autocompleteType = __webpack_require__(231); + +var _autocompleteType2 = _interopRequireDefault(_autocompleteType); + +var _checkboxType = __webpack_require__(232); + +var _checkboxType2 = _interopRequireDefault(_checkboxType); + +var _dateType = __webpack_require__(233); + +var _dateType2 = _interopRequireDefault(_dateType); + +var _dropdownType = __webpack_require__(234); + +var _dropdownType2 = _interopRequireDefault(_dropdownType); + +var _handsontableType = __webpack_require__(235); + +var _handsontableType2 = _interopRequireDefault(_handsontableType); + +var _numericType = __webpack_require__(236); + +var _numericType2 = _interopRequireDefault(_numericType); + +var _passwordType = __webpack_require__(237); + +var _passwordType2 = _interopRequireDefault(_passwordType); + +var _textType = __webpack_require__(238); + +var _textType2 = _interopRequireDefault(_textType); + +var _timeType = __webpack_require__(239); + +var _timeType2 = _interopRequireDefault(_timeType); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _staticRegister = (0, _staticRegister3.default)('cellTypes'), + register = _staticRegister.register, + getItem = _staticRegister.getItem, + hasItem = _staticRegister.hasItem, + getNames = _staticRegister.getNames, + getValues = _staticRegister.getValues; + +_register('autocomplete', _autocompleteType2.default); +_register('checkbox', _checkboxType2.default); +_register('date', _dateType2.default); +_register('dropdown', _dropdownType2.default); +_register('handsontable', _handsontableType2.default); +_register('numeric', _numericType2.default); +_register('password', _passwordType2.default); +_register('text', _textType2.default); +_register('time', _timeType2.default); + +/** + * Retrieve cell type object. + * + * @param {String} name Cell type identification. + * @returns {Object} Returns cell type object. + */ +function _getItem(name) { + if (!hasItem(name)) { + throw Error('You declared cell type "' + name + '" as a string that is not mapped to a known object.\n Cell type must be an object or a string mapped to an object registered by "Handsontable.cellTypes.registerCellType" method'); + } + + return getItem(name); +} + +/** + * Register cell type under specified name. + * + * @param {String} name Cell type identification. + * @param {Object} type An object with contains keys (eq: `editor`, `renderer`, `validator`) which describes specified behaviour of the cell. + */ +function _register(name, type) { + var editor = type.editor, + renderer = type.renderer, + validator = type.validator; + + + if (editor) { + (0, _editors.registerEditor)(name, editor); + } + if (renderer) { + (0, _renderers.registerRenderer)(name, renderer); + } + if (validator) { + (0, _validators.registerValidator)(name, validator); + } + + register(name, type); +} + +exports.registerCellType = _register; +exports.getCellType = _getItem; +exports.hasCellType = hasItem; +exports.getRegisteredCellTypeNames = getNames; +exports.getRegisteredCellTypes = getValues; + +/***/ }), +/* 82 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.default = Core; + +var _numbro = __webpack_require__(80); + +var _numbro2 = _interopRequireDefault(_numbro); + +var _element = __webpack_require__(0); + +var _setting = __webpack_require__(83); + +var _function = __webpack_require__(35); + +var _mixed = __webpack_require__(22); + +var _browser = __webpack_require__(26); + +var _dataMap = __webpack_require__(240); + +var _dataMap2 = _interopRequireDefault(_dataMap); + +var _editorManager = __webpack_require__(243); + +var _editorManager2 = _interopRequireDefault(_editorManager); + +var _eventManager = __webpack_require__(4); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +var _object = __webpack_require__(1); + +var _array = __webpack_require__(2); + +var _plugins = __webpack_require__(5); + +var _renderers = __webpack_require__(9); + +var _validators = __webpack_require__(27); + +var _string = __webpack_require__(32); + +var _number = __webpack_require__(6); + +var _tableView = __webpack_require__(244); + +var _tableView2 = _interopRequireDefault(_tableView); + +var _dataSource = __webpack_require__(245); + +var _dataSource2 = _interopRequireDefault(_dataSource); + +var _data = __webpack_require__(84); + +var _recordTranslator = __webpack_require__(172); + +var _rootInstance = __webpack_require__(173); + +var _src = __webpack_require__(12); -var _pluginHooks = __webpack_require__(8); +var _pluginHooks = __webpack_require__(7); var _pluginHooks2 = _interopRequireDefault(_pluginHooks); -var _defaultSettings = __webpack_require__(88); +var _defaultSettings = __webpack_require__(174); var _defaultSettings2 = _interopRequireDefault(_defaultSettings); -var _cellTypes = __webpack_require__(62); +var _cellTypes = __webpack_require__(81); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -26955,7 +27912,7 @@ function Core(rootElement, userSettings) { if (result === false && cellProperties.allowInvalid === false) { changes.splice(i, 1); // cancel the change cellProperties.valid = true; // we cancelled the change, so cell value is still valid - var cell = instance.getCell(cellProperties.row, cellProperties.col); + var cell = instance.getCell(cellProperties.visualRow, cellProperties.visualCol); (0, _element.removeClass)(cell, instance.getSettings().invalidCellClassName); --i; } @@ -29060,10 +30017,12 @@ function Core(rootElement, userSettings) { } dataSource = null; - var nextSibling = instance.rootElement.nextSibling; + if (false) { + var licenseInfo = document.querySelector('#hot-display-license-info'); - if ((0, _rootInstance.isRootInstance)(instance) && nextSibling) { - instance.rootElement.parentNode.removeChild(nextSibling); + if (licenseInfo) { + licenseInfo.parentNode.removeChild(licenseInfo); + } } (0, _element.empty)(instance.rootElement); eventManager.destroy(); @@ -29273,7 +30232,40 @@ function Core(rootElement, userSettings) { }; /***/ }), -/* 64 */ +/* 83 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; +exports.columnFactory = columnFactory; + +var _object = __webpack_require__(1); + +/* eslint-disable import/prefer-default-export */ +/** + * Factory for columns constructors. + * + * @param {Object} GridSettings + * @param {Array} conflictList + * @return {Object} ColumnSettings + */ +function columnFactory(GridSettings, conflictList) { + function ColumnSettings() {}; + + (0, _object.inherit)(ColumnSettings, GridSettings); + + // Clear conflict settings + for (var i = 0, len = conflictList.length; i < len; i++) { + ColumnSettings.prototype[conflictList[i]] = void 0; + } + + return ColumnSettings; +} + +/***/ }), +/* 84 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29288,7 +30280,7 @@ exports.createEmptySpreadsheetData = createEmptySpreadsheetData; exports.translateRowsToColumns = translateRowsToColumns; exports.cellMethodLookupFactory = cellMethodLookupFactory; -var _cellTypes = __webpack_require__(62); +var _cellTypes = __webpack_require__(81); var _object = __webpack_require__(1); @@ -29482,40 +30474,7 @@ function cellMethodLookupFactory(methodName, allowUndefined) { } /***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.columnFactory = columnFactory; - -var _object = __webpack_require__(1); - -/* eslint-disable import/prefer-default-export */ -/** - * Factory for columns constructors. - * - * @param {Object} GridSettings - * @param {Array} conflictList - * @return {Object} ColumnSettings - */ -function columnFactory(GridSettings, conflictList) { - function ColumnSettings() {}; - - (0, _object.inherit)(ColumnSettings, GridSettings); - - // Clear conflict settings - for (var i = 0, len = conflictList.length; i < len; i++) { - ColumnSettings.prototype[conflictList[i]] = void 0; - } - - return ColumnSettings; -} - -/***/ }), -/* 66 */ +/* 85 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30056,47 +31015,24 @@ var GhostTable = function () { exports.default = GhostTable; /***/ }), -/* 67 */ +/* 86 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var addToUnscopables = __webpack_require__(37) - , step = __webpack_require__(168) - , Iterators = __webpack_require__(45) - , toIObject = __webpack_require__(23); - -// 22.1.3.4 Array.prototype.entries() -// 22.1.3.13 Array.prototype.keys() -// 22.1.3.29 Array.prototype.values() -// 22.1.3.30 Array.prototype[@@iterator]() -module.exports = __webpack_require__(167)(Array, 'Array', function(iterated, kind){ - this._t = toIObject(iterated); // target - this._i = 0; // next index - this._k = kind; // kind -// 22.1.5.2.1 %ArrayIteratorPrototype%.next() -}, function(){ - var O = this._t - , kind = this._k - , index = this._i++; - if(!O || index >= O.length){ - this._t = undefined; - return step(1); - } - if(kind == 'keys' )return step(0, index); - if(kind == 'values')return step(0, O[index]); - return step(0, [index, O[index]]); -}, 'values'); -// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) -Iterators.Arguments = Iterators.Array; +exports.__esModule = true; +exports.default = separatorItem; +var KEY = exports.KEY = '---------'; -addToUnscopables('keys'); -addToUnscopables('values'); -addToUnscopables('entries'); +function separatorItem() { + return { + name: KEY + }; +} /***/ }), -/* 68 */ +/* 87 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30104,5371 +31040,3696 @@ addToUnscopables('entries'); exports.__esModule = true; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _coords = __webpack_require__(42); - -var _coords2 = _interopRequireDefault(_coords); +var _array = __webpack_require__(2); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _object = __webpack_require__(1); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var MIXIN_NAME = 'localHooks'; /** - * A cell range is a set of exactly two CellCoords (that can be the same or different) + * Mixin object to extend objects functionality for local hooks. * - * @class CellRange + * @type {Object} */ -var CellRange = function () { +var localHooks = { /** - * @param {CellCoords} highlight Used to draw bold border around a cell where selection was - * started and to edit the cell when you press Enter - * @param {CellCoords} from Usually the same as highlight, but in Excel there is distinction - one can change - * highlight within a selection - * @param {CellCoords} to End selection + * Internal hooks storage. */ - function CellRange(highlight, from, to) { - _classCallCheck(this, CellRange); + _localHooks: Object.create(null), + + /** + * Add hook to the collection. + * + * @param {String} key Hook name. + * @param {Function} callback Hook callback + */ + addLocalHook: function addLocalHook(key, callback) { + if (!this._localHooks[key]) { + this._localHooks[key] = []; + } + this._localHooks[key].push(callback); + }, - this.highlight = highlight; - this.from = from; - this.to = to; - } /** - * Checks if given coords are valid in context of a given Walkontable instance + * Run hooks. * - * @param {Walkontable} wotInstance - * @returns {Boolean} + * @param {String} key Hook name. + * @param {*} params */ + runLocalHooks: function runLocalHooks(key) { + var _this = this; + for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + params[_key - 1] = arguments[_key]; + } - _createClass(CellRange, [{ - key: 'isValid', - value: function isValid(wotInstance) { - return this.from.isValid(wotInstance) && this.to.isValid(wotInstance); + if (this._localHooks[key]) { + (0, _array.arrayEach)(this._localHooks[key], function (callback) { + return callback.apply(_this, params); + }); } + }, - /** - * Checks if this cell range is restricted to one cell - * - * @returns {Boolean} - */ - }, { - key: 'isSingle', - value: function isSingle() { - return this.from.row === this.to.row && this.from.col === this.to.col; - } + /** + * Clear all added hooks. + */ + clearLocalHooks: function clearLocalHooks() { + this._localHooks = {}; + } +}; - /** - * Returns selected range height (in number of rows) - * - * @returns {Number} - */ +(0, _object.defineGetter)(localHooks, 'MIXIN_NAME', MIXIN_NAME, { + writable: false, + enumerable: false +}); - }, { - key: 'getHeight', - value: function getHeight() { - return Math.max(this.from.row, this.to.row) - Math.min(this.from.row, this.to.row) + 1; - } +exports.default = localHooks; - /** - * Returns selected range width (in number of columns) - * - * @returns {Number} - */ +/***/ }), +/* 88 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'getWidth', - value: function getWidth() { - return Math.max(this.from.col, this.to.col) - Math.min(this.from.col, this.to.col) + 1; - } +"use strict"; - /** - * Checks if given cell coords is within `from` and `to` cell coords of this range - * - * @param {CellCoords} cellCoords - * @returns {Boolean} - */ - }, { - key: 'includes', - value: function includes(cellCoords) { - var row = cellCoords.row, - col = cellCoords.col; +exports.__esModule = true; +exports.ITEMS = exports.UNDO = exports.SEPARATOR = exports.ROW_BELOW = exports.ROW_ABOVE = exports.REMOVE_ROW = exports.REMOVE_COLUMN = exports.REDO = exports.READ_ONLY = exports.COLUMN_RIGHT = exports.COLUMN_LEFT = exports.CLEAR_COLUMN = exports.ALIGNMENT = undefined; - var topLeft = this.getTopLeftCorner(); - var bottomRight = this.getBottomRightCorner(); +var _predefinedItems2; - return topLeft.row <= row && bottomRight.row >= row && topLeft.col <= col && bottomRight.col >= col; - } +var _alignment = __webpack_require__(262); - /** - * Checks if given range is within of this range - * - * @param {CellRange} testedRange - * @returns {Boolean} - */ +Object.defineProperty(exports, 'ALIGNMENT', { + enumerable: true, + get: function get() { + return _alignment.KEY; + } +}); - }, { - key: 'includesRange', - value: function includesRange(testedRange) { - return this.includes(testedRange.getTopLeftCorner()) && this.includes(testedRange.getBottomRightCorner()); - } +var _clearColumn = __webpack_require__(263); - /** - * Checks if given range is equal to this range - * - * @param {CellRange} testedRange - * @returns {Boolean} - */ +Object.defineProperty(exports, 'CLEAR_COLUMN', { + enumerable: true, + get: function get() { + return _clearColumn.KEY; + } +}); - }, { - key: 'isEqual', - value: function isEqual(testedRange) { - return Math.min(this.from.row, this.to.row) == Math.min(testedRange.from.row, testedRange.to.row) && Math.max(this.from.row, this.to.row) == Math.max(testedRange.from.row, testedRange.to.row) && Math.min(this.from.col, this.to.col) == Math.min(testedRange.from.col, testedRange.to.col) && Math.max(this.from.col, this.to.col) == Math.max(testedRange.from.col, testedRange.to.col); - } +var _columnLeft = __webpack_require__(264); - /** - * Checks if tested range overlaps with the range. - * Range A is considered to to be overlapping with range B if intersection of A and B or B and A is not empty. - * - * @param {CellRange} testedRange - * @returns {Boolean} - */ +Object.defineProperty(exports, 'COLUMN_LEFT', { + enumerable: true, + get: function get() { + return _columnLeft.KEY; + } +}); - }, { - key: 'overlaps', - value: function overlaps(testedRange) { - return testedRange.isSouthEastOf(this.getTopLeftCorner()) && testedRange.isNorthWestOf(this.getBottomRightCorner()); - } +var _columnRight = __webpack_require__(265); - /** - * @param {CellRange} testedCoords - * @returns {Boolean} - */ +Object.defineProperty(exports, 'COLUMN_RIGHT', { + enumerable: true, + get: function get() { + return _columnRight.KEY; + } +}); - }, { - key: 'isSouthEastOf', - value: function isSouthEastOf(testedCoords) { - return this.getTopLeftCorner().isSouthEastOf(testedCoords) || this.getBottomRightCorner().isSouthEastOf(testedCoords); - } +var _readOnly = __webpack_require__(266); - /** - * @param {CellRange} testedCoords - * @returns {Boolean} - */ +Object.defineProperty(exports, 'READ_ONLY', { + enumerable: true, + get: function get() { + return _readOnly.KEY; + } +}); - }, { - key: 'isNorthWestOf', - value: function isNorthWestOf(testedCoords) { - return this.getTopLeftCorner().isNorthWestOf(testedCoords) || this.getBottomRightCorner().isNorthWestOf(testedCoords); - } +var _redo = __webpack_require__(267); - /** - * Adds a cell to a range (only if exceeds corners of the range). Returns information if range was expanded - * - * @param {CellCoords} cellCoords - * @returns {Boolean} - */ +Object.defineProperty(exports, 'REDO', { + enumerable: true, + get: function get() { + return _redo.KEY; + } +}); - }, { - key: 'expand', - value: function expand(cellCoords) { - var topLeft = this.getTopLeftCorner(); - var bottomRight = this.getBottomRightCorner(); +var _removeColumn = __webpack_require__(268); - if (cellCoords.row < topLeft.row || cellCoords.col < topLeft.col || cellCoords.row > bottomRight.row || cellCoords.col > bottomRight.col) { - this.from = new _coords2.default(Math.min(topLeft.row, cellCoords.row), Math.min(topLeft.col, cellCoords.col)); - this.to = new _coords2.default(Math.max(bottomRight.row, cellCoords.row), Math.max(bottomRight.col, cellCoords.col)); +Object.defineProperty(exports, 'REMOVE_COLUMN', { + enumerable: true, + get: function get() { + return _removeColumn.KEY; + } +}); - return true; - } +var _removeRow = __webpack_require__(269); - return false; - } +Object.defineProperty(exports, 'REMOVE_ROW', { + enumerable: true, + get: function get() { + return _removeRow.KEY; + } +}); - /** - * @param {CellRange} expandingRange - * @returns {Boolean} - */ +var _rowAbove = __webpack_require__(270); - }, { - key: 'expandByRange', - value: function expandByRange(expandingRange) { - if (this.includesRange(expandingRange) || !this.overlaps(expandingRange)) { - return false; - } +Object.defineProperty(exports, 'ROW_ABOVE', { + enumerable: true, + get: function get() { + return _rowAbove.KEY; + } +}); - var topLeft = this.getTopLeftCorner(); - var bottomRight = this.getBottomRightCorner(); - var topRight = this.getTopRightCorner(); - var bottomLeft = this.getBottomLeftCorner(); +var _rowBelow = __webpack_require__(271); - var expandingTopLeft = expandingRange.getTopLeftCorner(); - var expandingBottomRight = expandingRange.getBottomRightCorner(); +Object.defineProperty(exports, 'ROW_BELOW', { + enumerable: true, + get: function get() { + return _rowBelow.KEY; + } +}); - var resultTopRow = Math.min(topLeft.row, expandingTopLeft.row); - var resultTopCol = Math.min(topLeft.col, expandingTopLeft.col); - var resultBottomRow = Math.max(bottomRight.row, expandingBottomRight.row); - var resultBottomCol = Math.max(bottomRight.col, expandingBottomRight.col); +var _separator = __webpack_require__(86); - var finalFrom = new _coords2.default(resultTopRow, resultTopCol), - finalTo = new _coords2.default(resultBottomRow, resultBottomCol); - var isCorner = new CellRange(finalFrom, finalFrom, finalTo).isCorner(this.from, expandingRange), - onlyMerge = expandingRange.isEqual(new CellRange(finalFrom, finalFrom, finalTo)); +Object.defineProperty(exports, 'SEPARATOR', { + enumerable: true, + get: function get() { + return _separator.KEY; + } +}); - if (isCorner && !onlyMerge) { - if (this.from.col > finalFrom.col) { - finalFrom.col = resultBottomCol; - finalTo.col = resultTopCol; - } - if (this.from.row > finalFrom.row) { - finalFrom.row = resultBottomRow; - finalTo.row = resultTopRow; - } - } - this.from = finalFrom; - this.to = finalTo; +var _undo = __webpack_require__(272); - return true; - } +Object.defineProperty(exports, 'UNDO', { + enumerable: true, + get: function get() { + return _undo.KEY; + } +}); +exports.predefinedItems = predefinedItems; +exports.addItem = addItem; - /** - * @returns {String} - */ +var _object = __webpack_require__(1); - }, { - key: 'getDirection', - value: function getDirection() { - if (this.from.isNorthWestOf(this.to)) { - // NorthWest - SouthEast - return 'NW-SE'; - } else if (this.from.isNorthEastOf(this.to)) { - // NorthEast - SouthWest - return 'NE-SW'; - } else if (this.from.isSouthEastOf(this.to)) { - // SouthEast - NorthWest - return 'SE-NW'; - } else if (this.from.isSouthWestOf(this.to)) { - // SouthWest - NorthEast - return 'SW-NE'; - } - } +var _alignment2 = _interopRequireDefault(_alignment); - /** - * @param {String} direction - */ +var _clearColumn2 = _interopRequireDefault(_clearColumn); - }, { - key: 'setDirection', - value: function setDirection(direction) { - switch (direction) { - case 'NW-SE': - var _ref = [this.getTopLeftCorner(), this.getBottomRightCorner()]; - this.from = _ref[0]; - this.to = _ref[1]; +var _columnLeft2 = _interopRequireDefault(_columnLeft); - break; - case 'NE-SW': - var _ref2 = [this.getTopRightCorner(), this.getBottomLeftCorner()]; - this.from = _ref2[0]; - this.to = _ref2[1]; +var _columnRight2 = _interopRequireDefault(_columnRight); - break; - case 'SE-NW': - var _ref3 = [this.getBottomRightCorner(), this.getTopLeftCorner()]; - this.from = _ref3[0]; - this.to = _ref3[1]; +var _readOnly2 = _interopRequireDefault(_readOnly); - break; - case 'SW-NE': - var _ref4 = [this.getBottomLeftCorner(), this.getTopRightCorner()]; - this.from = _ref4[0]; - this.to = _ref4[1]; +var _redo2 = _interopRequireDefault(_redo); - break; - default: - break; - } - } +var _removeColumn2 = _interopRequireDefault(_removeColumn); - /** - * Get top left corner of this range - * - * @returns {CellCoords} - */ +var _removeRow2 = _interopRequireDefault(_removeRow); - }, { - key: 'getTopLeftCorner', - value: function getTopLeftCorner() { - return new _coords2.default(Math.min(this.from.row, this.to.row), Math.min(this.from.col, this.to.col)); - } +var _rowAbove2 = _interopRequireDefault(_rowAbove); - /** - * Get bottom right corner of this range - * - * @returns {CellCoords} - */ +var _rowBelow2 = _interopRequireDefault(_rowBelow); - }, { - key: 'getBottomRightCorner', - value: function getBottomRightCorner() { - return new _coords2.default(Math.max(this.from.row, this.to.row), Math.max(this.from.col, this.to.col)); - } +var _separator2 = _interopRequireDefault(_separator); - /** - * Get top right corner of this range - * - * @returns {CellCoords} - */ +var _undo2 = _interopRequireDefault(_undo); - }, { - key: 'getTopRightCorner', - value: function getTopRightCorner() { - return new _coords2.default(Math.min(this.from.row, this.to.row), Math.max(this.from.col, this.to.col)); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - /** - * Get bottom left corner of this range - * - * @returns {CellCoords} - */ +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - }, { - key: 'getBottomLeftCorner', - value: function getBottomLeftCorner() { - return new _coords2.default(Math.max(this.from.row, this.to.row), Math.min(this.from.col, this.to.col)); - } - - /** - * @param {CellCoords} coords - * @param {CellRange} expandedRange - * @returns {*} - */ +var ITEMS = exports.ITEMS = [_rowAbove.KEY, _rowBelow.KEY, _columnLeft.KEY, _columnRight.KEY, _clearColumn.KEY, _removeRow.KEY, _removeColumn.KEY, _undo.KEY, _redo.KEY, _readOnly.KEY, _alignment.KEY, _separator.KEY]; - }, { - key: 'isCorner', - value: function isCorner(coords, expandedRange) { - if (expandedRange) { - if (expandedRange.includes(coords)) { - if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col)) || this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col)) || this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col)) || this.getBottomRightCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.to.col))) { - return true; - } - } - } +var _predefinedItems = (_predefinedItems2 = {}, _defineProperty(_predefinedItems2, _separator.KEY, _separator2.default), _defineProperty(_predefinedItems2, _rowAbove.KEY, _rowAbove2.default), _defineProperty(_predefinedItems2, _rowBelow.KEY, _rowBelow2.default), _defineProperty(_predefinedItems2, _columnLeft.KEY, _columnLeft2.default), _defineProperty(_predefinedItems2, _columnRight.KEY, _columnRight2.default), _defineProperty(_predefinedItems2, _clearColumn.KEY, _clearColumn2.default), _defineProperty(_predefinedItems2, _removeRow.KEY, _removeRow2.default), _defineProperty(_predefinedItems2, _removeColumn.KEY, _removeColumn2.default), _defineProperty(_predefinedItems2, _undo.KEY, _undo2.default), _defineProperty(_predefinedItems2, _redo.KEY, _redo2.default), _defineProperty(_predefinedItems2, _readOnly.KEY, _readOnly2.default), _defineProperty(_predefinedItems2, _alignment.KEY, _alignment2.default), _predefinedItems2); - return coords.isEqual(this.getTopLeftCorner()) || coords.isEqual(this.getTopRightCorner()) || coords.isEqual(this.getBottomLeftCorner()) || coords.isEqual(this.getBottomRightCorner()); - } +/** + * Gets new object with all predefined menu items. + * + * @returns {Object} + */ +function predefinedItems() { + var items = {}; - /** - * @param {CellCoords} coords - * @param {CellRange} expandedRange - * @returns {CellCoords} - */ + (0, _object.objectEach)(_predefinedItems, function (itemFactory, key) { + items[key] = itemFactory(); + }); - }, { - key: 'getOppositeCorner', - value: function getOppositeCorner(coords, expandedRange) { - if (!(coords instanceof _coords2.default)) { - return false; - } + return items; +} - if (expandedRange) { - if (expandedRange.includes(coords)) { - if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col))) { - return this.getBottomRightCorner(); - } - if (this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col))) { - return this.getBottomLeftCorner(); - } - if (this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col))) { - return this.getTopRightCorner(); - } - if (this.getBottomRightCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.to.col))) { - return this.getTopLeftCorner(); - } - } - } +/** + * Add new predefined menu item to the collection. + * + * @param {String} key Menu command id. + * @param {Object} item Object command descriptor. + */ +function addItem(key, item) { + if (ITEMS.indexOf(key) === -1) { + _predefinedItems[key] = item; + } +} - if (coords.isEqual(this.getBottomRightCorner())) { - return this.getTopLeftCorner(); - } else if (coords.isEqual(this.getTopLeftCorner())) { - return this.getBottomRightCorner(); - } else if (coords.isEqual(this.getTopRightCorner())) { - return this.getBottomLeftCorner(); - } else if (coords.isEqual(this.getBottomLeftCorner())) { - return this.getTopRightCorner(); - } - } +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @param {CellRange} range - * @returns {Array} - */ +"use strict"; - }, { - key: 'getBordersSharedWith', - value: function getBordersSharedWith(range) { - if (!this.includesRange(range)) { - return []; - } +var strong = __webpack_require__(90); +var validate = __webpack_require__(39); +var MAP = 'Map'; - var thisBorders = { - top: Math.min(this.from.row, this.to.row), - bottom: Math.max(this.from.row, this.to.row), - left: Math.min(this.from.col, this.to.col), - right: Math.max(this.from.col, this.to.col) - }; - var rangeBorders = { - top: Math.min(range.from.row, range.to.row), - bottom: Math.max(range.from.row, range.to.row), - left: Math.min(range.from.col, range.to.col), - right: Math.max(range.from.col, range.to.col) - }; - var result = []; +// 23.1 Map Objects +module.exports = __webpack_require__(58)(MAP, function (get) { + return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); }; +}, { + // 23.1.3.6 Map.prototype.get(key) + get: function get(key) { + var entry = strong.getEntry(validate(this, MAP), key); + return entry && entry.v; + }, + // 23.1.3.9 Map.prototype.set(key, value) + set: function set(key, value) { + return strong.def(validate(this, MAP), key === 0 ? 0 : key, value); + } +}, strong, true); - if (thisBorders.top == rangeBorders.top) { - result.push('top'); - } - if (thisBorders.right == rangeBorders.right) { - result.push('right'); - } - if (thisBorders.bottom == rangeBorders.bottom) { - result.push('bottom'); - } - if (thisBorders.left == rangeBorders.left) { - result.push('left'); - } - return result; - } +/***/ }), +/* 90 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Get inner selected cell coords defined by this range - * - * @returns {Array} - */ +"use strict"; - }, { - key: 'getInner', - value: function getInner() { - var topLeft = this.getTopLeftCorner(); - var bottomRight = this.getBottomRightCorner(); - var out = []; +var dP = __webpack_require__(18).f; +var create = __webpack_require__(66); +var redefineAll = __webpack_require__(53); +var ctx = __webpack_require__(30); +var anInstance = __webpack_require__(55); +var forOf = __webpack_require__(56); +var $iterDefine = __webpack_require__(99); +var step = __webpack_require__(100); +var setSpecies = __webpack_require__(101); +var DESCRIPTORS = __webpack_require__(20); +var fastKey = __webpack_require__(47).fastKey; +var validate = __webpack_require__(39); +var SIZE = DESCRIPTORS ? '_s' : 'size'; + +var getEntry = function (that, key) { + // fast case + var index = fastKey(key); + var entry; + if (index !== 'F') return that._i[index]; + // frozen object case + for (entry = that._f; entry; entry = entry.n) { + if (entry.k == key) return entry; + } +}; - for (var r = topLeft.row; r <= bottomRight.row; r++) { - for (var c = topLeft.col; c <= bottomRight.col; c++) { - if (!(this.from.row === r && this.from.col === c) && !(this.to.row === r && this.to.col === c)) { - out.push(new _coords2.default(r, c)); - } +module.exports = { + getConstructor: function (wrapper, NAME, IS_MAP, ADDER) { + var C = wrapper(function (that, iterable) { + anInstance(that, C, NAME, '_i'); + that._t = NAME; // collection type + that._i = create(null); // index + that._f = undefined; // first entry + that._l = undefined; // last entry + that[SIZE] = 0; // size + if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that); + }); + redefineAll(C.prototype, { + // 23.1.3.1 Map.prototype.clear() + // 23.2.3.2 Set.prototype.clear() + clear: function clear() { + for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) { + entry.r = true; + if (entry.p) entry.p = entry.p.n = undefined; + delete data[entry.i]; } - } - return out; - } - - /** - * Get all selected cell coords defined by this range - * - * @returns {Array} - */ - - }, { - key: 'getAll', - value: function getAll() { - var topLeft = this.getTopLeftCorner(); - var bottomRight = this.getBottomRightCorner(); - var out = []; - - for (var r = topLeft.row; r <= bottomRight.row; r++) { - for (var c = topLeft.col; c <= bottomRight.col; c++) { - if (topLeft.row === r && topLeft.col === c) { - out.push(topLeft); - } else if (bottomRight.row === r && bottomRight.col === c) { - out.push(bottomRight); - } else { - out.push(new _coords2.default(r, c)); - } + that._f = that._l = undefined; + that[SIZE] = 0; + }, + // 23.1.3.3 Map.prototype.delete(key) + // 23.2.3.4 Set.prototype.delete(value) + 'delete': function (key) { + var that = validate(this, NAME); + var entry = getEntry(that, key); + if (entry) { + var next = entry.n; + var prev = entry.p; + delete that._i[entry.i]; + entry.r = true; + if (prev) prev.n = next; + if (next) next.p = prev; + if (that._f == entry) that._f = next; + if (that._l == entry) that._l = prev; + that[SIZE]--; + } return !!entry; + }, + // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined) + // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined) + forEach: function forEach(callbackfn /* , that = undefined */) { + validate(this, NAME); + var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3); + var entry; + while (entry = entry ? entry.n : this._f) { + f(entry.v, entry.k, this); + // revert to the last existing entry + while (entry && entry.r) entry = entry.p; } + }, + // 23.1.3.7 Map.prototype.has(key) + // 23.2.3.7 Set.prototype.has(value) + has: function has(key) { + return !!getEntry(validate(this, NAME), key); } - - return out; - } - - /** - * Runs a callback function against all cells in the range. You can break the iteration by returning - * `false` in the callback function - * - * @param callback {Function} - */ - - }, { - key: 'forAll', - value: function forAll(callback) { - var topLeft = this.getTopLeftCorner(); - var bottomRight = this.getBottomRightCorner(); - - for (var r = topLeft.row; r <= bottomRight.row; r++) { - for (var c = topLeft.col; c <= bottomRight.col; c++) { - var breakIteration = callback(r, c); - - if (breakIteration === false) { - return; - } - } + }); + if (DESCRIPTORS) dP(C.prototype, 'size', { + get: function () { + return validate(this, NAME)[SIZE]; } - } - }]); + }); + return C; + }, + def: function (that, key, value) { + var entry = getEntry(that, key); + var prev, index; + // change existing entry + if (entry) { + entry.v = value; + // create new entry + } else { + that._l = entry = { + i: index = fastKey(key, true), // <- index + k: key, // <- key + v: value, // <- value + p: prev = that._l, // <- previous entry + n: undefined, // <- next entry + r: false // <- removed + }; + if (!that._f) that._f = entry; + if (prev) prev.n = entry; + that[SIZE]++; + // add to index + if (index !== 'F') that._i[index] = entry; + } return that; + }, + getEntry: getEntry, + setStrong: function (C, NAME, IS_MAP) { + // add .keys, .values, .entries, [@@iterator] + // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11 + $iterDefine(C, NAME, function (iterated, kind) { + this._t = validate(iterated, NAME); // target + this._k = kind; // kind + this._l = undefined; // previous + }, function () { + var that = this; + var kind = that._k; + var entry = that._l; + // revert to the last existing entry + while (entry && entry.r) entry = entry.p; + // get next entry + if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) { + // or finish the iteration + that._t = undefined; + return step(1); + } + // return step by kind + if (kind == 'keys') return step(0, entry.k); + if (kind == 'values') return step(0, entry.v); + return step(0, [entry.k, entry.v]); + }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); - return CellRange; -}(); + // add [@@species], 23.1.2.2, 23.2.2.2 + setSpecies(NAME); + } +}; -exports.default = CellRange; /***/ }), -/* 69 */ +/* 91 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +module.exports = !__webpack_require__(20) && !__webpack_require__(23)(function () { + return Object.defineProperty(__webpack_require__(64)('div'), 'a', { get: function () { return 7; } }).a != 7; +}); -exports.__esModule = true; +/***/ }), +/* 92 */ +/***/ (function(module, exports, __webpack_require__) { -var _array = __webpack_require__(2); +var has = __webpack_require__(24); +var toIObject = __webpack_require__(25); +var arrayIndexOf = __webpack_require__(93)(false); +var IE_PROTO = __webpack_require__(68)('IE_PROTO'); -var _object = __webpack_require__(1); +module.exports = function (object, names) { + var O = toIObject(object); + var i = 0; + var result = []; + var key; + for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); + // Don't enum bug & hidden keys + while (names.length > i) if (has(O, key = names[i++])) { + ~arrayIndexOf(result, key) || result.push(key); + } + return result; +}; -var MIXIN_NAME = 'localHooks'; -/** - * Mixin object to extend objects functionality for local hooks. - * - * @type {Object} - */ -var localHooks = { - /** - * Internal hooks storage. - */ - _localHooks: Object.create(null), +/***/ }), +/* 93 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Add hook to the collection. - * - * @param {String} key Hook name. - * @param {Function} callback Hook callback - */ - addLocalHook: function addLocalHook(key, callback) { - if (!this._localHooks[key]) { - this._localHooks[key] = []; - } - this._localHooks[key].push(callback); - }, +// false -> Array#indexOf +// true -> Array#includes +var toIObject = __webpack_require__(25); +var toLength = __webpack_require__(21); +var toAbsoluteIndex = __webpack_require__(52); +module.exports = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = toIObject($this); + var length = toLength(O.length); + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare + if (IS_INCLUDES && el != el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare + if (value != value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) if (IS_INCLUDES || index in O) { + if (O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; - /** - * Run hooks. - * - * @param {String} key Hook name. - * @param {*} params - */ - runLocalHooks: function runLocalHooks(key) { - var _this = this; +/***/ }), +/* 94 */ +/***/ (function(module, exports, __webpack_require__) { - for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - params[_key - 1] = arguments[_key]; - } +var document = __webpack_require__(11).document; +module.exports = document && document.documentElement; - if (this._localHooks[key]) { - (0, _array.arrayEach)(this._localHooks[key], function (callback) { - return callback.apply(_this, params); - }); - } - }, +/***/ }), +/* 95 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Clear all added hooks. - */ - clearLocalHooks: function clearLocalHooks() { - this._localHooks = {}; +// call something on iterator step with safe closing on error +var anObject = __webpack_require__(16); +module.exports = function (iterator, fn, value, entries) { + try { + return entries ? fn(anObject(value)[0], value[1]) : fn(value); + // 7.4.6 IteratorClose(iterator, completion) + } catch (e) { + var ret = iterator['return']; + if (ret !== undefined) anObject(ret.call(iterator)); + throw e; } }; -(0, _object.defineGetter)(localHooks, 'MIXIN_NAME', MIXIN_NAME, { - writable: false, - enumerable: false -}); - -exports.default = localHooks; /***/ }), -/* 70 */ +/* 96 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// check on default Array iterator +var Iterators = __webpack_require__(45); +var ITERATOR = __webpack_require__(10)('iterator'); +var ArrayProto = Array.prototype; +module.exports = function (it) { + return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); +}; -exports.__esModule = true; -exports.ITEMS = exports.UNDO = exports.SEPARATOR = exports.ROW_BELOW = exports.ROW_ABOVE = exports.REMOVE_ROW = exports.REMOVE_COLUMN = exports.REDO = exports.READ_ONLY = exports.COLUMN_RIGHT = exports.COLUMN_LEFT = exports.CLEAR_COLUMN = exports.ALIGNMENT = undefined; -var _predefinedItems2; +/***/ }), +/* 97 */ +/***/ (function(module, exports, __webpack_require__) { -var _alignment = __webpack_require__(225); +var classof = __webpack_require__(98); +var ITERATOR = __webpack_require__(10)('iterator'); +var Iterators = __webpack_require__(45); +module.exports = __webpack_require__(44).getIteratorMethod = function (it) { + if (it != undefined) return it[ITERATOR] + || it['@@iterator'] + || Iterators[classof(it)]; +}; -Object.defineProperty(exports, 'ALIGNMENT', { - enumerable: true, - get: function get() { - return _alignment.KEY; - } -}); -var _clearColumn = __webpack_require__(226); +/***/ }), +/* 98 */ +/***/ (function(module, exports, __webpack_require__) { -Object.defineProperty(exports, 'CLEAR_COLUMN', { - enumerable: true, - get: function get() { - return _clearColumn.KEY; - } -}); +// getting tag from 19.1.3.6 Object.prototype.toString() +var cof = __webpack_require__(37); +var TAG = __webpack_require__(10)('toStringTag'); +// ES3 wrong here +var ARG = cof(function () { return arguments; }()) == 'Arguments'; -var _columnLeft = __webpack_require__(227); +// fallback for IE11 Script Access Denied error +var tryGet = function (it, key) { + try { + return it[key]; + } catch (e) { /* empty */ } +}; -Object.defineProperty(exports, 'COLUMN_LEFT', { - enumerable: true, - get: function get() { - return _columnLeft.KEY; - } -}); +module.exports = function (it) { + var O, T, B; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T + // builtinTag case + : ARG ? cof(O) + // ES3 arguments fallback + : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; +}; -var _columnRight = __webpack_require__(228); -Object.defineProperty(exports, 'COLUMN_RIGHT', { - enumerable: true, - get: function get() { - return _columnRight.KEY; - } -}); +/***/ }), +/* 99 */ +/***/ (function(module, exports, __webpack_require__) { -var _readOnly = __webpack_require__(229); +"use strict"; -Object.defineProperty(exports, 'READ_ONLY', { - enumerable: true, - get: function get() { - return _readOnly.KEY; +var LIBRARY = __webpack_require__(57); +var $export = __webpack_require__(3); +var redefine = __webpack_require__(28); +var hide = __webpack_require__(29); +var has = __webpack_require__(24); +var Iterators = __webpack_require__(45); +var $iterCreate = __webpack_require__(182); +var setToStringTag = __webpack_require__(46); +var getPrototypeOf = __webpack_require__(183); +var ITERATOR = __webpack_require__(10)('iterator'); +var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` +var FF_ITERATOR = '@@iterator'; +var KEYS = 'keys'; +var VALUES = 'values'; + +var returnThis = function () { return this; }; + +module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { + $iterCreate(Constructor, NAME, next); + var getMethod = function (kind) { + if (!BUGGY && kind in proto) return proto[kind]; + switch (kind) { + case KEYS: return function keys() { return new Constructor(this, kind); }; + case VALUES: return function values() { return new Constructor(this, kind); }; + } return function entries() { return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator'; + var DEF_VALUES = DEFAULT == VALUES; + var VALUES_BUG = false; + var proto = Base.prototype; + var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; + var $default = $native || getMethod(DEFAULT); + var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; + var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; + var methods, key, IteratorPrototype; + // Fix native + if ($anyNative) { + IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); + if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { + // Set @@toStringTag to native iterators + setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if (!LIBRARY && !has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis); + } } -}); - -var _redo = __webpack_require__(230); - -Object.defineProperty(exports, 'REDO', { - enumerable: true, - get: function get() { - return _redo.KEY; + // fix Array#{values, @@iterator}.name in V8 / FF + if (DEF_VALUES && $native && $native.name !== VALUES) { + VALUES_BUG = true; + $default = function values() { return $native.call(this); }; } -}); - -var _removeColumn = __webpack_require__(231); - -Object.defineProperty(exports, 'REMOVE_COLUMN', { - enumerable: true, - get: function get() { - return _removeColumn.KEY; + // Define iterator + if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { + hide(proto, ITERATOR, $default); } -}); - -var _removeRow = __webpack_require__(232); - -Object.defineProperty(exports, 'REMOVE_ROW', { - enumerable: true, - get: function get() { - return _removeRow.KEY; + // Plug for library + Iterators[NAME] = $default; + Iterators[TAG] = returnThis; + if (DEFAULT) { + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if (FORCED) for (key in methods) { + if (!(key in proto)) redefine(proto, key, methods[key]); + } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); } -}); + return methods; +}; -var _rowAbove = __webpack_require__(233); -Object.defineProperty(exports, 'ROW_ABOVE', { - enumerable: true, - get: function get() { - return _rowAbove.KEY; - } -}); +/***/ }), +/* 100 */ +/***/ (function(module, exports) { -var _rowBelow = __webpack_require__(234); +module.exports = function (done, value) { + return { value: value, done: !!done }; +}; -Object.defineProperty(exports, 'ROW_BELOW', { - enumerable: true, - get: function get() { - return _rowBelow.KEY; - } -}); -var _separator = __webpack_require__(71); +/***/ }), +/* 101 */ +/***/ (function(module, exports, __webpack_require__) { -Object.defineProperty(exports, 'SEPARATOR', { - enumerable: true, - get: function get() { - return _separator.KEY; - } -}); +"use strict"; -var _undo = __webpack_require__(235); +var global = __webpack_require__(11); +var dP = __webpack_require__(18); +var DESCRIPTORS = __webpack_require__(20); +var SPECIES = __webpack_require__(10)('species'); -Object.defineProperty(exports, 'UNDO', { - enumerable: true, - get: function get() { - return _undo.KEY; - } -}); -exports.predefinedItems = predefinedItems; -exports.addItem = addItem; +module.exports = function (KEY) { + var C = global[KEY]; + if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, { + configurable: true, + get: function () { return this; } + }); +}; -var _object = __webpack_require__(1); -var _alignment2 = _interopRequireDefault(_alignment); - -var _clearColumn2 = _interopRequireDefault(_clearColumn); - -var _columnLeft2 = _interopRequireDefault(_columnLeft); - -var _columnRight2 = _interopRequireDefault(_columnRight); - -var _readOnly2 = _interopRequireDefault(_readOnly); +/***/ }), +/* 102 */ +/***/ (function(module, exports, __webpack_require__) { -var _redo2 = _interopRequireDefault(_redo); +// Works with __proto__ only. Old v8 can't work with null proto objects. +/* eslint-disable no-proto */ +var isObject = __webpack_require__(14); +var anObject = __webpack_require__(16); +var check = function (O, proto) { + anObject(O); + if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!"); +}; +module.exports = { + set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line + function (test, buggy, set) { + try { + set = __webpack_require__(30)(Function.call, __webpack_require__(72).f(Object.prototype, '__proto__').set, 2); + set(test, []); + buggy = !(test instanceof Array); + } catch (e) { buggy = true; } + return function setPrototypeOf(O, proto) { + check(O, proto); + if (buggy) O.__proto__ = proto; + else set(O, proto); + return O; + }; + }({}, false) : undefined), + check: check +}; -var _removeColumn2 = _interopRequireDefault(_removeColumn); -var _removeRow2 = _interopRequireDefault(_removeRow); +/***/ }), +/* 103 */ +/***/ (function(module, exports, __webpack_require__) { -var _rowAbove2 = _interopRequireDefault(_rowAbove); +"use strict"; -var _rowBelow2 = _interopRequireDefault(_rowBelow); +var strong = __webpack_require__(90); +var validate = __webpack_require__(39); +var SET = 'Set'; -var _separator2 = _interopRequireDefault(_separator); +// 23.2 Set Objects +module.exports = __webpack_require__(58)(SET, function (get) { + return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); }; +}, { + // 23.2.3.1 Set.prototype.add(value) + add: function add(value) { + return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value); + } +}, strong); -var _undo2 = _interopRequireDefault(_undo); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/***/ }), +/* 104 */ +/***/ (function(module, exports, __webpack_require__) { -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +"use strict"; -var ITEMS = exports.ITEMS = [_rowAbove.KEY, _rowBelow.KEY, _columnLeft.KEY, _columnRight.KEY, _clearColumn.KEY, _removeRow.KEY, _removeColumn.KEY, _undo.KEY, _redo.KEY, _readOnly.KEY, _alignment.KEY, _separator.KEY]; +var each = __webpack_require__(59)(0); +var redefine = __webpack_require__(28); +var meta = __webpack_require__(47); +var assign = __webpack_require__(106); +var weak = __webpack_require__(107); +var isObject = __webpack_require__(14); +var fails = __webpack_require__(23); +var validate = __webpack_require__(39); +var WEAK_MAP = 'WeakMap'; +var getWeak = meta.getWeak; +var isExtensible = Object.isExtensible; +var uncaughtFrozenStore = weak.ufstore; +var tmp = {}; +var InternalMap; + +var wrapper = function (get) { + return function WeakMap() { + return get(this, arguments.length > 0 ? arguments[0] : undefined); + }; +}; -var _predefinedItems = (_predefinedItems2 = {}, _defineProperty(_predefinedItems2, _separator.KEY, _separator2.default), _defineProperty(_predefinedItems2, _rowAbove.KEY, _rowAbove2.default), _defineProperty(_predefinedItems2, _rowBelow.KEY, _rowBelow2.default), _defineProperty(_predefinedItems2, _columnLeft.KEY, _columnLeft2.default), _defineProperty(_predefinedItems2, _columnRight.KEY, _columnRight2.default), _defineProperty(_predefinedItems2, _clearColumn.KEY, _clearColumn2.default), _defineProperty(_predefinedItems2, _removeRow.KEY, _removeRow2.default), _defineProperty(_predefinedItems2, _removeColumn.KEY, _removeColumn2.default), _defineProperty(_predefinedItems2, _undo.KEY, _undo2.default), _defineProperty(_predefinedItems2, _redo.KEY, _redo2.default), _defineProperty(_predefinedItems2, _readOnly.KEY, _readOnly2.default), _defineProperty(_predefinedItems2, _alignment.KEY, _alignment2.default), _predefinedItems2); +var methods = { + // 23.3.3.3 WeakMap.prototype.get(key) + get: function get(key) { + if (isObject(key)) { + var data = getWeak(key); + if (data === true) return uncaughtFrozenStore(validate(this, WEAK_MAP)).get(key); + return data ? data[this._i] : undefined; + } + }, + // 23.3.3.5 WeakMap.prototype.set(key, value) + set: function set(key, value) { + return weak.def(validate(this, WEAK_MAP), key, value); + } +}; -/** - * Gets new object with all predefined menu items. - * - * @returns {Object} - */ -function predefinedItems() { - var items = {}; +// 23.3 WeakMap Objects +var $WeakMap = module.exports = __webpack_require__(58)(WEAK_MAP, wrapper, methods, weak, true, true); - (0, _object.objectEach)(_predefinedItems, function (itemFactory, key) { - items[key] = itemFactory(); +// IE11 WeakMap frozen keys fix +if (fails(function () { return new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7; })) { + InternalMap = weak.getConstructor(wrapper, WEAK_MAP); + assign(InternalMap.prototype, methods); + meta.NEED = true; + each(['delete', 'has', 'get', 'set'], function (key) { + var proto = $WeakMap.prototype; + var method = proto[key]; + redefine(proto, key, function (a, b) { + // store frozen objects on internal weakmap shim + if (isObject(a) && !isExtensible(a)) { + if (!this._f) this._f = new InternalMap(); + var result = this._f[key](a, b); + return key == 'set' ? this : result; + // store all the rest on native weakmap + } return method.call(this, a, b); + }); }); - - return items; } -/** - * Add new predefined menu item to the collection. - * - * @param {String} key Menu command id. - * @param {Object} item Object command descriptor. - */ -function addItem(key, item) { - if (ITEMS.indexOf(key) === -1) { - _predefinedItems[key] = item; - } -} /***/ }), -/* 71 */ +/* 105 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// 7.2.2 IsArray(argument) +var cof = __webpack_require__(37); +module.exports = Array.isArray || function isArray(arg) { + return cof(arg) == 'Array'; +}; -exports.__esModule = true; -exports.default = separatorItem; -var KEY = exports.KEY = '---------'; +/***/ }), +/* 106 */ +/***/ (function(module, exports, __webpack_require__) { -function separatorItem() { - return { - name: KEY - }; -} +"use strict"; -/***/ }), -/* 72 */ -/***/ (function(module, exports) { +// 19.1.2.1 Object.assign(target, source, ...) +var getKeys = __webpack_require__(36); +var gOPS = __webpack_require__(60); +var pIE = __webpack_require__(48); +var toObject = __webpack_require__(38); +var IObject = __webpack_require__(67); +var $assign = Object.assign; + +// should work with symbols and should have deterministic property order (V8 bug) +module.exports = !$assign || __webpack_require__(23)(function () { + var A = {}; + var B = {}; + // eslint-disable-next-line no-undef + var S = Symbol(); + var K = 'abcdefghijklmnopqrst'; + A[S] = 7; + K.split('').forEach(function (k) { B[k] = k; }); + return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K; +}) ? function assign(target, source) { // eslint-disable-line no-unused-vars + var T = toObject(target); + var aLen = arguments.length; + var index = 1; + var getSymbols = gOPS.f; + var isEnum = pIE.f; + while (aLen > index) { + var S = IObject(arguments[index++]); + var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S); + var length = keys.length; + var j = 0; + var key; + while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key]; + } return T; +} : $assign; -module.exports = function(it){ - if(typeof it != 'function')throw TypeError(it + ' is not a function!'); - return it; -}; /***/ }), -/* 73 */ +/* 107 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var $defineProperty = __webpack_require__(19) - , createDesc = __webpack_require__(40); +var redefineAll = __webpack_require__(53); +var getWeak = __webpack_require__(47).getWeak; +var anObject = __webpack_require__(16); +var isObject = __webpack_require__(14); +var anInstance = __webpack_require__(55); +var forOf = __webpack_require__(56); +var createArrayMethod = __webpack_require__(59); +var $has = __webpack_require__(24); +var validate = __webpack_require__(39); +var arrayFind = createArrayMethod(5); +var arrayFindIndex = createArrayMethod(6); +var id = 0; -module.exports = function(object, index, value){ - if(index in object)$defineProperty.f(object, index, createDesc(0, value)); - else object[index] = value; +// fallback for uncaught frozen keys +var uncaughtFrozenStore = function (that) { + return that._l || (that._l = new UncaughtFrozenStore()); }; - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(15) - , document = __webpack_require__(13).document - // in old IE typeof document.createElement is 'object' - , is = isObject(document) && isObject(document.createElement); -module.exports = function(it){ - return is ? document.createElement(it) : {}; +var UncaughtFrozenStore = function () { + this.a = []; +}; +var findUncaughtFrozen = function (store, key) { + return arrayFind(store.a, function (it) { + return it[0] === key; + }); +}; +UncaughtFrozenStore.prototype = { + get: function (key) { + var entry = findUncaughtFrozen(this, key); + if (entry) return entry[1]; + }, + has: function (key) { + return !!findUncaughtFrozen(this, key); + }, + set: function (key, value) { + var entry = findUncaughtFrozen(this, key); + if (entry) entry[1] = value; + else this.a.push([key, value]); + }, + 'delete': function (key) { + var index = arrayFindIndex(this.a, function (it) { + return it[0] === key; + }); + if (~index) this.a.splice(index, 1); + return !!~index; + } }; -/***/ }), -/* 75 */ -/***/ (function(module, exports) { +module.exports = { + getConstructor: function (wrapper, NAME, IS_MAP, ADDER) { + var C = wrapper(function (that, iterable) { + anInstance(that, C, NAME, '_i'); + that._t = NAME; // collection type + that._i = id++; // collection id + that._l = undefined; // leak store for uncaught frozen objects + if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that); + }); + redefineAll(C.prototype, { + // 23.3.3.2 WeakMap.prototype.delete(key) + // 23.4.3.3 WeakSet.prototype.delete(value) + 'delete': function (key) { + if (!isObject(key)) return false; + var data = getWeak(key); + if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key); + return data && $has(data, this._i) && delete data[this._i]; + }, + // 23.3.3.4 WeakMap.prototype.has(key) + // 23.4.3.4 WeakSet.prototype.has(value) + has: function has(key) { + if (!isObject(key)) return false; + var data = getWeak(key); + if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key); + return data && $has(data, this._i); + } + }); + return C; + }, + def: function (that, key, value) { + var data = getWeak(anObject(key), true); + if (data === true) uncaughtFrozenStore(that).set(key, value); + else data[that._i] = value; + return that; + }, + ufstore: uncaughtFrozenStore +}; -// IE 8- don't enum bug keys -module.exports = ( - 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' -).split(','); /***/ }), -/* 76 */ +/* 108 */ /***/ (function(module, exports, __webpack_require__) { -var MATCH = __webpack_require__(10)('match'); -module.exports = function(KEY){ - var re = /./; - try { - '/./'[KEY](re); - } catch(e){ - try { - re[MATCH] = false; - return !'/./'[KEY](re); - } catch(f){ /* empty */ } - } return true; -}; +"use strict"; -/***/ }), -/* 77 */ -/***/ (function(module, exports, __webpack_require__) { +var weak = __webpack_require__(107); +var validate = __webpack_require__(39); +var WEAK_SET = 'WeakSet'; + +// 23.4 WeakSet Objects +__webpack_require__(58)(WEAK_SET, function (get) { + return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); }; +}, { + // 23.4.3.1 WeakSet.prototype.add(value) + add: function add(value) { + return weak.def(validate(this, WEAK_SET), value, true); + } +}, weak, false, true); -// fallback for non-array-like ES3 and non-enumerable old V8 strings -var cof = __webpack_require__(38); -module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ - return cof(it) == 'String' ? it.split('') : Object(it); -}; /***/ }), -/* 78 */ +/* 109 */ /***/ (function(module, exports, __webpack_require__) { -var ITERATOR = __webpack_require__(10)('iterator') - , SAFE_CLOSING = false; - -try { - var riter = [7][ITERATOR](); - riter['return'] = function(){ SAFE_CLOSING = true; }; - Array.from(riter, function(){ throw 2; }); -} catch(e){ /* empty */ } +"use strict"; -module.exports = function(exec, skipClosing){ - if(!skipClosing && !SAFE_CLOSING)return false; - var safe = false; +var LIBRARY = __webpack_require__(57); +var global = __webpack_require__(11); +var ctx = __webpack_require__(30); +var classof = __webpack_require__(98); +var $export = __webpack_require__(3); +var isObject = __webpack_require__(14); +var aFunction = __webpack_require__(54); +var anInstance = __webpack_require__(55); +var forOf = __webpack_require__(56); +var speciesConstructor = __webpack_require__(187); +var task = __webpack_require__(73).set; +var microtask = __webpack_require__(189)(); +var newPromiseCapabilityModule = __webpack_require__(110); +var perform = __webpack_require__(190); +var promiseResolve = __webpack_require__(191); +var PROMISE = 'Promise'; +var TypeError = global.TypeError; +var process = global.process; +var $Promise = global[PROMISE]; +var isNode = classof(process) == 'process'; +var empty = function () { /* empty */ }; +var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; +var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f; + +var USE_NATIVE = !!function () { try { - var arr = [7] - , iter = arr[ITERATOR](); - iter.next = function(){ return {done: safe = true}; }; - arr[ITERATOR] = function(){ return iter; }; - exec(arr); - } catch(e){ /* empty */ } - return safe; -}; - -/***/ }), -/* 79 */ -/***/ (function(module, exports, __webpack_require__) { - -// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) -var anObject = __webpack_require__(18) - , dPs = __webpack_require__(290) - , enumBugKeys = __webpack_require__(75) - , IE_PROTO = __webpack_require__(82)('IE_PROTO') - , Empty = function(){ /* empty */ } - , PROTOTYPE = 'prototype'; + // correct subclassing with @@species support + var promise = $Promise.resolve(1); + var FakePromise = (promise.constructor = {})[__webpack_require__(10)('species')] = function (exec) { + exec(empty, empty); + }; + // unhandled rejections tracking support, NodeJS Promise without it fails @@species test + return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise; + } catch (e) { /* empty */ } +}(); -// Create object with fake `null` prototype: use iframe Object with cleared prototype -var createDict = function(){ - // Thrash, waste and sodomy: IE GC bug - var iframe = __webpack_require__(74)('iframe') - , i = enumBugKeys.length - , lt = '<' - , gt = '>' - , iframeDocument; - iframe.style.display = 'none'; - __webpack_require__(160).appendChild(iframe); - iframe.src = 'javascript:'; // eslint-disable-line no-script-url - // createDict = iframe.contentWindow.Object; - // html.removeChild(iframe); - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); - iframeDocument.close(); - createDict = iframeDocument.F; - while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]]; - return createDict(); +// helpers +var isThenable = function (it) { + var then; + return isObject(it) && typeof (then = it.then) == 'function' ? then : false; }; - -module.exports = Object.create || function create(O, Properties){ - var result; - if(O !== null){ - Empty[PROTOTYPE] = anObject(O); - result = new Empty; - Empty[PROTOTYPE] = null; - // add "__proto__" for Object.getPrototypeOf polyfill - result[IE_PROTO] = O; - } else result = createDict(); - return Properties === undefined ? result : dPs(result, Properties); +var notify = function (promise, isReject) { + if (promise._n) return; + promise._n = true; + var chain = promise._c; + microtask(function () { + var value = promise._v; + var ok = promise._s == 1; + var i = 0; + var run = function (reaction) { + var handler = ok ? reaction.ok : reaction.fail; + var resolve = reaction.resolve; + var reject = reaction.reject; + var domain = reaction.domain; + var result, then; + try { + if (handler) { + if (!ok) { + if (promise._h == 2) onHandleUnhandled(promise); + promise._h = 1; + } + if (handler === true) result = value; + else { + if (domain) domain.enter(); + result = handler(value); + if (domain) domain.exit(); + } + if (result === reaction.promise) { + reject(TypeError('Promise-chain cycle')); + } else if (then = isThenable(result)) { + then.call(result, resolve, reject); + } else resolve(result); + } else reject(value); + } catch (e) { + reject(e); + } + }; + while (chain.length > i) run(chain[i++]); // variable length - can't use forEach + promise._c = []; + promise._n = false; + if (isReject && !promise._h) onUnhandled(promise); + }); +}; +var onUnhandled = function (promise) { + task.call(global, function () { + var value = promise._v; + var unhandled = isUnhandled(promise); + var result, handler, console; + if (unhandled) { + result = perform(function () { + if (isNode) { + process.emit('unhandledRejection', value, promise); + } else if (handler = global.onunhandledrejection) { + handler({ promise: promise, reason: value }); + } else if ((console = global.console) && console.error) { + console.error('Unhandled promise rejection', value); + } + }); + // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should + promise._h = isNode || isUnhandled(promise) ? 2 : 1; + } promise._a = undefined; + if (unhandled && result.e) throw result.v; + }); +}; +var isUnhandled = function (promise) { + if (promise._h == 1) return false; + var chain = promise._a || promise._c; + var i = 0; + var reaction; + while (chain.length > i) { + reaction = chain[i++]; + if (reaction.fail || !isUnhandled(reaction.promise)) return false; + } return true; +}; +var onHandleUnhandled = function (promise) { + task.call(global, function () { + var handler; + if (isNode) { + process.emit('rejectionHandled', promise); + } else if (handler = global.onrejectionhandled) { + handler({ promise: promise, reason: promise._v }); + } + }); +}; +var $reject = function (value) { + var promise = this; + if (promise._d) return; + promise._d = true; + promise = promise._w || promise; // unwrap + promise._v = value; + promise._s = 2; + if (!promise._a) promise._a = promise._c.slice(); + notify(promise, true); +}; +var $resolve = function (value) { + var promise = this; + var then; + if (promise._d) return; + promise._d = true; + promise = promise._w || promise; // unwrap + try { + if (promise === value) throw TypeError("Promise can't be resolved itself"); + if (then = isThenable(value)) { + microtask(function () { + var wrapper = { _w: promise, _d: false }; // wrap + try { + then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); + } catch (e) { + $reject.call(wrapper, e); + } + }); + } else { + promise._v = value; + promise._s = 1; + notify(promise, false); + } + } catch (e) { + $reject.call({ _w: promise, _d: false }, e); // wrap + } }; +// constructor polyfill +if (!USE_NATIVE) { + // 25.4.3.1 Promise(executor) + $Promise = function Promise(executor) { + anInstance(this, $Promise, PROMISE, '_h'); + aFunction(executor); + Internal.call(this); + try { + executor(ctx($resolve, this, 1), ctx($reject, this, 1)); + } catch (err) { + $reject.call(this, err); + } + }; + // eslint-disable-next-line no-unused-vars + Internal = function Promise(executor) { + this._c = []; // <- awaiting reactions + this._a = undefined; // <- checked in isUnhandled reactions + this._s = 0; // <- state + this._d = false; // <- done + this._v = undefined; // <- value + this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled + this._n = false; // <- notify + }; + Internal.prototype = __webpack_require__(53)($Promise.prototype, { + // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) + then: function then(onFulfilled, onRejected) { + var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); + reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; + reaction.fail = typeof onRejected == 'function' && onRejected; + reaction.domain = isNode ? process.domain : undefined; + this._c.push(reaction); + if (this._a) this._a.push(reaction); + if (this._s) notify(this, false); + return reaction.promise; + }, + // 25.4.5.1 Promise.prototype.catch(onRejected) + 'catch': function (onRejected) { + return this.then(undefined, onRejected); + } + }); + OwnPromiseCapability = function () { + var promise = new Internal(); + this.promise = promise; + this.resolve = ctx($resolve, promise, 1); + this.reject = ctx($reject, promise, 1); + }; + newPromiseCapabilityModule.f = newPromiseCapability = function (C) { + return C === $Promise || C === Wrapper + ? new OwnPromiseCapability(C) + : newGenericPromiseCapability(C); + }; +} -/***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { +$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise }); +__webpack_require__(46)($Promise, PROMISE); +__webpack_require__(101)(PROMISE); +Wrapper = __webpack_require__(44)[PROMISE]; -var pIE = __webpack_require__(47) - , createDesc = __webpack_require__(40) - , toIObject = __webpack_require__(23) - , toPrimitive = __webpack_require__(86) - , has = __webpack_require__(22) - , IE8_DOM_DEFINE = __webpack_require__(161) - , gOPD = Object.getOwnPropertyDescriptor; +// statics +$export($export.S + $export.F * !USE_NATIVE, PROMISE, { + // 25.4.4.5 Promise.reject(r) + reject: function reject(r) { + var capability = newPromiseCapability(this); + var $$reject = capability.reject; + $$reject(r); + return capability.promise; + } +}); +$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { + // 25.4.4.6 Promise.resolve(x) + resolve: function resolve(x) { + return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x); + } +}); +$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(71)(function (iter) { + $Promise.all(iter)['catch'](empty); +})), PROMISE, { + // 25.4.4.1 Promise.all(iterable) + all: function all(iterable) { + var C = this; + var capability = newPromiseCapability(C); + var resolve = capability.resolve; + var reject = capability.reject; + var result = perform(function () { + var values = []; + var index = 0; + var remaining = 1; + forOf(iterable, false, function (promise) { + var $index = index++; + var alreadyCalled = false; + values.push(undefined); + remaining++; + C.resolve(promise).then(function (value) { + if (alreadyCalled) return; + alreadyCalled = true; + values[$index] = value; + --remaining || resolve(values); + }, reject); + }); + --remaining || resolve(values); + }); + if (result.e) reject(result.v); + return capability.promise; + }, + // 25.4.4.4 Promise.race(iterable) + race: function race(iterable) { + var C = this; + var capability = newPromiseCapability(C); + var reject = capability.reject; + var result = perform(function () { + forOf(iterable, false, function (promise) { + C.resolve(promise).then(capability.resolve, reject); + }); + }); + if (result.e) reject(result.v); + return capability.promise; + } +}); -exports.f = __webpack_require__(21) ? gOPD : function getOwnPropertyDescriptor(O, P){ - O = toIObject(O); - P = toPrimitive(P, true); - if(IE8_DOM_DEFINE)try { - return gOPD(O, P); - } catch(e){ /* empty */ } - if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]); -}; /***/ }), -/* 81 */ +/* 110 */ /***/ (function(module, exports, __webpack_require__) { -// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) -var $keys = __webpack_require__(170) - , hiddenKeys = __webpack_require__(75).concat('length', 'prototype'); +"use strict"; -exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){ - return $keys(O, hiddenKeys); -}; +// 25.4.1.5 NewPromiseCapability(C) +var aFunction = __webpack_require__(54); -/***/ }), -/* 82 */ -/***/ (function(module, exports, __webpack_require__) { +function PromiseCapability(C) { + var resolve, reject; + this.promise = new C(function ($$resolve, $$reject) { + if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor'); + resolve = $$resolve; + reject = $$reject; + }); + this.resolve = aFunction(resolve); + this.reject = aFunction(reject); +} -var shared = __webpack_require__(83)('keys') - , uid = __webpack_require__(49); -module.exports = function(key){ - return shared[key] || (shared[key] = uid(key)); +module.exports.f = function (C) { + return new PromiseCapability(C); }; + /***/ }), -/* 83 */ +/* 111 */ /***/ (function(module, exports, __webpack_require__) { -var global = __webpack_require__(13) - , SHARED = '__core-js_shared__' - , store = global[SHARED] || (global[SHARED] = {}); -module.exports = function(key){ - return store[key] || (store[key] = {}); -}; +"use strict"; -/***/ }), -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { +// ECMAScript 6 symbols shim +var global = __webpack_require__(11); +var has = __webpack_require__(24); +var DESCRIPTORS = __webpack_require__(20); +var $export = __webpack_require__(3); +var redefine = __webpack_require__(28); +var META = __webpack_require__(47).KEY; +var $fails = __webpack_require__(23); +var shared = __webpack_require__(69); +var setToStringTag = __webpack_require__(46); +var uid = __webpack_require__(42); +var wks = __webpack_require__(10); +var wksExt = __webpack_require__(112); +var wksDefine = __webpack_require__(192); +var enumKeys = __webpack_require__(193); +var isArray = __webpack_require__(105); +var anObject = __webpack_require__(16); +var toIObject = __webpack_require__(25); +var toPrimitive = __webpack_require__(65); +var createDesc = __webpack_require__(43); +var _create = __webpack_require__(66); +var gOPNExt = __webpack_require__(194); +var $GOPD = __webpack_require__(72); +var $DP = __webpack_require__(18); +var $keys = __webpack_require__(36); +var gOPD = $GOPD.f; +var dP = $DP.f; +var gOPN = gOPNExt.f; +var $Symbol = global.Symbol; +var $JSON = global.JSON; +var _stringify = $JSON && $JSON.stringify; +var PROTOTYPE = 'prototype'; +var HIDDEN = wks('_hidden'); +var TO_PRIMITIVE = wks('toPrimitive'); +var isEnum = {}.propertyIsEnumerable; +var SymbolRegistry = shared('symbol-registry'); +var AllSymbols = shared('symbols'); +var OPSymbols = shared('op-symbols'); +var ObjectProto = Object[PROTOTYPE]; +var USE_NATIVE = typeof $Symbol == 'function'; +var QObject = global.QObject; +// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 +var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; -// helper for String#{startsWith, endsWith, includes} -var isRegExp = __webpack_require__(165) - , defined = __webpack_require__(30); +// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 +var setSymbolDesc = DESCRIPTORS && $fails(function () { + return _create(dP({}, 'a', { + get: function () { return dP(this, 'a', { value: 7 }).a; } + })).a != 7; +}) ? function (it, key, D) { + var protoDesc = gOPD(ObjectProto, key); + if (protoDesc) delete ObjectProto[key]; + dP(it, key, D); + if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc); +} : dP; -module.exports = function(that, searchString, NAME){ - if(isRegExp(searchString))throw TypeError('String#' + NAME + " doesn't accept regex!"); - return String(defined(that)); +var wrap = function (tag) { + var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]); + sym._k = tag; + return sym; }; -/***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { +var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) { + return typeof it == 'symbol'; +} : function (it) { + return it instanceof $Symbol; +}; -var ctx = __webpack_require__(29) - , invoke = __webpack_require__(286) - , html = __webpack_require__(160) - , cel = __webpack_require__(74) - , global = __webpack_require__(13) - , process = global.process - , setTask = global.setImmediate - , clearTask = global.clearImmediate - , MessageChannel = global.MessageChannel - , counter = 0 - , queue = {} - , ONREADYSTATECHANGE = 'onreadystatechange' - , defer, channel, port; -var run = function(){ - var id = +this; - if(queue.hasOwnProperty(id)){ - var fn = queue[id]; - delete queue[id]; - fn(); - } +var $defineProperty = function defineProperty(it, key, D) { + if (it === ObjectProto) $defineProperty(OPSymbols, key, D); + anObject(it); + key = toPrimitive(key, true); + anObject(D); + if (has(AllSymbols, key)) { + if (!D.enumerable) { + if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {})); + it[HIDDEN][key] = true; + } else { + if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false; + D = _create(D, { enumerable: createDesc(0, false) }); + } return setSymbolDesc(it, key, D); + } return dP(it, key, D); }; -var listener = function(event){ - run.call(event.data); +var $defineProperties = function defineProperties(it, P) { + anObject(it); + var keys = enumKeys(P = toIObject(P)); + var i = 0; + var l = keys.length; + var key; + while (l > i) $defineProperty(it, key = keys[i++], P[key]); + return it; }; -// Node.js 0.9+ & IE10+ has setImmediate, otherwise: -if(!setTask || !clearTask){ - setTask = function setImmediate(fn){ - var args = [], i = 1; - while(arguments.length > i)args.push(arguments[i++]); - queue[++counter] = function(){ - invoke(typeof fn == 'function' ? fn : Function(fn), args); +var $create = function create(it, P) { + return P === undefined ? _create(it) : $defineProperties(_create(it), P); +}; +var $propertyIsEnumerable = function propertyIsEnumerable(key) { + var E = isEnum.call(this, key = toPrimitive(key, true)); + if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false; + return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true; +}; +var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) { + it = toIObject(it); + key = toPrimitive(key, true); + if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return; + var D = gOPD(it, key); + if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true; + return D; +}; +var $getOwnPropertyNames = function getOwnPropertyNames(it) { + var names = gOPN(toIObject(it)); + var result = []; + var i = 0; + var key; + while (names.length > i) { + if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key); + } return result; +}; +var $getOwnPropertySymbols = function getOwnPropertySymbols(it) { + var IS_OP = it === ObjectProto; + var names = gOPN(IS_OP ? OPSymbols : toIObject(it)); + var result = []; + var i = 0; + var key; + while (names.length > i) { + if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]); + } return result; +}; + +// 19.4.1.1 Symbol([description]) +if (!USE_NATIVE) { + $Symbol = function Symbol() { + if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!'); + var tag = uid(arguments.length > 0 ? arguments[0] : undefined); + var $set = function (value) { + if (this === ObjectProto) $set.call(OPSymbols, value); + if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false; + setSymbolDesc(this, tag, createDesc(1, value)); }; - defer(counter); - return counter; - }; - clearTask = function clearImmediate(id){ - delete queue[id]; + if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set }); + return wrap(tag); }; - // Node.js 0.8- - if(__webpack_require__(38)(process) == 'process'){ - defer = function(id){ - process.nextTick(ctx(run, id, 1)); - }; - // Browsers with MessageChannel, includes WebWorkers - } else if(MessageChannel){ - channel = new MessageChannel; - port = channel.port2; - channel.port1.onmessage = listener; - defer = ctx(port.postMessage, port, 1); - // Browsers with postMessage, skip WebWorkers - // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' - } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ - defer = function(id){ - global.postMessage(id + '', '*'); - }; - global.addEventListener('message', listener, false); - // IE8- - } else if(ONREADYSTATECHANGE in cel('script')){ - defer = function(id){ - html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ - html.removeChild(this); - run.call(id); - }; - }; - // Rest old browsers - } else { - defer = function(id){ - setTimeout(ctx(run, id, 1), 0); - }; + redefine($Symbol[PROTOTYPE], 'toString', function toString() { + return this._k; + }); + + $GOPD.f = $getOwnPropertyDescriptor; + $DP.f = $defineProperty; + __webpack_require__(74).f = gOPNExt.f = $getOwnPropertyNames; + __webpack_require__(48).f = $propertyIsEnumerable; + __webpack_require__(60).f = $getOwnPropertySymbols; + + if (DESCRIPTORS && !__webpack_require__(57)) { + redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); } + + wksExt.f = function (name) { + return wrap(wks(name)); + }; } -module.exports = { - set: setTask, - clear: clearTask -}; -/***/ }), -/* 86 */ -/***/ (function(module, exports, __webpack_require__) { +$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol }); + +for (var es6Symbols = ( + // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 + 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' +).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]); + +for (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]); + +$export($export.S + $export.F * !USE_NATIVE, 'Symbol', { + // 19.4.2.1 Symbol.for(key) + 'for': function (key) { + return has(SymbolRegistry, key += '') + ? SymbolRegistry[key] + : SymbolRegistry[key] = $Symbol(key); + }, + // 19.4.2.5 Symbol.keyFor(sym) + keyFor: function keyFor(sym) { + if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!'); + for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key; + }, + useSetter: function () { setter = true; }, + useSimple: function () { setter = false; } +}); + +$export($export.S + $export.F * !USE_NATIVE, 'Object', { + // 19.1.2.2 Object.create(O [, Properties]) + create: $create, + // 19.1.2.4 Object.defineProperty(O, P, Attributes) + defineProperty: $defineProperty, + // 19.1.2.3 Object.defineProperties(O, Properties) + defineProperties: $defineProperties, + // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) + getOwnPropertyDescriptor: $getOwnPropertyDescriptor, + // 19.1.2.7 Object.getOwnPropertyNames(O) + getOwnPropertyNames: $getOwnPropertyNames, + // 19.1.2.8 Object.getOwnPropertySymbols(O) + getOwnPropertySymbols: $getOwnPropertySymbols +}); + +// 24.3.2 JSON.stringify(value [, replacer [, space]]) +$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () { + var S = $Symbol(); + // MS Edge converts symbol values to JSON as {} + // WebKit converts symbol values to JSON as null + // V8 throws on boxed symbols + return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}'; +})), 'JSON', { + stringify: function stringify(it) { + if (it === undefined || isSymbol(it)) return; // IE8 returns string on undefined + var args = [it]; + var i = 1; + var replacer, $replacer; + while (arguments.length > i) args.push(arguments[i++]); + replacer = args[1]; + if (typeof replacer == 'function') $replacer = replacer; + if ($replacer || !isArray(replacer)) replacer = function (key, value) { + if ($replacer) value = $replacer.call(this, key, value); + if (!isSymbol(value)) return value; + }; + args[1] = replacer; + return _stringify.apply($JSON, args); + } +}); + +// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) +$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(29)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); +// 19.4.3.5 Symbol.prototype[@@toStringTag] +setToStringTag($Symbol, 'Symbol'); +// 20.2.1.9 Math[@@toStringTag] +setToStringTag(Math, 'Math', true); +// 24.3.3 JSON[@@toStringTag] +setToStringTag(global.JSON, 'JSON', true); -// 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(15); -// instead of the ES6 spec version, we didn't implement @@toPrimitive case -// and the second argument - flag - preferred type is a string -module.exports = function(it, S){ - if(!isObject(it))return it; - var fn, val; - if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; - if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val; - if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; - throw TypeError("Can't convert object to primitive value"); -}; /***/ }), -/* 87 */ -/***/ (function(module, exports) { +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { + +exports.f = __webpack_require__(10); -module.exports = __WEBPACK_EXTERNAL_MODULE_87__; /***/ }), -/* 88 */ +/* 113 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// 19.1.3.1 Object.assign(target, source) +var $export = __webpack_require__(3); +$export($export.S + $export.F, 'Object', { assign: __webpack_require__(106) }); -exports.__esModule = true; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +/***/ }), +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { -var _mixed = __webpack_require__(20); +// 19.1.3.10 Object.is(value1, value2) +var $export = __webpack_require__(3); +$export($export.S, 'Object', { is: __webpack_require__(195) }); -var _object = __webpack_require__(1); -/** - * @alias Options - * @constructor - * @description +/***/ }), +/* 115 */ +/***/ (function(module, exports, __webpack_require__) { - * ## Constructor options - * - * Constructor options are applied using an object literal passed as a second argument to the Handsontable constructor. - * - * ```js - * var hot = new Handsontable(document.getElementById('example1'), { - * data: myArray, - * width: 400, - * height: 300 - * }); - * ``` - * - * --- - * ## Cascading configuration - * - * Handsontable 0.9 and newer is using *Cascading Configuration*, which is a fast way to provide configuration options - * for the entire table, including its columns and particular cells. - * - * Consider the following example: - * ```js - * var hot = new Handsontable(document.getElementById('example'), { - * readOnly: true, - * columns: [ - * {readOnly: false}, - * {}, - * {} - * ], - * cells: function (row, col, prop) { - * var cellProperties = {}; - * - * if (row === 0 && col === 0) { - * cellProperties.readOnly = true; - * } - * - * return cellProperties; - * } - * }); - * ``` - * - * The above notation will result in all TDs being *read only*, except for first column TDs which will be *editable*, except for the TD in top left corner which will still be *read only*. - * - * ### The Cascading Configuration model - * - * ##### 1. Constructor - * - * Configuration options that are provided using first-level `handsontable(container, {option: "value"})` and `updateSettings` method. - * - * ##### 2. Columns - * - * Configuration options that are provided using second-level object `handsontable(container, {columns: {option: "value"}]})` - * - * ##### 3. Cells - * - * Configuration options that are provided using third-level function `handsontable(container, {cells: function: (row, col, prop){ }})` - * - * --- - * ## Architecture performance - * - * The Cascading Configuration model is based on prototypical inheritance. It is much faster and memory efficient compared - * to the previous model that used jQuery extend. See: [http://jsperf.com/extending-settings](http://jsperf.com/extending-settings). - * - * --- - * __Important notice:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`. - */ -function DefaultSettings() {}; +// 19.1.3.19 Object.setPrototypeOf(O, proto) +var $export = __webpack_require__(3); +$export($export.S, 'Object', { setPrototypeOf: __webpack_require__(102).set }); -DefaultSettings.prototype = { - /** - * License key for commercial version of Handsontable. - * - * @pro - * @type {String} - * @default 'trial' - */ - licenseKey: 'trial', - /** - * @description - * Initial data source that will be bound to the data grid __by reference__ (editing data grid alters the data source). - * Can be declared as an Array of Arrays, Array of Objects or a Function. - * - * See [Understanding binding as reference](http://docs.handsontable.com/tutorial-data-binding.html#page-reference). - * - * @type {Array|Function} - * @default undefined - */ - data: void 0, +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Defines the structure of a new row when data source is an array of objects. - * - * See [data-schema](http://docs.handsontable.com/tutorial-data-sources.html#page-data-schema) for examples. - * - * @type {Object} - * @default undefined - */ - dataSchema: void 0, +var dP = __webpack_require__(18).f; +var FProto = Function.prototype; +var nameRE = /^\s*function ([^ (]*)/; +var NAME = 'name'; - /** - * Width of the grid. Can be a value or a function that returns a value. - * - * @type {Number|Function} - * @default undefined - */ - width: void 0, +// 19.2.4.2 name +NAME in FProto || __webpack_require__(20) && dP(FProto, NAME, { + configurable: true, + get: function () { + try { + return ('' + this).match(nameRE)[1]; + } catch (e) { + return ''; + } + } +}); - /** - * Height of the grid. Can be a number or a function that returns a number. - * - * @type {Number|Function} - * @default undefined - */ - height: void 0, - /** - * @description - * Initial number of rows. - * - * __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided - * - * @type {Number} - * @default 5 - */ - startRows: 5, +/***/ }), +/* 117 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Initial number of columns. - * - * __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided - * - * @type {Number} - * @default 5 - */ - startCols: 5, +var $export = __webpack_require__(3); +var toIObject = __webpack_require__(25); +var toLength = __webpack_require__(21); - /** - * Setting `true` or `false` will enable or disable the default row headers (1, 2, 3). - * You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers. - * If a function is set the index of the row is passed as a parameter. - * - * @type {Boolean|Array|Function} - * @default null - * @example - * ```js - * ... - * // as boolean - * rowHeaders: true, - * ... - * - * ... - * // as array - * rowHeaders: [1, 2, 3], - * ... - * - * ... - * // as function - * rowHeaders: function(index) { - * return index + ': AB'; - * }, - * ... - * ``` - */ - rowHeaders: void 0, +$export($export.S, 'String', { + // 21.1.2.4 String.raw(callSite, ...substitutions) + raw: function raw(callSite) { + var tpl = toIObject(callSite.raw); + var len = toLength(tpl.length); + var aLen = arguments.length; + var res = []; + var i = 0; + while (len > i) { + res.push(String(tpl[i++])); + if (i < aLen) res.push(String(arguments[i])); + } return res.join(''); + } +}); - /** - * Setting `true` or `false` will enable or disable the default column headers (A, B, C). - * You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers. - * If a function is set, then the index of the column is passed as a parameter. - * - * @type {Boolean|Array|Function} - * @default null - * @example - * ```js - * ... - * // as boolean - * colHeaders: true, - * ... - * - * ... - * // as array - * colHeaders: ['A', 'B', 'C'], - * ... - * - * ... - * // as function - * colHeaders: function(index) { - * return index + ': AB'; - * }, - * ... - * ``` - */ - colHeaders: null, - /** - * Defines column widths in pixels. Accepts number, string (that will be converted to a number), - * array of numbers (if you want to define column width separately for each column) or a - * function (if you want to set column width dynamically on each render). - * - * @type {Array|Function|Number|String} - * @default undefined - * @example - * ```js - * ... - * // as numeric, for each column. - * colWidths: 100, - * ... - * - * * ... - * // as string, for each column. - * colWidths: '100px', - * ... - * - * ... - * // as array, based on visual indexes. The rest of the columns have a default width. - * colWidths: [100, 120, 90], - * ... - * - * ... - * // as function, based on visual indexes. - * colWidths: function(index) { - * return index * 10; - * }, - * ... - * ``` - */ - colWidths: void 0, +/***/ }), +/* 118 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Defines row heights in pixels. Accepts numbers, strings (that will be converted into a number), - * array of numbers (if you want to define row height separately for each row) or a - * function (if you want to set row height dynamically on each render). - * If the ManualRowResize or AutoRowSize plugins are enabled, this is also the minimum height that can be set - * via either of those two plugins. - * Height should be equal or greater than 23px. Table is rendered incorrectly if height is less than 23px. - * - * @type {Array|Function|Number|String} - * @default undefined - * @example - * ```js - * ... - * // as numeric, for each row. - * rowHeights: 100, - * ... - * - * * ... - * // as string, for each row. - * rowHeights: '100px', - * ... - * - * ... - * // as array, based on visual indexes. The rest of the rows have a default height. - * rowHeights: [100, 120, 90], - * ... - * - * ... - * // as function, based on visual indexes. - * rowHeights: function(index) { - * return index * 10; - * }, - * ... - * ``` - */ - rowHeights: void 0, +var $export = __webpack_require__(3); +var toAbsoluteIndex = __webpack_require__(52); +var fromCharCode = String.fromCharCode; +var $fromCodePoint = String.fromCodePoint; - /** - * @description - * Defines the cell properties and data binding for certain columns. - * - * __Notice:__ Using this option sets a fixed number of columns (options `startCols`, `minCols`, `maxCols` will be ignored). - * - * See [documentation -> datasources.html](http://docs.handsontable.com/tutorial-data-sources.html#page-nested) for examples. - * - * @type {Array|Function} - * @default undefined - * @example - * ```js - * ... - * // as an array of objects. Order of the objects in array is representation of physical indexes. - * columns: [ - * { - * // column options for the first column - * type: 'numeric', - * format: '0,0.00 $' - * }, - * { - * // column options for the second column - * type: 'text', - * readOnly: true - * } - * ], - * ... - * - * // or as function, based on physical indexes - * ... - * columns: function(index) { - * return { - * type: index > 0 ? 'numeric' : 'text', - * readOnly: index < 1 - * } - * } - * ... - * ``` - */ - columns: void 0, +// length should be 1, old FF problem +$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', { + // 21.1.2.2 String.fromCodePoint(...codePoints) + fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars + var res = []; + var aLen = arguments.length; + var i = 0; + var code; + while (aLen > i) { + code = +arguments[i++]; + if (toAbsoluteIndex(code, 0x10ffff) !== code) throw RangeError(code + ' is not a valid code point'); + res.push(code < 0x10000 + ? fromCharCode(code) + : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00) + ); + } return res.join(''); + } +}); - /** - * @description - * Defines the cell properties for given `row`, `col`, `prop` coordinates. - * Any constructor or column option may be overwritten for a particular cell (row/column combination) - * using the `cells` property in the Handsontable constructor. - * - * __Note:__ Parameters `row` and `col` always represent __physical indexes__. Example below show how to execute - * operations based on the __visual__ representation of Handsontable. - * - * Possible values of `prop`: - * - property name for column's data source object, when dataset is an [array of objects](/tutorial-data-sources.html#page-object) - * - the same number as `col`, when dataset is an [array of arrays](/tutorial-data-sources.html#page-array) - * - * @type {Function} - * @default undefined - * @example - * ```js - * ... - * cells: function (row, col, prop) { - * var cellProperties = {}; - * var visualRowIndex = this.instance.toVisualRow(row); - * var visualColIndex = this.instance.toVisualColumn(col); - * - * if (visualRowIndex === 0 && visualColIndex === 0) { - * cellProperties.readOnly = true; - * } - * - * return cellProperties; - * }, - * ... - * ``` - */ - cells: void 0, - /** - * Any constructor or column option may be overwritten for a particular cell (row/column combination), using `cell` - * array passed to the Handsontable constructor. - * - * @type {Array} - * @default [] - * @example - * ```js - * ... - * cell: [ - * {row: 0, col: 0, readOnly: true} - * ], - * ... - * ``` - */ - cell: [], +/***/ }), +/* 119 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * If `true`, enables the {@link Comments} plugin, which enables an option to apply cell comments through the context menu - * (configurable with context menu keys `commentsAddEdit`, `commentsRemove`). - * - * To initialize Handsontable with predefined comments, provide cell coordinates and comment text values in a form of an array. - * - * See [Comments](http://docs.handsontable.com/demo-comments_.html) demo for examples. - * - * @since 0.11.0 - * @type {Boolean|Array} - * @default false - * @example - * ```js - * ... - * comments: [{row: 1, col: 1, comment: {value: "Test comment"}}], - * ... - * ``` - */ - comments: false, +"use strict"; - /** - * @description - * If `true`, enables the Custom Borders plugin, which enables an option to apply custom borders through the context menu (configurable with context menu key `borders`). - * - * To initialize Handsontable with predefined custom borders, provide cell coordinates and border styles in a form of an array. - * - * See [Custom Borders](http://docs.handsontable.com/demo-custom-borders.html) demo for examples. - * - * @since 0.11.0 - * @type {Boolean|Array} - * @default false - * @example - * ```js - * ... - * customBorders: [ - * {range: { - * from: {row: 1, col: 1}, - * to: {row: 3, col: 4}}, - * left: {}, - * right: {}, - * top: {}, - * bottom: {} - * } - * ], - * ... - * - * // or - * ... - * customBorders: [ - * {row: 2, col: 2, left: {width: 2, color: 'red'}, - * right: {width: 1, color: 'green'}, top: '', bottom: ''} - * ], - * ... - * ``` - */ - customBorders: false, +var $export = __webpack_require__(3); +var $at = __webpack_require__(196)(false); +$export($export.P, 'String', { + // 21.1.3.3 String.prototype.codePointAt(pos) + codePointAt: function codePointAt(pos) { + return $at(this, pos); + } +}); - /** - * Minimum number of rows. At least that number of rows will be created during initialization. - * - * @type {Number} - * @default 0 - */ - minRows: 0, - /** - * Minimum number of columns. At least that number of columns will be created during initialization. - * - * @type {Number} - * @default 0 - */ - minCols: 0, +/***/ }), +/* 120 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Maximum number of rows. If set to a value lower than the initial row count, the data will be trimmed to the provided value as the number of rows. - * - * @type {Number} - * @default Infinity - */ - maxRows: Infinity, +var $export = __webpack_require__(3); - /** - * Maximum number of cols. If set to a value lower than the initial col count, the data will be trimmed to the provided value as the number of cols. - * - * @type {Number} - * @default Infinity - */ - maxCols: Infinity, +$export($export.P, 'String', { + // 21.1.3.13 String.prototype.repeat(count) + repeat: __webpack_require__(121) +}); - /** - * When set to 1 (or more), Handsontable will add a new row at the end of grid if there are no more empty rows. - * (unless the number of rows exceeds the one set in the `maxRows` property) - * - * @type {Number} - * @default 0 - */ - minSpareRows: 0, - /** - * When set to 1 (or more), Handsontable will add a new column at the end of grid if there are no more empty columns. - * (unless the number of rows exceeds the one set in the `maxCols` property) - * - * @type {Number} - * @default 0 - */ - minSpareCols: 0, +/***/ }), +/* 121 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * If set to `false`, there won't be an option to insert new rows in the Context Menu. - * - * @type {Boolean} - * @default true - */ - allowInsertRow: true, +"use strict"; - /** - * If set to `false`, there won't be an option to insert new columns in the Context Menu. - * - * @type {Boolean} - * @default true - */ - allowInsertColumn: true, +var toInteger = __webpack_require__(51); +var defined = __webpack_require__(33); - /** - * If set to `false`, there won't be an option to remove rows in the Context Menu. - * - * @type {Boolean} - * @default true - */ - allowRemoveRow: true, +module.exports = function repeat(count) { + var str = String(defined(this)); + var res = ''; + var n = toInteger(count); + if (n < 0 || n == Infinity) throw RangeError("Count can't be negative"); + for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str; + return res; +}; - /** - * If set to `false`, there won't be an option to remove columns in the Context Menu. - * - * @type {Boolean} - * @default true - */ - allowRemoveColumn: true, - /** - * If true, selection of multiple cells using keyboard or mouse is allowed. - * - * @type {Boolean} - * @default true - */ - multiSelect: true, +/***/ }), +/* 122 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Enables the fill handle (drag-down and copy-down) functionality, which shows a small rectangle in bottom - * right corner of the selected area, that let's you expand values to the adjacent cells. - * - * Possible values: `true` (to enable in all directions), `'vertical'` or `'horizontal'` (to enable in one direction), - * `false` (to disable completely). Setting to `true` enables the fillHandle plugin. - * - * Since 0.23.0 you can pass object to plugin which allows you to add more options for this functionality. If `autoInsertRow` - * option is `true`, fill-handler will create new rows till it reaches the last row. It is enabled by default. - * - * @example - * ```js - * ... - * fillHandle: true // enable plugin in all directions and with autoInsertRow as true - * ... - * // or - * ... - * fillHandle: 'vertical' // enable plugin in vertical direction and with autoInsertRow as true - * ... - * // or - * ... - * fillHandle: { // enable plugin in both directions and with autoInsertRow as false - * autoInsertRow: false, - * } - * // or - * ... - * fillHandle: { // enable plugin in vertical direction and with autoInsertRow as false - * autoInsertRow: false, - * direction: 'vertical' // 'vertical' or 'horizontal' - * } - * ``` - * - * @type {Boolean|String|Object} - * @default true - */ - fillHandle: true, +"use strict"; +// 21.1.3.18 String.prototype.startsWith(searchString [, position ]) - /** - * Allows to specify the number of fixed (or *frozen*) rows at the top of the table. - * - * @type {Number} - * @default 0 - * @example - * ```js - * fixedRowsTop: 3 // This would freeze the top 3 rows of the table. - * ``` - */ - fixedRowsTop: 0, +var $export = __webpack_require__(3); +var toLength = __webpack_require__(21); +var context = __webpack_require__(75); +var STARTS_WITH = 'startsWith'; +var $startsWith = ''[STARTS_WITH]; - /** - * Allows to specify the number of fixed (or *frozen*) rows at the bottom of the table. - * - * @pro - * @type {Number} - * @default 0 - * @example - * ```js - * fixedRowsBottom: 3 // This would freeze the top 3 rows of the table. - * ``` - */ - fixedRowsBottom: 0, +$export($export.P + $export.F * __webpack_require__(76)(STARTS_WITH), 'String', { + startsWith: function startsWith(searchString /* , position = 0 */) { + var that = context(this, searchString, STARTS_WITH); + var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length)); + var search = String(searchString); + return $startsWith + ? $startsWith.call(that, search, index) + : that.slice(index, index + search.length) === search; + } +}); - /** - * Allows to specify the number of fixed (or *frozen*) columns on the left of the table. - * - * @type {Number} - * @default 0 - * @example - * ```js - * fixedColumnsLeft: 3 // This would freeze the top 3 rows of the table. - * ``` - */ - fixedColumnsLeft: 0, - /** - * If `true`, mouse click outside the grid will deselect the current selection. - * Can be a function that takes the click event target and returns a boolean. - * - * @type {Boolean|Function} - * @default true - */ - outsideClickDeselects: true, +/***/ }), +/* 123 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * If `true`, ENTER begins editing mode (like in Google Docs). If `false`, ENTER moves to next - * row (like Excel) and adds a new row if necessary. TAB adds new column if necessary. - * - * @type {Boolean} - * @default true - */ - enterBeginsEditing: true, +// 7.2.8 IsRegExp(argument) +var isObject = __webpack_require__(14); +var cof = __webpack_require__(37); +var MATCH = __webpack_require__(10)('match'); +module.exports = function (it) { + var isRegExp; + return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp'); +}; - /** - * Defines the cursor movement after ENTER was pressed (SHIFT + ENTER uses a negative vector). - * Can be an object or a function that returns an object. The event argument passed to the function - * is a DOM Event object received after the ENTER key has been pressed. This event object can be used to check - * whether user pressed ENTER or SHIFT + ENTER. - * - * @type {Object|Function} - * @default {row: 1, col: 0} - */ - enterMoves: { row: 1, col: 0 }, - /** - * Defines the cursor movement after TAB is pressed (SHIFT + TAB uses a negative vector). - * Can be an object or a function that returns an object. The event argument passed to the function - * is a DOM Event object received after the TAB key has been pressed. This event object can be used to check - * whether user pressed TAB or SHIFT + TAB. - * - * @type {Object} - * @default {row: 0, col: 1} - */ - tabMoves: { row: 0, col: 1 }, +/***/ }), +/* 124 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * If `true`, pressing TAB or right arrow in the last column will move to first column in next row. - * - * @type {Boolean} - * @default false - */ - autoWrapRow: false, +"use strict"; +// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition]) - /** - * If `true`, pressing ENTER or down arrow in the last row will move to the first row in the next column. - * - * @type {Boolean} - * @default false - */ - autoWrapCol: false, +var $export = __webpack_require__(3); +var toLength = __webpack_require__(21); +var context = __webpack_require__(75); +var ENDS_WITH = 'endsWith'; +var $endsWith = ''[ENDS_WITH]; - /** - * @description - * Turns on saving the state of column sorting, column positions and column sizes in local storage. - * - * You can save any sort of data in local storage to preserve table state between page reloads. - * In order to enable data storage mechanism, `persistentState` option must be set to `true` (you can set it - * either during Handsontable initialization or using the `updateSettings` method). When `persistentState` is enabled it exposes 3 hooks: - * - * __persistentStateSave__ (key: String, value: Mixed) - * - * * Saves value under given key in browser local storage. - * - * __persistentStateLoad__ (key: String, valuePlaceholder: Object) - * - * * Loads `value`, saved under given key, form browser local storage. The loaded `value` will be saved in `valuePlaceholder.value` - * (this is due to specific behaviour of `Hooks.run()` method). If no value have been saved under key `valuePlaceholder.value` - * will be `undefined`. - * - * __persistentStateReset__ (key: String) - * - * * Clears the value saved under `key`. If no `key` is given, all values associated with table will be cleared. - * - * __Note:__ The main reason behind using `persistentState` hooks rather than regular LocalStorage API is that it - * ensures separation of data stored by multiple Handsontable instances. In other words, if you have two (or more) - * instances of Handsontable on one page, data saved by one instance won't be accessible by the second instance. - * Those two instances can store data under the same key and no data would be overwritten. - * - * __Important:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`. - * - * @type {Boolean} - * @default false - */ - persistentState: void 0, +$export($export.P + $export.F * __webpack_require__(76)(ENDS_WITH), 'String', { + endsWith: function endsWith(searchString /* , endPosition = @length */) { + var that = context(this, searchString, ENDS_WITH); + var endPosition = arguments.length > 1 ? arguments[1] : undefined; + var len = toLength(that.length); + var end = endPosition === undefined ? len : Math.min(toLength(endPosition), len); + var search = String(searchString); + return $endsWith + ? $endsWith.call(that, search, end) + : that.slice(end - search.length, end) === search; + } +}); - /** - * Class name for all visible rows in the current selection. - * - * @type {String} - * @default undefined - * @example - * ```js - * currentRowClassName: 'currentRow' // This will add a 'currentRow' class name to appropriate table cells. - * ``` - */ - currentRowClassName: void 0, - /** - * Class name for all visible columns in the current selection. - * - * @type {String} - * @default undefined - * @example - * ```js - * currentColClassName: 'currentColumn' // This will add a 'currentColumn' class name to appropriate table cells. - * ``` - */ - currentColClassName: void 0, +/***/ }), +/* 125 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Class name for all visible headers in current selection. - * - * @type {String} - * @since 0.27.0 - * @default 'ht__highlight' - * @example - * ```js - * currentHeaderClassName: 'ht__highlight' // This will add a 'ht__highlight' class name to appropriate table headers. - * ``` - */ - currentHeaderClassName: 'ht__highlight', - /** - * Class name for the Handsontable container element. - * - * @type {String|Array} - * @default undefined - */ - className: void 0, +"use strict"; +// 21.1.3.7 String.prototype.includes(searchString, position = 0) - /** - * Class name for all tables inside container element. - * - * @since 0.17.0 - * @type {String|Array} - * @default undefined - */ - tableClassName: void 0, +var $export = __webpack_require__(3); +var context = __webpack_require__(75); +var INCLUDES = 'includes'; - /** - * @description - * Defines how the columns react, when the declared table width is different than the calculated sum of all column widths. - * [See more](http://docs.handsontable.com/demo-stretching.html) mode. Possible values: - * * `'none'` Disable stretching - * * `'last'` Stretch only the last column - * * `'all'` Stretch all the columns evenly - * - * @type {String} - * @default 'none' - */ - stretchH: 'none', +$export($export.P + $export.F * __webpack_require__(76)(INCLUDES), 'String', { + includes: function includes(searchString /* , position = 0 */) { + return !!~context(this, searchString, INCLUDES) + .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined); + } +}); - /** - * Lets you overwrite the default `isEmptyRow` method, which checks if row at the provided index is empty. - * - * @type {Function} - * @param {Number} row Visual row index. - * @returns {Boolean} - */ - isEmptyRow: function isEmptyRow(row) { - var col, colLen, value, meta; - for (col = 0, colLen = this.countCols(); col < colLen; col++) { - value = this.getDataAtCell(row, col); +/***/ }), +/* 126 */ +/***/ (function(module, exports, __webpack_require__) { - if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) { - if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') { - meta = this.getCellMeta(row, col); +// 21.2.5.3 get RegExp.prototype.flags() +if (__webpack_require__(20) && /./g.flags != 'g') __webpack_require__(18).f(RegExp.prototype, 'flags', { + configurable: true, + get: __webpack_require__(197) +}); - return (0, _object.isObjectEquals)(this.getSchema()[meta.prop], value); + +/***/ }), +/* 127 */ +/***/ (function(module, exports, __webpack_require__) { + +// @@match logic +__webpack_require__(61)('match', 1, function (defined, MATCH, $match) { + // 21.1.3.11 String.prototype.match(regexp) + return [function match(regexp) { + 'use strict'; + var O = defined(this); + var fn = regexp == undefined ? undefined : regexp[MATCH]; + return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O)); + }, $match]; +}); + + +/***/ }), +/* 128 */ +/***/ (function(module, exports, __webpack_require__) { + +// @@replace logic +__webpack_require__(61)('replace', 2, function (defined, REPLACE, $replace) { + // 21.1.3.14 String.prototype.replace(searchValue, replaceValue) + return [function replace(searchValue, replaceValue) { + 'use strict'; + var O = defined(this); + var fn = searchValue == undefined ? undefined : searchValue[REPLACE]; + return fn !== undefined + ? fn.call(searchValue, O, replaceValue) + : $replace.call(String(O), searchValue, replaceValue); + }, $replace]; +}); + + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +// @@split logic +__webpack_require__(61)('split', 2, function (defined, SPLIT, $split) { + 'use strict'; + var isRegExp = __webpack_require__(123); + var _split = $split; + var $push = [].push; + var $SPLIT = 'split'; + var LENGTH = 'length'; + var LAST_INDEX = 'lastIndex'; + if ( + 'abbc'[$SPLIT](/(b)*/)[1] == 'c' || + 'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 || + 'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 || + '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 || + '.'[$SPLIT](/()()/)[LENGTH] > 1 || + ''[$SPLIT](/.?/)[LENGTH] + ) { + var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group + // based on es5-shim implementation, need to rework it + $split = function (separator, limit) { + var string = String(this); + if (separator === undefined && limit === 0) return []; + // If `separator` is not a regex, use native split + if (!isRegExp(separator)) return _split.call(string, separator, limit); + var output = []; + var flags = (separator.ignoreCase ? 'i' : '') + + (separator.multiline ? 'm' : '') + + (separator.unicode ? 'u' : '') + + (separator.sticky ? 'y' : ''); + var lastLastIndex = 0; + var splitLimit = limit === undefined ? 4294967295 : limit >>> 0; + // Make `global` and avoid `lastIndex` issues by working with a copy + var separatorCopy = new RegExp(separator.source, flags + 'g'); + var separator2, match, lastIndex, lastLength, i; + // Doesn't need flags gy, but they don't hurt + if (!NPCG) separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags); + while (match = separatorCopy.exec(string)) { + // `separatorCopy.lastIndex` is not reliable cross-browser + lastIndex = match.index + match[0][LENGTH]; + if (lastIndex > lastLastIndex) { + output.push(string.slice(lastLastIndex, match.index)); + // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG + // eslint-disable-next-line no-loop-func + if (!NPCG && match[LENGTH] > 1) match[0].replace(separator2, function () { + for (i = 1; i < arguments[LENGTH] - 2; i++) if (arguments[i] === undefined) match[i] = undefined; + }); + if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1)); + lastLength = match[0][LENGTH]; + lastLastIndex = lastIndex; + if (output[LENGTH] >= splitLimit) break; } - return false; + if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop } - } + if (lastLastIndex === string[LENGTH]) { + if (lastLength || !separatorCopy.test('')) output.push(''); + } else output.push(string.slice(lastLastIndex)); + return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output; + }; + // Chakra, V8 + } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) { + $split = function (separator, limit) { + return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit); + }; + } + // 21.1.3.17 String.prototype.split(separator, limit) + return [function split(separator, limit) { + var O = defined(this); + var fn = separator == undefined ? undefined : separator[SPLIT]; + return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit); + }, $split]; +}); - return true; - }, +/***/ }), +/* 130 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Lets you overwrite the default `isEmptyCol` method, which checks if column at the provided index is empty. - * - * @type {Function} - * @param {Number} col Visual column index - * @returns {Boolean} - */ - isEmptyCol: function isEmptyCol(col) { - var row, rowLen, value; +// @@search logic +__webpack_require__(61)('search', 1, function (defined, SEARCH, $search) { + // 21.1.3.15 String.prototype.search(regexp) + return [function search(regexp) { + 'use strict'; + var O = defined(this); + var fn = regexp == undefined ? undefined : regexp[SEARCH]; + return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O)); + }, $search]; +}); - for (row = 0, rowLen = this.countRows(); row < rowLen; row++) { - value = this.getDataAtCell(row, col); - if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) { - return false; +/***/ }), +/* 131 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ctx = __webpack_require__(30); +var $export = __webpack_require__(3); +var toObject = __webpack_require__(38); +var call = __webpack_require__(95); +var isArrayIter = __webpack_require__(96); +var toLength = __webpack_require__(21); +var createProperty = __webpack_require__(77); +var getIterFn = __webpack_require__(97); + +$export($export.S + $export.F * !__webpack_require__(71)(function (iter) { Array.from(iter); }), 'Array', { + // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) + from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { + var O = toObject(arrayLike); + var C = typeof this == 'function' ? this : Array; + var aLen = arguments.length; + var mapfn = aLen > 1 ? arguments[1] : undefined; + var mapping = mapfn !== undefined; + var index = 0; + var iterFn = getIterFn(O); + var length, result, step, iterator; + if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); + // if object isn't iterable or it's array with default iterator - use simple case + if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) { + for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) { + createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value); + } + } else { + length = toLength(O.length); + for (result = new C(length); length > index; index++) { + createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); } } + result.length = index; + return result; + } +}); - return true; - }, +/***/ }), +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * When set to `true`, the table is re-rendered when it is detected that it was made visible in DOM. - * - * @type {Boolean} - * @default true - */ - observeDOMVisibility: true, +"use strict"; - /** - * If set to `true`, Handsontable will accept values that were marked as invalid by the cell `validator`. - * It will result with *invalid* cells being treated as *valid* (will save the *invalid* value into the Handsontable data source). - * If set to `false`, Handsontable will *not* accept the invalid values and won't allow the user to close the editor. - * This option will be particularly useful when used with the Autocomplete's `strict` mode. - * - * @type {Boolean} - * @default true - * @since 0.9.5 - */ - allowInvalid: true, +var $export = __webpack_require__(3); +var createProperty = __webpack_require__(77); - /** - * If set to `true`, Handsontable will accept values that are empty (`null`, `undefined` or `''`). - * If set to `false`, Handsontable will *not* accept the empty values and mark cell as invalid. - * - * @example - * ```js - * ... - * allowEmpty: true // allow empty values for all cells (whole table) - * ... - * // or - * ... - * columns: [ - * // allow empty values only for 'date' column - * {data: 'date', dateFormat: 'DD/MM/YYYY', allowEmpty: true} - * ] - * ... - * ``` - * - * @type {Boolean} - * @default true - * @since 0.23.0 - */ - allowEmpty: true, +// WebKit Array.of isn't generic +$export($export.S + $export.F * __webpack_require__(23)(function () { + function F() { /* empty */ } + return !(Array.of.call(F) instanceof F); +}), 'Array', { + // 22.1.2.3 Array.of( ...items) + of: function of(/* ...args */) { + var index = 0; + var aLen = arguments.length; + var result = new (typeof this == 'function' ? this : Array)(aLen); + while (aLen > index) createProperty(result, index, arguments[index++]); + result.length = aLen; + return result; + } +}); - /** - * CSS class name for cells that did not pass validation. - * - * @type {String} - * @default 'htInvalid' - */ - invalidCellClassName: 'htInvalid', - /** - * When set to an non-empty string, displayed as the cell content for empty cells. If a value of a different type is provided, - * it will be stringified and applied as a string. - * - * @type {Mixed} - * @default false - */ - placeholder: false, +/***/ }), +/* 133 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * CSS class name for cells that have a placeholder in use. - * - * @type {String} - * @default 'htPlaceholder' - */ - placeholderCellClassName: 'htPlaceholder', +// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length) +var $export = __webpack_require__(3); - /** - * CSS class name for read-only cells. - * - * @type {String} - * @default 'htDimmed' - */ - readOnlyCellClassName: 'htDimmed', +$export($export.P, 'Array', { copyWithin: __webpack_require__(198) }); - /** - * @description - * If a string is provided, it may be one of the following predefined values: - * * `autocomplete`, - * * `checkbox`, - * * `html`, - * * `numeric`, - * * `password`. - * * `text`. - * - * Or you can [register](http://docs.handsontable.com/demo-custom-renderers.html) the custom renderer under specified name and use - * its name as an alias in your configuration. - * - * If a function is provided, it will receive the following arguments: - * ```js - * function(instance, TD, row, col, prop, value, cellProperties) {} - * ``` - * - * You can read more about custom renderes [in the documentation](http://docs.handsontable.com/demo-custom-renderers.html). - * - * @example - * ```js - * ... - * Handsontable.renderers.registerRenderer('my.renderer', function(instance, TD, row, col, prop, value, cellProperties) { - * TD.innerHTML = value; - * }); - * ... - * columns: [ - * { - * editor: 'select', - * renderer: 'autocomplete' // as string - * }, - * { - * renderer: 'my.renderer' // custom renderer as an alias - * }, - * { - * // renderer as custom function - * renderer: function(hotInstance, TD, row, col, prop, value, cellProperties) { - * TD.style.color = 'blue'; - * TD.innerHTML = value; - * } - * } - * ] - * ... - * ``` - * - * @type {String|Function} - * @default undefined - */ - renderer: void 0, +__webpack_require__(40)('copyWithin'); - /** - * CSS class name added to the commented cells. - * - * @type {String} - * @default 'htCommentCell' - */ - commentedCellClassName: 'htCommentCell', - /** - * If set to `true`, it enables the browser's native selection of a fragment of the text within a single cell, between adjacent cells or in a whole table. - * If set to `'cell'`, it enables the possibility of selecting a fragment of the text within a single cell's body. - * - * @type {Boolean|String} - * @default false - */ - fragmentSelection: false, +/***/ }), +/* 134 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Make cell [read only](http://docs.handsontable.com/demo-read-only.html). - * - * @type {Boolean} - * @default false - */ - readOnly: false, +"use strict"; - /** - * @description - * When added to a `column` property, it skips the column on paste and pastes the data on the next column to the right. - * - * @type {Boolean} - * @default false - */ - skipColumnOnPaste: false, +// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined) +var $export = __webpack_require__(3); +var $find = __webpack_require__(59)(5); +var KEY = 'find'; +var forced = true; +// Shouldn't skip holes +if (KEY in []) Array(1)[KEY](function () { forced = false; }); +$export($export.P + $export.F * forced, 'Array', { + find: function find(callbackfn /* , that = undefined */) { + return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); +__webpack_require__(40)(KEY); - /** - * @description - * Setting to true enables the search plugin (see [demo](http://docs.handsontable.com/demo-search-for-values.html)). - * - * @type {Boolean} - * @default false - */ - search: false, - /** - * @description - * Shortcut to define the combination of the cell renderer, editor and validator for the column, cell or whole table. - * - * Possible values: - * * [autocomplete](http://docs.handsontable.com/demo-autocomplete.html) - * * [checkbox](http://docs.handsontable.com/demo-checkbox.html) - * * [date](http://docs.handsontable.com/demo-date.html) - * * [dropdown](http://docs.handsontable.com/demo-dropdown.html) - * * [handsontable](http://docs.handsontable.com/demo-handsontable.html) - * * [numeric](http://docs.handsontable.com/demo-numeric.html) - * * [password](http://docs.handsontable.com/demo-password.html) - * * text - * * [time](http://docs.handsontable.com/demo-time.html) - * - * Or you can register the custom cell type under specified name and use - * its name as an alias in your configuration. - * - * @example - * ```js - * ... - * Handsontable.cellTypes.registerCellType('my.type', { - * editor: MyEditorClass, - * renderer: function(hot, td, row, col, prop, value, cellProperties) { - * td.innerHTML = value; - * }, - * validator: function(value, callback) { - * callback(value === 'foo' ? true : false); - * } - * }); - * ... - * columns: [ - * { - * type: 'text' - * }, - * { - * type: 'my.type' // an alias to custom type - * }, - * { - * type: 'checkbox' - * } - * ] - * ... - * ``` - * - * @type {String} - * @default 'text' - */ - type: 'text', +/***/ }), +/* 135 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Make cell copyable (pressing CTRL + C on your keyboard moves its value to system clipboard). - * - * __Note:__ this setting is `false` by default for cells with type `password`. - * - * @type {Boolean} - * @default true - * @since 0.10.2 - */ - copyable: true, +"use strict"; - /** - * Defines the editor for the table/column/cell. - * - * If a string is provided, it may be one of the following predefined values: - * * [autocomplete](http://docs.handsontable.com/demo-autocomplete.html) - * * [checkbox](http://docs.handsontable.com/demo-checkbox.html) - * * [date](http://docs.handsontable.com/demo-date.html) - * * [dropdown](http://docs.handsontable.com/demo-dropdown.html) - * * [handsontable](http://docs.handsontable.com/demo-handsontable.html) - * * [mobile](http://docs.handsontable.com/demo-mobiles-and-tablets.html) - * * [password](http://docs.handsontable.com/demo-password.html) - * * [select](http://docs.handsontable.com/demo-select.html) - * * text - * - * Or you can [register](http://docs.handsontable.com/tutorial-cell-editor.html#registering-an-editor) the custom editor under specified name and use - * its name as an alias in your configuration. - * - * To disable cell editing completely set `editor` property to `false`. - * - * @example - * ```js - * ... - * columns: [ - * { - * editor: 'select' - * }, - * { - * editor: false - * } - * ] - * ... - * ``` - * - * @type {String|Function|Boolean} - * @default 'text' - */ - editor: void 0, +// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined) +var $export = __webpack_require__(3); +var $find = __webpack_require__(59)(6); +var KEY = 'findIndex'; +var forced = true; +// Shouldn't skip holes +if (KEY in []) Array(1)[KEY](function () { forced = false; }); +$export($export.P + $export.F * forced, 'Array', { + findIndex: function findIndex(callbackfn /* , that = undefined */) { + return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); +__webpack_require__(40)(KEY); - /** - * @description - * Autocomplete definitions. See [autocomplete demo](http://docs.handsontable.com/demo-autocomplete.html) for examples and definitions. - * - * @type {Array} - * @default undefined - */ - autoComplete: void 0, - /** - * Control number of choices for the autocomplete (or dropdown) typed cells. After exceeding it, a scrollbar for the dropdown list of choices will appear. - * - * @since 0.18.0 - * @type {Number} - * @default 10 - */ - visibleRows: 10, +/***/ }), +/* 136 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Makes autocomplete or dropdown width the same as the edited cell width. If `false` then editor will be scaled - * according to its content. - * - * @since 0.17.0 - * @type {Boolean} - * @default true - */ - trimDropdown: true, +// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length) +var $export = __webpack_require__(3); - /** - * Setting to true enables the debug mode, currently used to test the correctness of the row and column - * header fixed positioning on a layer above the master table. - * - * @type {Boolean} - * @default false - */ - debug: false, +$export($export.P, 'Array', { fill: __webpack_require__(199) }); - /** - * When set to `true`, the text of the cell content is wrapped if it does not fit in the fixed column width. - * - * @type {Boolean} - * @default true - * @since 0.11.0 - */ - wordWrap: true, +__webpack_require__(40)('fill'); - /** - * CSS class name added to cells with cell meta `wordWrap: false`. - * - * @type {String} - * @default 'htNoWrap' - * @since 0.11.0 - */ - noWordWrapClassName: 'htNoWrap', - /** - * @description - * Defines if the right-click context menu should be enabled. Context menu allows to create new row or - * column at any place in the grid among [other features](http://docs.handsontable.com/demo-context-menu.html). - * Possible values: - * * `true` (to enable default options), - * * `false` (to disable completely) - * * an array of [predefined options](https://docs.handsontable.com/demo-context-menu.html#page-specific), - * * an object [with defined structure](http://docs.handsontable.com/demo-context-menu.html#page-custom) - * - * See [the context menu demo](http://docs.handsontable.com/demo-context-menu.html) for examples. - * - * @example - * ```js - * ... - * // as a boolean - * contextMenu: true - * ... - * // as an array - * contextMenu: ['row_above', 'row_below', '--------', 'undo', 'redo'] - * ... - * ``` - * ... - * // as an object (`name` attribute is required in the custom keys) - * contextMenu: { - * items: { - * "option1": { - * name: "option1" - * }, - * "option2": { - * name: "option2", - * submenu: { - * items: [ - * { - * key: "option2:suboption1", - * name: "option2:suboption1", - * callback: function(key, options) { - * ... - * } - * }, - * ... - * ] - * } - * } - * } - * } - * ... - * ``` - * @type {Boolean|Array|Object} - * @default undefined - */ - contextMenu: void 0, +/***/ }), +/* 137 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Disable or enable the copy/paste functionality. - * - * @example - * ```js - * ... - * copyPaste: false, - * ... - * ``` - * - * @type {Boolean} - * @default true - */ - copyPaste: true, +// 20.1.2.2 Number.isFinite(number) +var $export = __webpack_require__(3); +var _isFinite = __webpack_require__(11).isFinite; - /** - * If `true`, undo/redo functionality is enabled. - * - * @type {Boolean} - * @default undefined - */ - undo: void 0, +$export($export.S, 'Number', { + isFinite: function isFinite(it) { + return typeof it == 'number' && _isFinite(it); + } +}); - /** - * @description - * Turns on [Column sorting](http://docs.handsontable.com/demo-sorting-data.html). - * Can be either a boolean (true/false) or an object with a declared sorting options. See the below example: - * - * @example - * ```js - * ... - * // as boolean - * columnSorting: true - * ... - * // as a object with initial order (sort ascending column at index 2) - * columnSorting: { - * column: 2, - * sortOrder: true, // true = ascending, false = descending, undefined = original order - * sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table - * } - * ... - * ``` - * - * @type {Boolean|Object} - * @default undefined - */ - columnSorting: void 0, - /** - * @description - * Turns on [Manual column move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial - * column order, if set to an array of column indexes. - * - * @example - * ```js - * ... - * // as boolean - * manualColumnMove: true - * ... - * // as a array with initial order (move column index at 0 to 1 and move column index at 1 to 4) - * manualColumnMove: [1, 4] - * ... - * ``` - * - * @type {Boolean|Array} - * @default undefined - */ - manualColumnMove: void 0, +/***/ }), +/* 138 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Turns on [Manual column resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial - * column resized widths, if set to an array of numbers. - * - * @example - * ```js - * ... - * // as boolean - * manualColumnResize: true - * ... - * // as a array with initial widths (column at 0 index has 40px and column at 1 index has 50px) - * manualColumnResize: [40, 50] - * ... - * ``` - * - * @type {Boolean|Array} - * @default undefined - */ - manualColumnResize: void 0, +// 20.1.2.3 Number.isInteger(number) +var $export = __webpack_require__(3); - /** - * @description - * Turns on [Manual row move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial - * row order, if set to an array of row indexes. - * - * @example - * ```js - * ... - * // as boolean - * manualRowMove: true - * ... - * // as a array with initial order (move row index at 0 to 1 and move row index at 1 to 4) - * manualRowMove: [1, 4] - * ... - * ``` - * - * @type {Boolean|Array} - * @default undefined - * @since 0.11.0 - */ - manualRowMove: void 0, +$export($export.S, 'Number', { isInteger: __webpack_require__(139) }); - /** - * @description - * Turns on [Manual row resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial - * row resized heights, if set to an array of numbers. - * - * @example - * ```js - * ... - * // as boolean - * manualRowResize: true - * ... - * // as a array with initial heights (row at 0 index has 40px and row at 1 index has 50px) - * manualRowResize: [40, 50] - * ... - * ``` - * - * @type {Boolean|Array} - * @default undefined - * @since 0.11.0 - */ - manualRowResize: void 0, - /** - * @description - * If set to `true`, it enables a possibility to merge cells. If set to an array of objects, it merges the cells provided in the objects (see the example below). - * [More information on the demo page.](http://docs.handsontable.com/demo-merge-cells.html) - * - * @example - * ```js - * // enables the mergeCells plugin: - * margeCells: true - * ... - * // declares a list of merged sections: - * mergeCells: [ - * {row: 1, col: 1, rowspan: 3, colspan: 3}, // rowspan and colspan properties declare the width and height of a merged section in cells - * {row: 3, col: 4, rowspan: 2, colspan: 2}, - * {row: 5, col: 6, rowspan: 3, colspan: 3} - * ] - * ``` - * @type {Boolean|Array} - * @default false - */ - mergeCells: false, +/***/ }), +/* 139 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Number of rows to be rendered outside of the visible part of the table. - * By default, it's set to `'auto'`, which makes Handsontable to attempt to calculate the best offset performance-wise. - * - * You may test out different values to find the best one that works for your specific implementation. - * - * @type {Number|String} - * @default 'auto' - */ - viewportRowRenderingOffset: 'auto', +// 20.1.2.3 Number.isInteger(number) +var isObject = __webpack_require__(14); +var floor = Math.floor; +module.exports = function isInteger(it) { + return !isObject(it) && isFinite(it) && floor(it) === it; +}; - /** - * Number of columns to be rendered outside of the visible part of the table. - * By default, it's set to `'auto'`, which makes Handsontable try calculating the best offset performance-wise. - * - * You may experiment with the value to find the one that works best for your specific implementation. - * - * @type {Number|String} - * @default 'auto' - */ - viewportColumnRenderingOffset: 'auto', - /** - * A function, regular expression or a string, which will be used in the process of cell validation. - * If a function is used, be sure to execute the callback argument with either `true` (`callback(true)`) if the validation passed - * or with `false` (`callback(false)`), if the validation failed. - * Note, that `this` in the function points to the `cellProperties` object. - * - * If a string is provided, it may be one of the following predefined values: - * * `autocomplete`, - * * `date`, - * * `numeric`, - * * `time`. - * - * Or you can [register](http://docs.handsontable.com/demo-data-validation.html) the validator function under specified name and use - * its name as an alias in your configuration. - * - * See more [in the demo](http://docs.handsontable.com/demo-data-validation.html). - * - * @example - * ```js - * // as a function - * columns: [ - * { - * validator: function(value, callback) { // validation rules } - * } - * ] - * ... - * // as a regexp - * columns: [ - * { - * validator: /^[0-9]$/ // regular expression - * } - * ] - * // as a string - * columns: [ - * { - * validator: 'numeric' - * } - * ] - * ``` - * @type {Function|RegExp|String} - * @default undefined - * @since 0.9.5 - */ - validator: void 0, +/***/ }), +/* 140 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Disable visual cells selection. - * - * Possible values: - * * `true` - Disables any type of visual selection (current and area selection), - * * `false` - Enables any type of visual selection. This is default value. - * * `current` - Disables the selection of a currently selected cell, the area selection is still present. - * * `area` - Disables the area selection, the currently selected cell selection is still present. - * - * @type {Boolean|String|Array} - * @default false - * @since 0.13.2 - * @example - * ```js - * ... - * // as boolean - * disableVisualSelection: true, - * ... - * - * ... - * // as string ('current' or 'area') - * disableVisualSelection: 'current', - * ... - * - * ... - * // as array - * disableVisualSelection: ['current', 'area'], - * ... - * ``` - */ - disableVisualSelection: false, +// 20.1.2.5 Number.isSafeInteger(number) +var $export = __webpack_require__(3); +var isInteger = __webpack_require__(139); +var abs = Math.abs; - /** - * @description - * Set whether to display the current sorting order indicator (a triangle icon in the column header, specifying the sorting order). - * - * @type {Boolean} - * @default false - * @since 0.15.0-beta3 - */ - sortIndicator: void 0, +$export($export.S, 'Number', { + isSafeInteger: function isSafeInteger(number) { + return isInteger(number) && abs(number) <= 0x1fffffffffffff; + } +}); - /** - * Disable or enable ManualColumnFreeze plugin. - * - * @type {Boolean} - * @default false - */ - manualColumnFreeze: void 0, - /** - * @description - * Defines whether Handsontable should trim the whitespace at the beginning and the end of the cell contents. - * - * @type {Boolean} - * @default true - */ - trimWhitespace: true, +/***/ }), +/* 141 */ +/***/ (function(module, exports, __webpack_require__) { - settings: void 0, +// 20.1.2.4 Number.isNaN(number) +var $export = __webpack_require__(3); - /** - * @description - * Defines data source for Autocomplete or Dropdown cell types. - * - * @example - * ```js - * ... - * // source as a array - * columns: [{ - * type: 'autocomplete', - * source: ['A', 'B', 'C', 'D'] - * }] - * ... - * // source as a function - * columns: [{ - * type: 'autocomplete', - * source: function(query, callback) { - * fetch('http://example.com/query?q=' + query, function(response) { - * callback(response.items); - * }) - * } - * }] - * ... - * ``` - * - * @type {Array|Function} - * @default undefined - */ - source: void 0, +$export($export.S, 'Number', { + isNaN: function isNaN(number) { + // eslint-disable-next-line no-self-compare + return number != number; + } +}); - /** - * @description - * Defines the column header name. - * - * @example - * ```js - * ... - * columns: [{ - * title: 'First name', - * type: 'text', - * }, - * { - * title: 'Last name', - * type: 'text', - * }] - * ... - * ``` - * - * @type {String} - * @default undefined - */ - title: void 0, - /** - * Data template for `'checkbox'` type when checkbox is checked. - * - * @example - * ```js - * checkedTemplate: 'good' - * - * // if a checkbox-typed cell is checked, then getDataAtCell(x,y), where x and y are the coordinates of the cell - * // will return 'good'. - * ``` - * @type {Boolean|String} - * @default true - */ - checkedTemplate: void 0, +/***/ }), +/* 142 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Data template for `'checkbox'` type when checkbox is unchecked. - * - * @example - * ```js - * uncheckedTemplate: 'bad' - * - * // if a checkbox-typed cell is not checked, then getDataAtCell(x,y), where x and y are the coordinates of the cell - * // will return 'bad'. - * ``` - * @type {Boolean|String} - * @default false - */ - uncheckedTemplate: void 0, +// 20.1.2.1 Number.EPSILON +var $export = __webpack_require__(3); - /** - * @description - * Object which describes if renderer should create checkbox element with label element as a parent. Option desired for - * [checkbox](http://docs.handsontable.com/demo-checkbox.html)-typed cells. - * - * By default the [checkbox](http://docs.handsontable.com/demo-checkbox.html) renderer renders the checkbox without a label. - * - * Possible object properties: - * * `property` - Defines the property name of the data object, which will to be used as a label. - * (eg. `label: {property: 'name.last'}`). This option works only if data was passed as an array of objects. - * * `position` - String which describes where to place the label text (before or after checkbox element). - * Valid values are `'before'` and '`after`' (defaults to `'after'`). - * * `value` - String or a Function which will be used as label text. - * - * @example - * ```js - * ... - * columns: [{ - * type: 'checkbox', - * label: {position: 'after', value: 'My label: '} - * }] - * ... - * ``` - * - * @since 0.19.0 - * @type {Object} - * @default undefined - */ - label: void 0, +$export($export.S, 'Number', { EPSILON: Math.pow(2, -52) }); - /** - * Display format. See [numbrojs](http://numbrojs.com). This option is desired for - * [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells. - * - * Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting. - * - * @example - * ```js - * ... - * columns: [{ - * type: 'numeric', - * format: '0,00' - * }] - * ... - * ``` - * - * @type {String} - * @default '0' - */ - format: void 0, - /** - * Language display format. See [numbrojs](http://numbrojs.com/languages.html#supported-languages). This option is desired for - * [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells. - * - * Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting. - * - * @example - * ```js - * ... - * columns: [{ - * type: 'numeric', - * language: 'en-US' - * }] - * ... - * ``` - * - * @type {String} - * @default 'en-US' - */ - language: void 0, +/***/ }), +/* 143 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @description - * Data source for [select](http://docs.handsontable.com/demo-select.html)-typed cells. - * - * @example - * ```js - * ... - * columns: [{ - * editor: 'select', - * selectOptions: ['A', 'B', 'C'], - * }] - * ... - * ``` - * - * @type {Array} - */ - selectOptions: void 0, +// 20.1.2.10 Number.MIN_SAFE_INTEGER +var $export = __webpack_require__(3); - /** - * Enables or disables the autoColumnSize plugin. Default value is `undefined`, which has the same effect as `true`. - * Disabling this plugin can increase performance, as no size-related calculations would be done. - * - * Column width calculations are divided into sync and async part. Each of this parts has their own advantages and - * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't - * block the browser UI. - * - * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value. - * `syncLimit` option is available since 0.16.0. - * - * You can also use the `useHeaders` option to take the column headers with into calculation. - * - * @example - * ```js - * ... - * // as a number (300 columns in sync, rest async) - * autoColumnSize: {syncLimit: 300}, - * ... - * - * ... - * // as a string (percent) - * autoColumnSize: {syncLimit: '40%'}, - * ... - * - * ... - * // use headers width while calculation the column width - * autoColumnSize: {useHeaders: true}, - * ... - * - * ``` - * - * @type {Object|Boolean} - * @default {syncLimit: 50} - */ - autoColumnSize: void 0, +$export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff }); - /** - * Enables or disables autoRowSize plugin. Default value is `undefined`, which has the same effect as `false` (disabled). - * Enabling this plugin can decrease performance, as size-related calculations would be performed. - * - * Row height calculations are divided into sync and async stages. Each of these stages has their own advantages and - * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't - * block the browser UI. - * - * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value. - * `syncLimit` options is available since 0.16.0. - * - * @example - * ```js - * ... - * // as number (300 columns in sync, rest async) - * autoRowSize: {syncLimit: 300}, - * ... - * - * ... - * // as string (percent) - * autoRowSize: {syncLimit: '40%'}, - * ... - * ``` - * @type {Object|Boolean} - * @default {syncLimit: 1000} - */ - autoRowSize: void 0, - /** - * Date validation format. - * - * Option desired for `'date'` - typed cells. - * - * @example - * ```js - * ... - * columns: [{ - * type: 'date', - * dateFormat: 'MM/DD/YYYY' - * }] - * ... - * ``` - * - * @type {String} - * @default 'DD/MM/YYYY' - */ - dateFormat: void 0, +/***/ }), +/* 144 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * If `true` then dates will be automatically formatted to match the desired format. - * - * Option desired for `'date'`-typed typed cells. - * - * @example - * ```js - * ... - * columns: [{ - * type: 'date', - * dateFormat: 'YYYY-MM-DD', - * correctFormat: true - * }] - * ... - * ``` - * - * @type {Boolean} - * @default false - */ - correctFormat: false, +// 20.1.2.6 Number.MAX_SAFE_INTEGER +var $export = __webpack_require__(3); - /** - * Definition of default value which will fill the empty cells. - * - * Option desired for `'date'`-typed cells. - * - * @example - * ```js - * ... - * columns: [{ - * type: 'date', - * defaultData: '2015-02-02' - * }] - * ... - * ``` - * - * @type {String} - */ - defaultDate: void 0, +$export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff }); - /** - * If set to `true`, the value entered into the cell must match (case-sensitive) the autocomplete source. Otherwise, cell won't pass the validation. - * When filtering the autocomplete source list, the editor will be working in case-insensitive mode. - * - * Option desired for `autocomplete`-typed cells. - * - * @example - * ```js - * ... - * columns: [{ - * type: 'autocomplete', - * source: ['A', 'B', 'C'], - * strict: true - * }] - * ... - * ``` - * - * @type {Boolean} - */ - strict: void 0, - - /** - * @description - * If typed `true`, data defined in `source` of the autocomplete or dropdown cell will be treated as HTML. - * - * __Warning:__ Enabling this option can cause serious XSS vulnerabilities. - * - * Option desired for `'autocomplete'`-typed cells. - * @example - * ```js - * ... - * columns: [{ - * type: 'autocomplete', - * allowHtml: true, - * source: ['foo', 'bar'] - * }] - * ... - * ``` - * @type {Boolean} - * @default false - */ - allowHtml: false, - - /** - * If typed `true` then virtual rendering mechanism for handsontable will be disabled. - * - * @type {Boolean} - */ - renderAllRows: void 0, - - /** - * Prevents table to overlap outside the parent element. If `'horizontal'` option is chosen then table will appear horizontal - * scrollbar in case where parent's width is narrower then table's width. - * - * Possible values: - * * `false` - Disables functionality (Default option). - * * `horizontal` - Prevents horizontal overflow table. - * * `vertical` - Prevents vertical overflow table (Not implemented yet). - * - * @since 0.20.3 - * @example - * ```js - * ... - * preventOverflow: 'horizontal' - * ... - * ``` - * - * @type {String|Boolean} - */ - preventOverflow: false, - - /** - * @description - * Plugin allowing binding the table rows with their headers. - * If the plugin is enabled, the table row headers will "stick" to the rows, when they are hidden/moved. Basically, if at the initialization - * row 0 has a header titled "A", it will have it no matter what you do with the table. - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean|String} - * @example - * - * ```js - * ... - * var hot = new Handsontable(document.getElementById('example'), { - * date: getData(), - * bindRowsWithHeaders: true - * }); - * ... - * ``` - * - */ - bindRowsWithHeaders: void 0, - - /** - * @description - * The CollapsibleColumns plugin allows collapsing of columns, covered by a header with the `colspan` property defined. - * - * Clicking the "collapse/expand" button collapses (or expands) all "child" headers except the first one. - * - * Setting the `collapsibleColumns` property to `true` will display a "collapse/expand" button in every header with a defined - * `colspan` property. - * - * To limit this functionality to a smaller group of headers, define the `collapsibleColumns` property as an array of objects, as in - * the example below. - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean|Array} - * @example - * ```js - * ... - * collapsibleColumns: [ - * {row: -4, col: 1, collapsible: true}, - * {row: -3, col: 5, collapsible: true} - * ] - * ... - * // or - * ... - * collapsibleColumns: true - * ... - * ``` - */ - collapsibleColumns: void 0, - - /** - * @description - * Allows making pre-defined calculations on the cell values and display the results within Handsontable. - * See the demo for more information. - * - * @pro - * @since 1.0.0-beta1 - * @type {Object} - */ - columnSummary: void 0, - - /** - * This plugin allows adding a configurable dropdown menu to the table's column headers. - * The dropdown menu acts like the Context Menu, but is triggered by clicking the button in the header. - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean|Object|Array} - */ - dropdownMenu: void 0, - - /** - * The filters plugin. - * It allows filtering the table data either by the built-in component or with the API. - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean} - */ - filters: void 0, - - /** - * It allows Handsontable to process formula expressions defined in the provided data. - * - * @pro - * @since 1.7.0 - * @type {Boolean} - */ - formulas: void 0, - - /** - * @description - * GanttChart plugin enables a possibility to create a Gantt chart using a Handsontable instance. - * In this case, the whole table becomes read-only. - * - * @pro - * @since 1.0.0-beta1 - * @type {Object} - */ - ganttChart: void 0, - - /** - * @description - * Allows adding a tooltip to the table headers. - * - * Available options: - * * the `rows` property defines if tooltips should be added to row headers, - * * the `columns` property defines if tooltips should be added to column headers, - * * the `onlyTrimmed` property defines if tooltips should be added only to headers, which content is trimmed by the header itself (the content being wider then the header). - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean|Object} - */ - headerTooltips: void 0, - - /** - * Plugin allowing hiding of certain columns. - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean|Object} - */ - hiddenColumns: void 0, - - /** - * @description - * Plugin allowing hiding of certain rows. - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean|Object} - */ - hiddenRows: void 0, - - /** - * @description - * Allows creating a nested header structure, using the HTML's colspan attribute. - * - * @pro - * @since 1.0.0-beta1 - * @type {Array} - */ - nestedHeaders: void 0, - - /** - * @description - * Plugin allowing hiding of certain rows. - * - * @pro - * @since 1.0.0-beta1 - * @type {Boolean|Array} - */ - trimRows: void 0, - - /** - * @description - * Allows setting a custom width of the row headers. You can provide a number or an array of widths, if many row header levels are defined. - * - * @since 0.22.0 - * @type {Number|Array} - */ - rowHeaderWidth: void 0, - - /** - * @description - * Allows setting a custom height of the column headers. You can provide a number or an array of heights, if many column header levels are defined. - * - * @since 0.22.0 - * @type {Number|Array} - */ - columnHeaderHeight: void 0, - - /** - * @description - * Enabling this plugin switches table into one-way data binding where changes are applied into data source (from outside table) - * will be automatically reflected in the table. - * - * For every data change [afterChangesObserved](Hooks.html#event:afterChangesObserved) hook will be fired. - * - * @type {Boolean} - * @default false - */ - observeChanges: void 0, - - /** - * @description - * When passed to the `column` property, allows specifying a custom sorting function for the desired column. - * - * @since 0.24.0 - * @type {Function} - * @example - * ```js - * columns: [ - * { - * sortFunction: function(sortOrder) { - * return function(a, b) { - * // sorting function body. - * // - * // Function parameters: - * // sortOrder: If true, the order is ascending, if false - descending. undefined = original order - * // a, b: Two compared elements. These are 2-element arrays, with the first element being the row index, the second - cell value. - * } - * } - * } - * ] - * ``` - */ - sortFunction: void 0, - - /** - * If defined as 'true', the Autocomplete's suggestion list would be sorted by relevance (the closer to the left the match is, the higher the suggestion). - * - * Option desired for cells of the `'autocomplete'` type. - * - * @type {Boolean} - * @default true - */ - sortByRelevance: true, - - /** - * If defined as 'true', when the user types into the input area the Autocomplete's suggestion list is updated to only - * include those choices starting with what has been typed; if defined as 'false' all suggestions remain shown, with - * those matching what has been typed marked in bold. - * - * @type {Boolean} - * @default true - */ - filter: true, - - /** - * If defined as 'true', filtering in the Autocomplete Editor will be case-sensitive. - * - * @type {Boolean} - * @default: false - */ - filteringCaseSensitive: false -}; - -exports.default = DefaultSettings; /***/ }), -/* 89 */ +/* 145 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +// https://github.com/tc39/Array.prototype.includes +var $export = __webpack_require__(3); +var $includes = __webpack_require__(93)(true); -exports.__esModule = true; -exports.getNormalizedDate = getNormalizedDate; -/* eslint-disable import/prefer-default-export */ - -/** - * Get normalized Date object for the ISO formatted date strings. - * Natively, the date object parsed from a ISO 8601 string will be offsetted by the timezone difference, which may result in returning a wrong date. - * See: Github issue #3338. - * - * @param {String} dateString String representing the date. - * @returns {Date} The proper Date object. - */ -function getNormalizedDate(dateString) { - var nativeDate = new Date(dateString); - - // NaN if dateString is not in ISO format - if (!isNaN(new Date(dateString + "T00:00").getDate())) { - - // Compensate timezone offset - return new Date(nativeDate.getTime() + nativeDate.getTimezoneOffset() * 60000); +$export($export.P, 'Array', { + includes: function includes(el /* , fromIndex = 0 */) { + return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined); } +}); - return nativeDate; -} - -/***/ }), -/* 90 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.registerAsRootInstance = registerAsRootInstance; -exports.hasValidParameter = hasValidParameter; -exports.isRootInstance = isRootInstance; -var holder = exports.holder = new WeakMap(); - -var rootInstanceSymbol = exports.rootInstanceSymbol = Symbol('rootInstance'); - -/** - * Register an object as a root instance. - * - * @param {Object} object An object to associate with root instance flag. - */ -function registerAsRootInstance(object) { - holder.set(object, true); -} - -/** - * Check if the source of the root indication call is valid. - * - * @param {Symbol} rootSymbol A symbol as a source of truth. - * @return {Boolean} - */ -function hasValidParameter(rootSymbol) { - return rootSymbol === rootInstanceSymbol; -} +__webpack_require__(40)('includes'); -/** - * Check if passed an object was flagged as a root instance. - * - * @param {Object} object An object to check. - * @return {Boolean} - */ -function isRootInstance(object) { - return holder.has(object); -} /***/ }), -/* 91 */ +/* 146 */ /***/ (function(module, exports, __webpack_require__) { -// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length) +// https://github.com/tc39/proposal-object-values-entries var $export = __webpack_require__(3); +var $values = __webpack_require__(147)(false); -$export($export.P, 'Array', {copyWithin: __webpack_require__(279)}); +$export($export.S, 'Object', { + values: function values(it) { + return $values(it); + } +}); -__webpack_require__(37)('copyWithin'); /***/ }), -/* 92 */ +/* 147 */ /***/ (function(module, exports, __webpack_require__) { -// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length) -var $export = __webpack_require__(3); - -$export($export.P, 'Array', {fill: __webpack_require__(280)}); +var getKeys = __webpack_require__(36); +var toIObject = __webpack_require__(25); +var isEnum = __webpack_require__(48).f; +module.exports = function (isEntries) { + return function (it) { + var O = toIObject(it); + var keys = getKeys(O); + var length = keys.length; + var i = 0; + var result = []; + var key; + while (length > i) if (isEnum.call(O, key = keys[i++])) { + result.push(isEntries ? [key, O[key]] : O[key]); + } return result; + }; +}; -__webpack_require__(37)('fill'); /***/ }), -/* 93 */ +/* 148 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// https://github.com/tc39/proposal-object-values-entries +var $export = __webpack_require__(3); +var $entries = __webpack_require__(147)(true); -// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined) -var $export = __webpack_require__(3) - , $find = __webpack_require__(52)(6) - , KEY = 'findIndex' - , forced = true; -// Shouldn't skip holes -if(KEY in [])Array(1)[KEY](function(){ forced = false; }); -$export($export.P + $export.F * forced, 'Array', { - findIndex: function findIndex(callbackfn/*, that = undefined */){ - return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); +$export($export.S, 'Object', { + entries: function entries(it) { + return $entries(it); } }); -__webpack_require__(37)(KEY); - -/***/ }), -/* 94 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; - -// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined) -var $export = __webpack_require__(3) - , $find = __webpack_require__(52)(5) - , KEY = 'find' - , forced = true; -// Shouldn't skip holes -if(KEY in [])Array(1)[KEY](function(){ forced = false; }); -$export($export.P + $export.F * forced, 'Array', { - find: function find(callbackfn/*, that = undefined */){ - return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); - } -}); -__webpack_require__(37)(KEY); /***/ }), -/* 95 */ +/* 149 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -var ctx = __webpack_require__(29) - , $export = __webpack_require__(3) - , toObject = __webpack_require__(41) - , call = __webpack_require__(166) - , isArrayIter = __webpack_require__(162) - , toLength = __webpack_require__(24) - , createProperty = __webpack_require__(73) - , getIterFn = __webpack_require__(177); +// https://github.com/tc39/proposal-object-getownpropertydescriptors +var $export = __webpack_require__(3); +var ownKeys = __webpack_require__(200); +var toIObject = __webpack_require__(25); +var gOPD = __webpack_require__(72); +var createProperty = __webpack_require__(77); -$export($export.S + $export.F * !__webpack_require__(78)(function(iter){ Array.from(iter); }), 'Array', { - // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) - from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){ - var O = toObject(arrayLike) - , C = typeof this == 'function' ? this : Array - , aLen = arguments.length - , mapfn = aLen > 1 ? arguments[1] : undefined - , mapping = mapfn !== undefined - , index = 0 - , iterFn = getIterFn(O) - , length, result, step, iterator; - if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); - // if object isn't iterable or it's array with default iterator - use simple case - if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){ - for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){ - createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value); - } - } else { - length = toLength(O.length); - for(result = new C(length); length > index; index++){ - createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); - } +$export($export.S, 'Object', { + getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) { + var O = toIObject(object); + var getDesc = gOPD.f; + var keys = ownKeys(O); + var result = {}; + var i = 0; + var key, desc; + while (keys.length > i) { + desc = getDesc(O, key = keys[i++]); + if (desc !== undefined) createProperty(result, key, desc); } - result.length = index; return result; } }); /***/ }), -/* 96 */ +/* 150 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var $export = __webpack_require__(3) - , createProperty = __webpack_require__(73); +// https://github.com/tc39/proposal-string-pad-start-end +var $export = __webpack_require__(3); +var $pad = __webpack_require__(151); -// WebKit Array.of isn't generic -$export($export.S + $export.F * __webpack_require__(31)(function(){ - function F(){} - return !(Array.of.call(F) instanceof F); -}), 'Array', { - // 22.1.2.3 Array.of( ...items) - of: function of(/* ...args */){ - var index = 0 - , aLen = arguments.length - , result = new (typeof this == 'function' ? this : Array)(aLen); - while(aLen > index)createProperty(result, index, arguments[index++]); - result.length = aLen; - return result; +$export($export.P, 'String', { + padStart: function padStart(maxLength /* , fillString = ' ' */) { + return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true); } }); + /***/ }), -/* 97 */ +/* 151 */ /***/ (function(module, exports, __webpack_require__) { -var dP = __webpack_require__(19).f - , createDesc = __webpack_require__(40) - , has = __webpack_require__(22) - , FProto = Function.prototype - , nameRE = /^\s*function ([^ (]*)/ - , NAME = 'name'; - -var isExtensible = Object.isExtensible || function(){ - return true; +// https://github.com/tc39/proposal-string-pad-start-end +var toLength = __webpack_require__(21); +var repeat = __webpack_require__(121); +var defined = __webpack_require__(33); + +module.exports = function (that, maxLength, fillString, left) { + var S = String(defined(that)); + var stringLength = S.length; + var fillStr = fillString === undefined ? ' ' : String(fillString); + var intMaxLength = toLength(maxLength); + if (intMaxLength <= stringLength || fillStr == '') return S; + var fillLen = intMaxLength - stringLength; + var stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length)); + if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen); + return left ? stringFiller + S : S + stringFiller; }; -// 19.2.4.2 name -NAME in FProto || __webpack_require__(21) && dP(FProto, NAME, { - configurable: true, - get: function(){ - try { - var that = this - , name = ('' + that).match(nameRE)[1]; - has(that, NAME) || !isExtensible(that) || dP(that, NAME, createDesc(5, name)); - return name; - } catch(e){ - return ''; - } - } -}); /***/ }), -/* 98 */ +/* 152 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var strong = __webpack_require__(158); +// https://github.com/tc39/proposal-string-pad-start-end +var $export = __webpack_require__(3); +var $pad = __webpack_require__(151); -// 23.1 Map Objects -module.exports = __webpack_require__(53)('Map', function(get){ - return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); }; -}, { - // 23.1.3.6 Map.prototype.get(key) - get: function get(key){ - var entry = strong.getEntry(this, key); - return entry && entry.v; - }, - // 23.1.3.9 Map.prototype.set(key, value) - set: function set(key, value){ - return strong.def(this, key === 0 ? 0 : key, value); +$export($export.P, 'String', { + padEnd: function padEnd(maxLength /* , fillString = ' ' */) { + return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false); } -}, strong, true); +}); + /***/ }), -/* 99 */ +/* 153 */ /***/ (function(module, exports, __webpack_require__) { -// 20.1.2.1 Number.EPSILON var $export = __webpack_require__(3); +var $task = __webpack_require__(73); +$export($export.G + $export.B, { + setImmediate: $task.set, + clearImmediate: $task.clear +}); -$export($export.S, 'Number', {EPSILON: Math.pow(2, -52)}); /***/ }), -/* 100 */ +/* 154 */ /***/ (function(module, exports, __webpack_require__) { -// 20.1.2.2 Number.isFinite(number) -var $export = __webpack_require__(3) - , _isFinite = __webpack_require__(13).isFinite; +var $iterators = __webpack_require__(78); +var getKeys = __webpack_require__(36); +var redefine = __webpack_require__(28); +var global = __webpack_require__(11); +var hide = __webpack_require__(29); +var Iterators = __webpack_require__(45); +var wks = __webpack_require__(10); +var ITERATOR = wks('iterator'); +var TO_STRING_TAG = wks('toStringTag'); +var ArrayValues = Iterators.Array; + +var DOMIterables = { + CSSRuleList: true, // TODO: Not spec compliant, should be false. + CSSStyleDeclaration: false, + CSSValueList: false, + ClientRectList: false, + DOMRectList: false, + DOMStringList: false, + DOMTokenList: true, + DataTransferItemList: false, + FileList: false, + HTMLAllCollection: false, + HTMLCollection: false, + HTMLFormElement: false, + HTMLSelectElement: false, + MediaList: true, // TODO: Not spec compliant, should be false. + MimeTypeArray: false, + NamedNodeMap: false, + NodeList: true, + PaintRequestList: false, + Plugin: false, + PluginArray: false, + SVGLengthList: false, + SVGNumberList: false, + SVGPathSegList: false, + SVGPointList: false, + SVGStringList: false, + SVGTransformList: false, + SourceBufferList: false, + StyleSheetList: true, // TODO: Not spec compliant, should be false. + TextTrackCueList: false, + TextTrackList: false, + TouchList: false +}; -$export($export.S, 'Number', { - isFinite: function isFinite(it){ - return typeof it == 'number' && _isFinite(it); +for (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) { + var NAME = collections[i]; + var explicit = DOMIterables[NAME]; + var Collection = global[NAME]; + var proto = Collection && Collection.prototype; + var key; + if (proto) { + if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues); + if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME); + Iterators[NAME] = ArrayValues; + if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true); } -}); +} + /***/ }), -/* 101 */ +/* 155 */ /***/ (function(module, exports, __webpack_require__) { -// 20.1.2.3 Number.isInteger(number) -var $export = __webpack_require__(3); +"use strict"; -$export($export.S, 'Number', {isInteger: __webpack_require__(164)}); -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { +exports.__esModule = true; -// 20.1.2.4 Number.isNaN(number) -var $export = __webpack_require__(3); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -$export($export.S, 'Number', { - isNaN: function isNaN(number){ - return number != number; - } -}); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -/***/ }), -/* 103 */ -/***/ (function(module, exports, __webpack_require__) { +var privatePool = new WeakMap(); -// 20.1.2.5 Number.isSafeInteger(number) -var $export = __webpack_require__(3) - , isInteger = __webpack_require__(164) - , abs = Math.abs; +/** + * Calculates indexes of columns to render OR columns that are visible. + * To redo the calculation, you need to create a new calculator. + * + * @class ViewportColumnsCalculator + */ -$export($export.S, 'Number', { - isSafeInteger: function isSafeInteger(number){ - return isInteger(number) && abs(number) <= 0x1fffffffffffff; - } -}); +var ViewportColumnsCalculator = function () { + _createClass(ViewportColumnsCalculator, null, [{ + key: 'DEFAULT_WIDTH', -/***/ }), -/* 104 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Default column width + * + * @type {Number} + */ + get: function get() { + return 50; + } -// 20.1.2.6 Number.MAX_SAFE_INTEGER -var $export = __webpack_require__(3); + /** + * @param {Number} viewportWidth Width of the viewport + * @param {Number} scrollOffset Current horizontal scroll position of the viewport + * @param {Number} totalColumns Total number of rows + * @param {Function} columnWidthFn Function that returns the width of the column at a given index (in px) + * @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin) + * @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport + * @param {Boolean} stretchH + * @param {Function} [stretchingColumnWidthFn] Function that returns the new width of the stretched column. + */ -$export($export.S, 'Number', {MAX_SAFE_INTEGER: 0x1fffffffffffff}); + }]); -/***/ }), -/* 105 */ -/***/ (function(module, exports, __webpack_require__) { + function ViewportColumnsCalculator(viewportWidth, scrollOffset, totalColumns, columnWidthFn, overrideFn, onlyFullyVisible, stretchH) { + var stretchingColumnWidthFn = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : function (width) { + return width; + }; -// 20.1.2.10 Number.MIN_SAFE_INTEGER -var $export = __webpack_require__(3); + _classCallCheck(this, ViewportColumnsCalculator); -$export($export.S, 'Number', {MIN_SAFE_INTEGER: -0x1fffffffffffff}); + privatePool.set(this, { + viewportWidth: viewportWidth, + scrollOffset: scrollOffset, + totalColumns: totalColumns, + columnWidthFn: columnWidthFn, + overrideFn: overrideFn, + onlyFullyVisible: onlyFullyVisible, + stretchingColumnWidthFn: stretchingColumnWidthFn + }); -/***/ }), -/* 106 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Number of rendered/visible columns + * + * @type {Number} + */ + this.count = 0; -// 19.1.3.1 Object.assign(target, source) -var $export = __webpack_require__(3); + /** + * Index of the first rendered/visible column (can be overwritten using overrideFn) + * + * @type {Number|null} + */ + this.startColumn = null; -$export($export.S + $export.F, 'Object', {assign: __webpack_require__(169)}); + /** + * Index of the last rendered/visible column (can be overwritten using overrideFn) + * + * @type {null} + */ + this.endColumn = null; -/***/ }), -/* 107 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Position of the first rendered/visible column (in px) + * + * @type {Number|null} + */ + this.startPosition = null; -// 19.1.3.10 Object.is(value1, value2) -var $export = __webpack_require__(3); -$export($export.S, 'Object', {is: __webpack_require__(294)}); + this.stretchAllRatio = 0; + this.stretchLastWidth = 0; + this.stretch = stretchH; + this.totalTargetWidth = 0; + this.needVerifyLastColumnWidth = true; + this.stretchAllColumnsWidth = []; -/***/ }), -/* 108 */ -/***/ (function(module, exports, __webpack_require__) { + this.calculate(); + } -// 19.1.3.19 Object.setPrototypeOf(O, proto) -var $export = __webpack_require__(3); -$export($export.S, 'Object', {setPrototypeOf: __webpack_require__(172).set}); + /** + * Calculates viewport + */ -/***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; + _createClass(ViewportColumnsCalculator, [{ + key: 'calculate', + value: function calculate() { + var sum = 0; + var needReverse = true; + var startPositions = []; + var columnWidth = void 0; -var LIBRARY = __webpack_require__(56) - , global = __webpack_require__(13) - , ctx = __webpack_require__(29) - , classof = __webpack_require__(157) - , $export = __webpack_require__(3) - , isObject = __webpack_require__(15) - , aFunction = __webpack_require__(72) - , anInstance = __webpack_require__(51) - , forOf = __webpack_require__(55) - , speciesConstructor = __webpack_require__(295) - , task = __webpack_require__(85).set - , microtask = __webpack_require__(289)() - , PROMISE = 'Promise' - , TypeError = global.TypeError - , process = global.process - , $Promise = global[PROMISE] - , process = global.process - , isNode = classof(process) == 'process' - , empty = function(){ /* empty */ } - , Internal, GenericPromiseCapability, Wrapper; - -var USE_NATIVE = !!function(){ - try { - // correct subclassing with @@species support - var promise = $Promise.resolve(1) - , FakePromise = (promise.constructor = {})[__webpack_require__(10)('species')] = function(exec){ exec(empty, empty); }; - // unhandled rejections tracking support, NodeJS Promise without it fails @@species test - return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise; - } catch(e){ /* empty */ } -}(); + var priv = privatePool.get(this); + var onlyFullyVisible = priv.onlyFullyVisible; + var overrideFn = priv.overrideFn; + var scrollOffset = priv.scrollOffset; + var totalColumns = priv.totalColumns; + var viewportWidth = priv.viewportWidth; -// helpers -var sameConstructor = function(a, b){ - // with library wrapper special case - return a === b || a === $Promise && b === Wrapper; -}; -var isThenable = function(it){ - var then; - return isObject(it) && typeof (then = it.then) == 'function' ? then : false; -}; -var newPromiseCapability = function(C){ - return sameConstructor($Promise, C) - ? new PromiseCapability(C) - : new GenericPromiseCapability(C); -}; -var PromiseCapability = GenericPromiseCapability = function(C){ - var resolve, reject; - this.promise = new C(function($$resolve, $$reject){ - if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor'); - resolve = $$resolve; - reject = $$reject; - }); - this.resolve = aFunction(resolve); - this.reject = aFunction(reject); -}; -var perform = function(exec){ - try { - exec(); - } catch(e){ - return {error: e}; - } -}; -var notify = function(promise, isReject){ - if(promise._n)return; - promise._n = true; - var chain = promise._c; - microtask(function(){ - var value = promise._v - , ok = promise._s == 1 - , i = 0; - var run = function(reaction){ - var handler = ok ? reaction.ok : reaction.fail - , resolve = reaction.resolve - , reject = reaction.reject - , domain = reaction.domain - , result, then; - try { - if(handler){ - if(!ok){ - if(promise._h == 2)onHandleUnhandled(promise); - promise._h = 1; - } - if(handler === true)result = value; - else { - if(domain)domain.enter(); - result = handler(value); - if(domain)domain.exit(); - } - if(result === reaction.promise){ - reject(TypeError('Promise-chain cycle')); - } else if(then = isThenable(result)){ - then.call(result, resolve, reject); - } else resolve(result); - } else reject(value); - } catch(e){ - reject(e); - } - }; - while(chain.length > i)run(chain[i++]); // variable length - can't use forEach - promise._c = []; - promise._n = false; - if(isReject && !promise._h)onUnhandled(promise); - }); -}; -var onUnhandled = function(promise){ - task.call(global, function(){ - var value = promise._v - , abrupt, handler, console; - if(isUnhandled(promise)){ - abrupt = perform(function(){ - if(isNode){ - process.emit('unhandledRejection', value, promise); - } else if(handler = global.onunhandledrejection){ - handler({promise: promise, reason: value}); - } else if((console = global.console) && console.error){ - console.error('Unhandled promise rejection', value); - } - }); - // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should - promise._h = isNode || isUnhandled(promise) ? 2 : 1; - } promise._a = undefined; - if(abrupt)throw abrupt.error; - }); -}; -var isUnhandled = function(promise){ - if(promise._h == 1)return false; - var chain = promise._a || promise._c - , i = 0 - , reaction; - while(chain.length > i){ - reaction = chain[i++]; - if(reaction.fail || !isUnhandled(reaction.promise))return false; - } return true; -}; -var onHandleUnhandled = function(promise){ - task.call(global, function(){ - var handler; - if(isNode){ - process.emit('rejectionHandled', promise); - } else if(handler = global.onrejectionhandled){ - handler({promise: promise, reason: promise._v}); - } - }); -}; -var $reject = function(value){ - var promise = this; - if(promise._d)return; - promise._d = true; - promise = promise._w || promise; // unwrap - promise._v = value; - promise._s = 2; - if(!promise._a)promise._a = promise._c.slice(); - notify(promise, true); -}; -var $resolve = function(value){ - var promise = this - , then; - if(promise._d)return; - promise._d = true; - promise = promise._w || promise; // unwrap - try { - if(promise === value)throw TypeError("Promise can't be resolved itself"); - if(then = isThenable(value)){ - microtask(function(){ - var wrapper = {_w: promise, _d: false}; // wrap - try { - then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); - } catch(e){ - $reject.call(wrapper, e); + for (var i = 0; i < totalColumns; i++) { + columnWidth = this._getColumnWidth(i); + + if (sum <= scrollOffset && !onlyFullyVisible) { + this.startColumn = i; } - }); - } else { - promise._v = value; - promise._s = 1; - notify(promise, false); - } - } catch(e){ - $reject.call({_w: promise, _d: false}, e); // wrap - } -}; -// constructor polyfill -if(!USE_NATIVE){ - // 25.4.3.1 Promise(executor) - $Promise = function Promise(executor){ - anInstance(this, $Promise, PROMISE, '_h'); - aFunction(executor); - Internal.call(this); - try { - executor(ctx($resolve, this, 1), ctx($reject, this, 1)); - } catch(err){ - $reject.call(this, err); - } - }; - Internal = function Promise(executor){ - this._c = []; // <- awaiting reactions - this._a = undefined; // <- checked in isUnhandled reactions - this._s = 0; // <- state - this._d = false; // <- done - this._v = undefined; // <- value - this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled - this._n = false; // <- notify - }; - Internal.prototype = __webpack_require__(58)($Promise.prototype, { - // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) - then: function then(onFulfilled, onRejected){ - var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); - reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; - reaction.fail = typeof onRejected == 'function' && onRejected; - reaction.domain = isNode ? process.domain : undefined; - this._c.push(reaction); - if(this._a)this._a.push(reaction); - if(this._s)notify(this, false); - return reaction.promise; - }, - // 25.4.5.1 Promise.prototype.catch(onRejected) - 'catch': function(onRejected){ - return this.then(undefined, onRejected); - } - }); - PromiseCapability = function(){ - var promise = new Internal; - this.promise = promise; - this.resolve = ctx($resolve, promise, 1); - this.reject = ctx($reject, promise, 1); - }; -} + // +1 pixel for row header width compensation for horizontal scroll > 0 + var compensatedViewportWidth = scrollOffset > 0 ? viewportWidth + 1 : viewportWidth; -$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise}); -__webpack_require__(48)($Promise, PROMISE); -__webpack_require__(173)(PROMISE); -Wrapper = __webpack_require__(44)[PROMISE]; + if (sum >= scrollOffset && sum + columnWidth <= scrollOffset + compensatedViewportWidth) { + if (this.startColumn == null) { + this.startColumn = i; + } + this.endColumn = i; + } + startPositions.push(sum); + sum += columnWidth; -// statics -$export($export.S + $export.F * !USE_NATIVE, PROMISE, { - // 25.4.4.5 Promise.reject(r) - reject: function reject(r){ - var capability = newPromiseCapability(this) - , $$reject = capability.reject; - $$reject(r); - return capability.promise; - } -}); -$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { - // 25.4.4.6 Promise.resolve(x) - resolve: function resolve(x){ - // instanceof instead of internal slot check because we should fix it without replacement native Promise core - if(x instanceof $Promise && sameConstructor(x.constructor, this))return x; - var capability = newPromiseCapability(this) - , $$resolve = capability.resolve; - $$resolve(x); - return capability.promise; - } -}); -$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(78)(function(iter){ - $Promise.all(iter)['catch'](empty); -})), PROMISE, { - // 25.4.4.1 Promise.all(iterable) - all: function all(iterable){ - var C = this - , capability = newPromiseCapability(C) - , resolve = capability.resolve - , reject = capability.reject; - var abrupt = perform(function(){ - var values = [] - , index = 0 - , remaining = 1; - forOf(iterable, false, function(promise){ - var $index = index++ - , alreadyCalled = false; - values.push(undefined); - remaining++; - C.resolve(promise).then(function(value){ - if(alreadyCalled)return; - alreadyCalled = true; - values[$index] = value; - --remaining || resolve(values); - }, reject); - }); - --remaining || resolve(values); - }); - if(abrupt)reject(abrupt.error); - return capability.promise; - }, - // 25.4.4.4 Promise.race(iterable) - race: function race(iterable){ - var C = this - , capability = newPromiseCapability(C) - , reject = capability.reject; - var abrupt = perform(function(){ - forOf(iterable, false, function(promise){ - C.resolve(promise).then(capability.resolve, reject); - }); - }); - if(abrupt)reject(abrupt.error); - return capability.promise; - } -}); + if (!onlyFullyVisible) { + this.endColumn = i; + } + if (sum >= scrollOffset + viewportWidth) { + needReverse = false; + break; + } + } -/***/ }), -/* 110 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.endColumn === totalColumns - 1 && needReverse) { + this.startColumn = this.endColumn; -// 21.2.5.3 get RegExp.prototype.flags() -if(__webpack_require__(21) && /./g.flags != 'g')__webpack_require__(19).f(RegExp.prototype, 'flags', { - configurable: true, - get: __webpack_require__(284) -}); + while (this.startColumn > 0) { + var viewportSum = startPositions[this.endColumn] + columnWidth - startPositions[this.startColumn - 1]; -/***/ }), -/* 111 */ -/***/ (function(module, exports, __webpack_require__) { + if (viewportSum <= viewportWidth || !onlyFullyVisible) { + this.startColumn--; + } + if (viewportSum > viewportWidth) { + break; + } + } + } -// @@match logic -__webpack_require__(54)('match', 1, function(defined, MATCH, $match){ - // 21.1.3.11 String.prototype.match(regexp) - return [function match(regexp){ - 'use strict'; - var O = defined(this) - , fn = regexp == undefined ? undefined : regexp[MATCH]; - return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O)); - }, $match]; -}); + if (this.startColumn !== null && overrideFn) { + overrideFn(this); + } + this.startPosition = startPositions[this.startColumn]; -/***/ }), -/* 112 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.startPosition == void 0) { + this.startPosition = null; + } + if (this.startColumn !== null) { + this.count = this.endColumn - this.startColumn + 1; + } + } -// @@replace logic -__webpack_require__(54)('replace', 2, function(defined, REPLACE, $replace){ - // 21.1.3.14 String.prototype.replace(searchValue, replaceValue) - return [function replace(searchValue, replaceValue){ - 'use strict'; - var O = defined(this) - , fn = searchValue == undefined ? undefined : searchValue[REPLACE]; - return fn !== undefined - ? fn.call(searchValue, O, replaceValue) - : $replace.call(String(O), searchValue, replaceValue); - }, $replace]; -}); + /** + * Recalculate columns stretching. + * + * @param {Number} totalWidth + */ -/***/ }), -/* 113 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: 'refreshStretching', + value: function refreshStretching(totalWidth) { + if (this.stretch === 'none') { + return; + } + this.totalTargetWidth = totalWidth; -// @@search logic -__webpack_require__(54)('search', 1, function(defined, SEARCH, $search){ - // 21.1.3.15 String.prototype.search(regexp) - return [function search(regexp){ - 'use strict'; - var O = defined(this) - , fn = regexp == undefined ? undefined : regexp[SEARCH]; - return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O)); - }, $search]; -}); + var priv = privatePool.get(this); + var totalColumns = priv.totalColumns; + var sumAll = 0; -/***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { + for (var i = 0; i < totalColumns; i++) { + var columnWidth = this._getColumnWidth(i); + var permanentColumnWidth = priv.stretchingColumnWidthFn(void 0, i); -// @@split logic -__webpack_require__(54)('split', 2, function(defined, SPLIT, $split){ - 'use strict'; - var isRegExp = __webpack_require__(165) - , _split = $split - , $push = [].push - , $SPLIT = 'split' - , LENGTH = 'length' - , LAST_INDEX = 'lastIndex'; - if( - 'abbc'[$SPLIT](/(b)*/)[1] == 'c' || - 'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 || - 'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 || - '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 || - '.'[$SPLIT](/()()/)[LENGTH] > 1 || - ''[$SPLIT](/.?/)[LENGTH] - ){ - var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group - // based on es5-shim implementation, need to rework it - $split = function(separator, limit){ - var string = String(this); - if(separator === undefined && limit === 0)return []; - // If `separator` is not a regex, use native split - if(!isRegExp(separator))return _split.call(string, separator, limit); - var output = []; - var flags = (separator.ignoreCase ? 'i' : '') + - (separator.multiline ? 'm' : '') + - (separator.unicode ? 'u' : '') + - (separator.sticky ? 'y' : ''); - var lastLastIndex = 0; - var splitLimit = limit === undefined ? 4294967295 : limit >>> 0; - // Make `global` and avoid `lastIndex` issues by working with a copy - var separatorCopy = new RegExp(separator.source, flags + 'g'); - var separator2, match, lastIndex, lastLength, i; - // Doesn't need flags gy, but they don't hurt - if(!NPCG)separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags); - while(match = separatorCopy.exec(string)){ - // `separatorCopy.lastIndex` is not reliable cross-browser - lastIndex = match.index + match[0][LENGTH]; - if(lastIndex > lastLastIndex){ - output.push(string.slice(lastLastIndex, match.index)); - // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG - if(!NPCG && match[LENGTH] > 1)match[0].replace(separator2, function(){ - for(i = 1; i < arguments[LENGTH] - 2; i++)if(arguments[i] === undefined)match[i] = undefined; - }); - if(match[LENGTH] > 1 && match.index < string[LENGTH])$push.apply(output, match.slice(1)); - lastLength = match[0][LENGTH]; - lastLastIndex = lastIndex; - if(output[LENGTH] >= splitLimit)break; + if (typeof permanentColumnWidth === 'number') { + totalWidth -= permanentColumnWidth; + } else { + sumAll += columnWidth; } - if(separatorCopy[LAST_INDEX] === match.index)separatorCopy[LAST_INDEX]++; // Avoid an infinite loop } - if(lastLastIndex === string[LENGTH]){ - if(lastLength || !separatorCopy.test(''))output.push(''); - } else output.push(string.slice(lastLastIndex)); - return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output; - }; - // Chakra, V8 - } else if('0'[$SPLIT](undefined, 0)[LENGTH]){ - $split = function(separator, limit){ - return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit); - }; - } - // 21.1.3.17 String.prototype.split(separator, limit) - return [function split(separator, limit){ - var O = defined(this) - , fn = separator == undefined ? undefined : separator[SPLIT]; - return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit); - }, $split]; -}); - -/***/ }), -/* 115 */ -/***/ (function(module, exports, __webpack_require__) { + var remainingSize = totalWidth - sumAll; -"use strict"; + if (this.stretch === 'all' && remainingSize > 0) { + this.stretchAllRatio = totalWidth / sumAll; + this.stretchAllColumnsWidth = []; + this.needVerifyLastColumnWidth = true; + } else if (this.stretch === 'last' && totalWidth !== Infinity) { + var _columnWidth = this._getColumnWidth(totalColumns - 1); + var lastColumnWidth = remainingSize + _columnWidth; -var strong = __webpack_require__(158); + this.stretchLastWidth = lastColumnWidth >= 0 ? lastColumnWidth : _columnWidth; + } + } -// 23.2 Set Objects -module.exports = __webpack_require__(53)('Set', function(get){ - return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); }; -}, { - // 23.2.3.1 Set.prototype.add(value) - add: function add(value){ - return strong.def(this, value = value === 0 ? 0 : value, value); - } -}, strong); + /** + * Get stretched column width based on stretchH (all or last) setting passed in handsontable instance. + * + * @param {Number} column + * @param {Number} baseWidth + * @returns {Number|null} + */ -/***/ }), -/* 116 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: 'getStretchedColumnWidth', + value: function getStretchedColumnWidth(column, baseWidth) { + var result = null; -"use strict"; + if (this.stretch === 'all' && this.stretchAllRatio !== 0) { + result = this._getStretchedAllColumnWidth(column, baseWidth); + } else if (this.stretch === 'last' && this.stretchLastWidth !== 0) { + result = this._getStretchedLastColumnWidth(column); + } -var $export = __webpack_require__(3) - , $at = __webpack_require__(296)(false); -$export($export.P, 'String', { - // 21.1.3.3 String.prototype.codePointAt(pos) - codePointAt: function codePointAt(pos){ - return $at(this, pos); - } -}); + return result; + } -/***/ }), -/* 117 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * @param {Number} column + * @param {Number} baseWidth + * @returns {Number} + * @private + */ -"use strict"; -// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition]) + }, { + key: '_getStretchedAllColumnWidth', + value: function _getStretchedAllColumnWidth(column, baseWidth) { + var sumRatioWidth = 0; + var priv = privatePool.get(this); + var totalColumns = priv.totalColumns; -var $export = __webpack_require__(3) - , toLength = __webpack_require__(24) - , context = __webpack_require__(84) - , ENDS_WITH = 'endsWith' - , $endsWith = ''[ENDS_WITH]; + if (!this.stretchAllColumnsWidth[column]) { + var stretchedWidth = Math.round(baseWidth * this.stretchAllRatio); + var newStretchedWidth = priv.stretchingColumnWidthFn(stretchedWidth, column); -$export($export.P + $export.F * __webpack_require__(76)(ENDS_WITH), 'String', { - endsWith: function endsWith(searchString /*, endPosition = @length */){ - var that = context(this, searchString, ENDS_WITH) - , endPosition = arguments.length > 1 ? arguments[1] : undefined - , len = toLength(that.length) - , end = endPosition === undefined ? len : Math.min(toLength(endPosition), len) - , search = String(searchString); - return $endsWith - ? $endsWith.call(that, search, end) - : that.slice(end - search.length, end) === search; - } -}); + if (newStretchedWidth === void 0) { + this.stretchAllColumnsWidth[column] = stretchedWidth; + } else { + this.stretchAllColumnsWidth[column] = isNaN(newStretchedWidth) ? this._getColumnWidth(column) : newStretchedWidth; + } + } -/***/ }), -/* 118 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.stretchAllColumnsWidth.length === totalColumns && this.needVerifyLastColumnWidth) { + this.needVerifyLastColumnWidth = false; -var $export = __webpack_require__(3) - , toIndex = __webpack_require__(59) - , fromCharCode = String.fromCharCode - , $fromCodePoint = String.fromCodePoint; + for (var i = 0; i < this.stretchAllColumnsWidth.length; i++) { + sumRatioWidth += this.stretchAllColumnsWidth[i]; + } + if (sumRatioWidth !== this.totalTargetWidth) { + this.stretchAllColumnsWidth[this.stretchAllColumnsWidth.length - 1] += this.totalTargetWidth - sumRatioWidth; + } + } -// length should be 1, old FF problem -$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', { - // 21.1.2.2 String.fromCodePoint(...codePoints) - fromCodePoint: function fromCodePoint(x){ // eslint-disable-line no-unused-vars - var res = [] - , aLen = arguments.length - , i = 0 - , code; - while(aLen > i){ - code = +arguments[i++]; - if(toIndex(code, 0x10ffff) !== code)throw RangeError(code + ' is not a valid code point'); - res.push(code < 0x10000 - ? fromCharCode(code) - : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00) - ); - } return res.join(''); - } -}); + return this.stretchAllColumnsWidth[column]; + } -/***/ }), -/* 119 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * @param {Number} column + * @returns {Number|null} + * @private + */ -"use strict"; -// 21.1.3.7 String.prototype.includes(searchString, position = 0) + }, { + key: '_getStretchedLastColumnWidth', + value: function _getStretchedLastColumnWidth(column) { + var priv = privatePool.get(this); + var totalColumns = priv.totalColumns; -var $export = __webpack_require__(3) - , context = __webpack_require__(84) - , INCLUDES = 'includes'; + if (column === totalColumns - 1) { + return this.stretchLastWidth; + } -$export($export.P + $export.F * __webpack_require__(76)(INCLUDES), 'String', { - includes: function includes(searchString /*, position = 0 */){ - return !!~context(this, searchString, INCLUDES) - .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined); - } -}); + return null; + } -/***/ }), -/* 120 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * @param {Number} column Column index. + * @returns {Number} + * @private + */ -var $export = __webpack_require__(3) - , toIObject = __webpack_require__(23) - , toLength = __webpack_require__(24); + }, { + key: '_getColumnWidth', + value: function _getColumnWidth(column) { + var width = privatePool.get(this).columnWidthFn(column); -$export($export.S, 'String', { - // 21.1.2.4 String.raw(callSite, ...substitutions) - raw: function raw(callSite){ - var tpl = toIObject(callSite.raw) - , len = toLength(tpl.length) - , aLen = arguments.length - , res = [] - , i = 0; - while(len > i){ - res.push(String(tpl[i++])); - if(i < aLen)res.push(String(arguments[i])); - } return res.join(''); - } -}); + if (width === void 0) { + width = ViewportColumnsCalculator.DEFAULT_WIDTH; + } -/***/ }), -/* 121 */ -/***/ (function(module, exports, __webpack_require__) { + return width; + } + }]); -var $export = __webpack_require__(3); + return ViewportColumnsCalculator; +}(); -$export($export.P, 'String', { - // 21.1.3.13 String.prototype.repeat(count) - repeat: __webpack_require__(175) -}); +exports.default = ViewportColumnsCalculator; /***/ }), -/* 122 */ +/* 156 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -// 21.1.3.18 String.prototype.startsWith(searchString [, position ]) -var $export = __webpack_require__(3) - , toLength = __webpack_require__(24) - , context = __webpack_require__(84) - , STARTS_WITH = 'startsWith' - , $startsWith = ''[STARTS_WITH]; -$export($export.P + $export.F * __webpack_require__(76)(STARTS_WITH), 'String', { - startsWith: function startsWith(searchString /*, position = 0 */){ - var that = context(this, searchString, STARTS_WITH) - , index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length)) - , search = String(searchString); - return $startsWith - ? $startsWith.call(that, search, index) - : that.slice(index, index + search.length) === search; - } -}); +exports.__esModule = true; -/***/ }), -/* 123 */ -/***/ (function(module, exports, __webpack_require__) { +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -"use strict"; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -// ECMAScript 6 symbols shim -var global = __webpack_require__(13) - , has = __webpack_require__(22) - , DESCRIPTORS = __webpack_require__(21) - , $export = __webpack_require__(3) - , redefine = __webpack_require__(33) - , META = __webpack_require__(46).KEY - , $fails = __webpack_require__(31) - , shared = __webpack_require__(83) - , setToStringTag = __webpack_require__(48) - , uid = __webpack_require__(49) - , wks = __webpack_require__(10) - , wksExt = __webpack_require__(176) - , wksDefine = __webpack_require__(297) - , keyOf = __webpack_require__(288) - , enumKeys = __webpack_require__(283) - , isArray = __webpack_require__(163) - , anObject = __webpack_require__(18) - , toIObject = __webpack_require__(23) - , toPrimitive = __webpack_require__(86) - , createDesc = __webpack_require__(40) - , _create = __webpack_require__(79) - , gOPNExt = __webpack_require__(291) - , $GOPD = __webpack_require__(80) - , $DP = __webpack_require__(19) - , $keys = __webpack_require__(39) - , gOPD = $GOPD.f - , dP = $DP.f - , gOPN = gOPNExt.f - , $Symbol = global.Symbol - , $JSON = global.JSON - , _stringify = $JSON && $JSON.stringify - , PROTOTYPE = 'prototype' - , HIDDEN = wks('_hidden') - , TO_PRIMITIVE = wks('toPrimitive') - , isEnum = {}.propertyIsEnumerable - , SymbolRegistry = shared('symbol-registry') - , AllSymbols = shared('symbols') - , OPSymbols = shared('op-symbols') - , ObjectProto = Object[PROTOTYPE] - , USE_NATIVE = typeof $Symbol == 'function' - , QObject = global.QObject; -// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 -var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; +var privatePool = new WeakMap(); -// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 -var setSymbolDesc = DESCRIPTORS && $fails(function(){ - return _create(dP({}, 'a', { - get: function(){ return dP(this, 'a', {value: 7}).a; } - })).a != 7; -}) ? function(it, key, D){ - var protoDesc = gOPD(ObjectProto, key); - if(protoDesc)delete ObjectProto[key]; - dP(it, key, D); - if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc); -} : dP; +/** + * Calculates indexes of rows to render OR rows that are visible. + * To redo the calculation, you need to create a new calculator. + * + * @class ViewportRowsCalculator + */ -var wrap = function(tag){ - var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]); - sym._k = tag; - return sym; -}; +var ViewportRowsCalculator = function () { + _createClass(ViewportRowsCalculator, null, [{ + key: "DEFAULT_HEIGHT", -var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){ - return typeof it == 'symbol'; -} : function(it){ - return it instanceof $Symbol; -}; + /** + * Default row height + * + * @type {Number} + */ + get: function get() { + return 23; + } -var $defineProperty = function defineProperty(it, key, D){ - if(it === ObjectProto)$defineProperty(OPSymbols, key, D); - anObject(it); - key = toPrimitive(key, true); - anObject(D); - if(has(AllSymbols, key)){ - if(!D.enumerable){ - if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {})); - it[HIDDEN][key] = true; - } else { - if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false; - D = _create(D, {enumerable: createDesc(0, false)}); - } return setSymbolDesc(it, key, D); - } return dP(it, key, D); -}; -var $defineProperties = function defineProperties(it, P){ - anObject(it); - var keys = enumKeys(P = toIObject(P)) - , i = 0 - , l = keys.length - , key; - while(l > i)$defineProperty(it, key = keys[i++], P[key]); - return it; -}; -var $create = function create(it, P){ - return P === undefined ? _create(it) : $defineProperties(_create(it), P); -}; -var $propertyIsEnumerable = function propertyIsEnumerable(key){ - var E = isEnum.call(this, key = toPrimitive(key, true)); - if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false; - return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true; -}; -var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){ - it = toIObject(it); - key = toPrimitive(key, true); - if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return; - var D = gOPD(it, key); - if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true; - return D; -}; -var $getOwnPropertyNames = function getOwnPropertyNames(it){ - var names = gOPN(toIObject(it)) - , result = [] - , i = 0 - , key; - while(names.length > i){ - if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key); - } return result; -}; -var $getOwnPropertySymbols = function getOwnPropertySymbols(it){ - var IS_OP = it === ObjectProto - , names = gOPN(IS_OP ? OPSymbols : toIObject(it)) - , result = [] - , i = 0 - , key; - while(names.length > i){ - if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]); - } return result; -}; + /** + * @param {Number} viewportHeight Height of the viewport + * @param {Number} scrollOffset Current vertical scroll position of the viewport + * @param {Number} totalRows Total number of rows + * @param {Function} rowHeightFn Function that returns the height of the row at a given index (in px) + * @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin) + * @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport + * @param {Number} horizontalScrollbarHeight + */ -// 19.4.1.1 Symbol([description]) -if(!USE_NATIVE){ - $Symbol = function Symbol(){ - if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!'); - var tag = uid(arguments.length > 0 ? arguments[0] : undefined); - var $set = function(value){ - if(this === ObjectProto)$set.call(OPSymbols, value); - if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false; - setSymbolDesc(this, tag, createDesc(1, value)); - }; - if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set}); - return wrap(tag); - }; - redefine($Symbol[PROTOTYPE], 'toString', function toString(){ - return this._k; - }); + }]); - $GOPD.f = $getOwnPropertyDescriptor; - $DP.f = $defineProperty; - __webpack_require__(81).f = gOPNExt.f = $getOwnPropertyNames; - __webpack_require__(47).f = $propertyIsEnumerable; - __webpack_require__(57).f = $getOwnPropertySymbols; + function ViewportRowsCalculator(viewportHeight, scrollOffset, totalRows, rowHeightFn, overrideFn, onlyFullyVisible, horizontalScrollbarHeight) { + _classCallCheck(this, ViewportRowsCalculator); - if(DESCRIPTORS && !__webpack_require__(56)){ - redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); - } + privatePool.set(this, { + viewportHeight: viewportHeight, + scrollOffset: scrollOffset, + totalRows: totalRows, + rowHeightFn: rowHeightFn, + overrideFn: overrideFn, + onlyFullyVisible: onlyFullyVisible, + horizontalScrollbarHeight: horizontalScrollbarHeight + }); - wksExt.f = function(name){ - return wrap(wks(name)); - } -} + /** + * Number of rendered/visible rows + * + * @type {Number} + */ + this.count = 0; -$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol}); + /** + * Index of the first rendered/visible row (can be overwritten using overrideFn) + * + * @type {Number|null} + */ + this.startRow = null; -for(var symbols = ( - // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 - 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' -).split(','), i = 0; symbols.length > i; )wks(symbols[i++]); + /** + * Index of the last rendered/visible row (can be overwritten using overrideFn) + * + * @type {null} + */ + this.endRow = null; -for(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]); + /** + * Position of the first rendered/visible row (in px) + * + * @type {Number|null} + */ + this.startPosition = null; -$export($export.S + $export.F * !USE_NATIVE, 'Symbol', { - // 19.4.2.1 Symbol.for(key) - 'for': function(key){ - return has(SymbolRegistry, key += '') - ? SymbolRegistry[key] - : SymbolRegistry[key] = $Symbol(key); - }, - // 19.4.2.5 Symbol.keyFor(sym) - keyFor: function keyFor(key){ - if(isSymbol(key))return keyOf(SymbolRegistry, key); - throw TypeError(key + ' is not a symbol!'); - }, - useSetter: function(){ setter = true; }, - useSimple: function(){ setter = false; } -}); + this.calculate(); + } -$export($export.S + $export.F * !USE_NATIVE, 'Object', { - // 19.1.2.2 Object.create(O [, Properties]) - create: $create, - // 19.1.2.4 Object.defineProperty(O, P, Attributes) - defineProperty: $defineProperty, - // 19.1.2.3 Object.defineProperties(O, Properties) - defineProperties: $defineProperties, - // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) - getOwnPropertyDescriptor: $getOwnPropertyDescriptor, - // 19.1.2.7 Object.getOwnPropertyNames(O) - getOwnPropertyNames: $getOwnPropertyNames, - // 19.1.2.8 Object.getOwnPropertySymbols(O) - getOwnPropertySymbols: $getOwnPropertySymbols -}); + /** + * Calculates viewport + */ -// 24.3.2 JSON.stringify(value [, replacer [, space]]) -$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){ - var S = $Symbol(); - // MS Edge converts symbol values to JSON as {} - // WebKit converts symbol values to JSON as null - // V8 throws on boxed symbols - return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}'; -})), 'JSON', { - stringify: function stringify(it){ - if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined - var args = [it] - , i = 1 - , replacer, $replacer; - while(arguments.length > i)args.push(arguments[i++]); - replacer = args[1]; - if(typeof replacer == 'function')$replacer = replacer; - if($replacer || !isArray(replacer))replacer = function(key, value){ - if($replacer)value = $replacer.call(this, key, value); - if(!isSymbol(value))return value; - }; - args[1] = replacer; - return _stringify.apply($JSON, args); - } -}); -// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) -$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(32)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); -// 19.4.3.5 Symbol.prototype[@@toStringTag] -setToStringTag($Symbol, 'Symbol'); -// 20.2.1.9 Math[@@toStringTag] -setToStringTag(Math, 'Math', true); -// 24.3.3 JSON[@@toStringTag] -setToStringTag(global.JSON, 'JSON', true); + _createClass(ViewportRowsCalculator, [{ + key: "calculate", + value: function calculate() { + var sum = 0; + var needReverse = true; + var startPositions = []; -/***/ }), -/* 124 */ -/***/ (function(module, exports, __webpack_require__) { + var priv = privatePool.get(this); + var onlyFullyVisible = priv.onlyFullyVisible; + var overrideFn = priv.overrideFn; + var rowHeightFn = priv.rowHeightFn; + var scrollOffset = priv.scrollOffset; + var totalRows = priv.totalRows; + var viewportHeight = priv.viewportHeight; + var horizontalScrollbarHeight = priv.horizontalScrollbarHeight || 0; + var rowHeight = void 0; -"use strict"; + // Calculate the number (start and end index) of rows needed + for (var i = 0; i < totalRows; i++) { + rowHeight = rowHeightFn(i); -var each = __webpack_require__(52)(0) - , redefine = __webpack_require__(33) - , meta = __webpack_require__(46) - , assign = __webpack_require__(169) - , weak = __webpack_require__(159) - , isObject = __webpack_require__(15) - , getWeak = meta.getWeak - , isExtensible = Object.isExtensible - , uncaughtFrozenStore = weak.ufstore - , tmp = {} - , InternalMap; - -var wrapper = function(get){ - return function WeakMap(){ - return get(this, arguments.length > 0 ? arguments[0] : undefined); - }; -}; + if (rowHeight === undefined) { + rowHeight = ViewportRowsCalculator.DEFAULT_HEIGHT; + } + if (sum <= scrollOffset && !onlyFullyVisible) { + this.startRow = i; + } -var methods = { - // 23.3.3.3 WeakMap.prototype.get(key) - get: function get(key){ - if(isObject(key)){ - var data = getWeak(key); - if(data === true)return uncaughtFrozenStore(this).get(key); - return data ? data[this._i] : undefined; - } - }, - // 23.3.3.5 WeakMap.prototype.set(key, value) - set: function set(key, value){ - return weak.def(this, key, value); - } -}; + // the row is within the "visible range" + if (sum >= scrollOffset && sum + rowHeight <= scrollOffset + viewportHeight - horizontalScrollbarHeight) { + if (this.startRow === null) { + this.startRow = i; + } + this.endRow = i; + } + startPositions.push(sum); + sum += rowHeight; -// 23.3 WeakMap Objects -var $WeakMap = module.exports = __webpack_require__(53)('WeakMap', wrapper, methods, weak, true, true); + if (!onlyFullyVisible) { + this.endRow = i; + } + if (sum >= scrollOffset + viewportHeight - horizontalScrollbarHeight) { + needReverse = false; + break; + } + } -// IE11 WeakMap frozen keys fix -if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){ - InternalMap = weak.getConstructor(wrapper); - assign(InternalMap.prototype, methods); - meta.NEED = true; - each(['delete', 'has', 'get', 'set'], function(key){ - var proto = $WeakMap.prototype - , method = proto[key]; - redefine(proto, key, function(a, b){ - // store frozen objects on internal weakmap shim - if(isObject(a) && !isExtensible(a)){ - if(!this._f)this._f = new InternalMap; - var result = this._f[key](a, b); - return key == 'set' ? this : result; - // store all the rest on native weakmap - } return method.call(this, a, b); - }); - }); -} + // If the estimation has reached the last row and there is still some space available in the viewport, + // we need to render in reverse in order to fill the whole viewport with rows + if (this.endRow === totalRows - 1 && needReverse) { + this.startRow = this.endRow; -/***/ }), -/* 125 */ -/***/ (function(module, exports, __webpack_require__) { + while (this.startRow > 0) { + // rowHeight is the height of the last row + var viewportSum = startPositions[this.endRow] + rowHeight - startPositions[this.startRow - 1]; -"use strict"; + if (viewportSum <= viewportHeight - horizontalScrollbarHeight || !onlyFullyVisible) { + this.startRow--; + } + if (viewportSum >= viewportHeight - horizontalScrollbarHeight) { + break; + } + } + } -var weak = __webpack_require__(159); + if (this.startRow !== null && overrideFn) { + overrideFn(this); + } + this.startPosition = startPositions[this.startRow]; -// 23.4 WeakSet Objects -__webpack_require__(53)('WeakSet', function(get){ - return function WeakSet(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); }; -}, { - // 23.4.3.1 WeakSet.prototype.add(value) - add: function add(value){ - return weak.def(this, value, true); - } -}, weak, false, true); + if (this.startPosition == void 0) { + this.startPosition = null; + } + if (this.startRow !== null) { + this.count = this.endRow - this.startRow + 1; + } + } + }]); + + return ViewportRowsCalculator; +}(); + +exports.default = ViewportRowsCalculator; /***/ }), -/* 126 */ +/* 157 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -// https://github.com/tc39/Array.prototype.includes -var $export = __webpack_require__(3) - , $includes = __webpack_require__(156)(true); -$export($export.P, 'Array', { - includes: function includes(el /*, fromIndex = 0 */){ - return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined); - } -}); +exports.__esModule = true; -__webpack_require__(37)('includes'); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -/***/ }), -/* 127 */ -/***/ (function(module, exports, __webpack_require__) { +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -// https://github.com/tc39/proposal-object-values-entries -var $export = __webpack_require__(3) - , $entries = __webpack_require__(171)(true); +/** + * @class ColumnFilter + */ +var ColumnFilter = function () { + /** + * @param {Number} offset + * @param {Number} total + * @param {Number} countTH + */ + function ColumnFilter(offset, total, countTH) { + _classCallCheck(this, ColumnFilter); -$export($export.S, 'Object', { - entries: function entries(it){ - return $entries(it); + this.offset = offset; + this.total = total; + this.countTH = countTH; } -}); -/***/ }), -/* 128 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * @param index + * @returns {Number} + */ -// https://github.com/tc39/proposal-object-getownpropertydescriptors -var $export = __webpack_require__(3) - , ownKeys = __webpack_require__(293) - , toIObject = __webpack_require__(23) - , gOPD = __webpack_require__(80) - , createProperty = __webpack_require__(73); -$export($export.S, 'Object', { - getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object){ - var O = toIObject(object) - , getDesc = gOPD.f - , keys = ownKeys(O) - , result = {} - , i = 0 - , key; - while(keys.length > i)createProperty(result, key = keys[i++], getDesc(O, key)); - return result; - } -}); + _createClass(ColumnFilter, [{ + key: "offsetted", + value: function offsetted(index) { + return index + this.offset; + } -/***/ }), -/* 129 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * @param index + * @returns {Number} + */ -// https://github.com/tc39/proposal-object-values-entries -var $export = __webpack_require__(3) - , $values = __webpack_require__(171)(false); + }, { + key: "unOffsetted", + value: function unOffsetted(index) { + return index - this.offset; + } -$export($export.S, 'Object', { - values: function values(it){ - return $values(it); - } -}); + /** + * @param index + * @returns {Number} + */ -/***/ }), -/* 130 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: "renderedToSource", + value: function renderedToSource(index) { + return this.offsetted(index); + } -"use strict"; + /** + * @param index + * @returns {Number} + */ -// https://github.com/tc39/proposal-string-pad-start-end -var $export = __webpack_require__(3) - , $pad = __webpack_require__(174); + }, { + key: "sourceToRendered", + value: function sourceToRendered(index) { + return this.unOffsetted(index); + } -$export($export.P, 'String', { - padEnd: function padEnd(maxLength /*, fillString = ' ' */){ - return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false); - } -}); + /** + * @param index + * @returns {Number} + */ -/***/ }), -/* 131 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: "offsettedTH", + value: function offsettedTH(index) { + return index - this.countTH; + } -"use strict"; + /** + * @param index + * @returns {Number} + */ -// https://github.com/tc39/proposal-string-pad-start-end -var $export = __webpack_require__(3) - , $pad = __webpack_require__(174); + }, { + key: "unOffsettedTH", + value: function unOffsettedTH(index) { + return index + this.countTH; + } -$export($export.P, 'String', { - padStart: function padStart(maxLength /*, fillString = ' ' */){ - return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true); - } -}); + /** + * @param index + * @returns {Number} + */ -/***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: "visibleRowHeadedColumnToSourceColumn", + value: function visibleRowHeadedColumnToSourceColumn(index) { + return this.renderedToSource(this.offsettedTH(index)); + } -var $iterators = __webpack_require__(67) - , redefine = __webpack_require__(33) - , global = __webpack_require__(13) - , hide = __webpack_require__(32) - , Iterators = __webpack_require__(45) - , wks = __webpack_require__(10) - , ITERATOR = wks('iterator') - , TO_STRING_TAG = wks('toStringTag') - , ArrayValues = Iterators.Array; - -for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){ - var NAME = collections[i] - , Collection = global[NAME] - , proto = Collection && Collection.prototype - , key; - if(proto){ - if(!proto[ITERATOR])hide(proto, ITERATOR, ArrayValues); - if(!proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME); - Iterators[NAME] = ArrayValues; - for(key in $iterators)if(!proto[key])redefine(proto, key, $iterators[key], true); - } -} + /** + * @param index + * @returns {Number} + */ -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: "sourceColumnToVisibleRowHeadedColumn", + value: function sourceColumnToVisibleRowHeadedColumn(index) { + return this.unOffsettedTH(this.sourceToRendered(index)); + } + }]); -var $export = __webpack_require__(3) - , $task = __webpack_require__(85); -$export($export.G + $export.B, { - setImmediate: $task.set, - clearImmediate: $task.clear -}); + return ColumnFilter; +}(); + +exports.default = ColumnFilter; /***/ }), -/* 134 */ +/* 158 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +exports.__esModule = true; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** - * SheetClip - Spreadsheet Clipboard Parser - * version 0.2 - * - * This tiny library transforms JavaScript arrays to strings that are pasteable by LibreOffice, OpenOffice, - * Google Docs and Microsoft Excel. - * - * Copyright 2012, Marcin Warpechowski - * Licensed under the MIT license. - * http://github.com/warpech/sheetclip/ + * @class RowFilter */ -/*jslint white: true*/ -(function (global) { - "use strict"; +var RowFilter = function () { + /** + * @param {Number} offset + * @param {Number} total + * @param {Number} countTH + */ + function RowFilter(offset, total, countTH) { + _classCallCheck(this, RowFilter); - function countQuotes(str) { - return str.split('"').length - 1; + this.offset = offset; + this.total = total; + this.countTH = countTH; } - var SheetClip = { + /** + * @param index + * @returns {Number} + */ + + + _createClass(RowFilter, [{ + key: "offsetted", + value: function offsetted(index) { + return index + this.offset; + } + /** - * Decode spreadsheet string into array + * @param index + * @returns {Number} + */ + + }, { + key: "unOffsetted", + value: function unOffsetted(index) { + return index - this.offset; + } + + /** + * @param index + * @returns {Number} + */ + + }, { + key: "renderedToSource", + value: function renderedToSource(index) { + return this.offsetted(index); + } + + /** + * @param index + * @returns {Number} + */ + + }, { + key: "sourceToRendered", + value: function sourceToRendered(index) { + return this.unOffsetted(index); + } + + /** + * @param index + * @returns {Number} + */ + + }, { + key: "offsettedTH", + value: function offsettedTH(index) { + return index - this.countTH; + } + + /** + * @param index + * @returns {Number} + */ + + }, { + key: "unOffsettedTH", + value: function unOffsettedTH(index) { + return index + this.countTH; + } + + /** + * @param index + * @returns {Number} + */ + + }, { + key: "visibleColHeadedRowToSourceRow", + value: function visibleColHeadedRowToSourceRow(index) { + return this.renderedToSource(this.offsettedTH(index)); + } + + /** + * @param index + * @returns {Number} + */ + + }, { + key: "sourceRowToVisibleColHeadedRow", + value: function sourceRowToVisibleColHeadedRow(index) { + return this.unOffsettedTH(this.sourceToRendered(index)); + } + }]); + + return RowFilter; +}(); + +exports.default = RowFilter; + +/***/ }), +/* 159 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _element = __webpack_require__(0); + +var _object = __webpack_require__(1); + +var _string = __webpack_require__(32); + +var _event = __webpack_require__(160); + +var _event2 = _interopRequireDefault(_event); + +var _overlays = __webpack_require__(161); + +var _overlays2 = _interopRequireDefault(_overlays); + +var _scroll = __webpack_require__(162); + +var _scroll2 = _interopRequireDefault(_scroll); + +var _settings = __webpack_require__(163); + +var _settings2 = _interopRequireDefault(_settings); + +var _table = __webpack_require__(164); + +var _table2 = _interopRequireDefault(_table); + +var _viewport = __webpack_require__(166); + +var _viewport2 = _interopRequireDefault(_viewport); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * @class Walkontable + */ +var Walkontable = function () { + /** + * @param {Object} settings + */ + function Walkontable(settings) { + _classCallCheck(this, Walkontable); + + var originalHeaders = []; + + // this is the namespace for global events + this.guid = 'wt_' + (0, _string.randomString)(); + + // bootstrap from settings + if (settings.cloneSource) { + this.cloneSource = settings.cloneSource; + this.cloneOverlay = settings.cloneOverlay; + this.wtSettings = settings.cloneSource.wtSettings; + this.wtTable = new _table2.default(this, settings.table, settings.wtRootElement); + this.wtScroll = new _scroll2.default(this); + this.wtViewport = settings.cloneSource.wtViewport; + this.wtEvent = new _event2.default(this); + this.selections = this.cloneSource.selections; + } else { + this.wtSettings = new _settings2.default(this, settings); + this.wtTable = new _table2.default(this, settings.table); + this.wtScroll = new _scroll2.default(this); + this.wtViewport = new _viewport2.default(this); + this.wtEvent = new _event2.default(this); + this.selections = this.getSetting('selections'); + this.wtOverlays = new _overlays2.default(this); + this.exportSettingsAsClassNames(); + } + + // find original headers + if (this.wtTable.THEAD.childNodes.length && this.wtTable.THEAD.childNodes[0].childNodes.length) { + for (var c = 0, clen = this.wtTable.THEAD.childNodes[0].childNodes.length; c < clen; c++) { + originalHeaders.push(this.wtTable.THEAD.childNodes[0].childNodes[c].innerHTML); + } + if (!this.getSetting('columnHeaders').length) { + this.update('columnHeaders', [function (column, TH) { + (0, _element.fastInnerText)(TH, originalHeaders[column]); + }]); + } + } + this.drawn = false; + this.drawInterrupted = false; + } + + /** + * Force rerender of Walkontable + * + * @param {Boolean} [fastDraw=false] When `true`, try to refresh only the positions of borders without rerendering + * the data. It will only work if Table.draw() does not force + * rendering anyway + * @returns {Walkontable} + */ + + + _createClass(Walkontable, [{ + key: 'draw', + value: function draw() { + var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + this.drawInterrupted = false; + + if (!fastDraw && !(0, _element.isVisible)(this.wtTable.TABLE)) { + // draw interrupted because TABLE is not visible + this.drawInterrupted = true; + } else { + this.wtTable.draw(fastDraw); + } + + return this; + } + + /** + * Returns the TD at coords. If topmost is set to true, returns TD from the topmost overlay layer, + * if not set or set to false, returns TD from the master table. * - * @param {String} str - * @returns {Array} + * @param {CellCoords} coords + * @param {Boolean} [topmost=false] + * @returns {Object} */ - parse: function parse(str) { - var r, - rLen, - rows, - arr = [], - a = 0, - c, - cLen, - multiline, - last; - rows = str.split('\n'); + }, { + key: 'getCell', + value: function getCell(coords) { + var topmost = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - if (rows.length > 1 && rows[rows.length - 1] === '') { - rows.pop(); + if (!topmost) { + return this.wtTable.getCell(coords); } - for (r = 0, rLen = rows.length; r < rLen; r += 1) { - rows[r] = rows[r].split('\t'); - for (c = 0, cLen = rows[r].length; c < cLen; c += 1) { - if (!arr[a]) { - arr[a] = []; - } - if (multiline && c === 0) { - last = arr[a].length - 1; - arr[a][last] = arr[a][last] + '\n' + rows[r][0]; + var totalRows = this.wtSettings.getSetting('totalRows'); + var fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop'); + var fixedRowsBottom = this.wtSettings.getSetting('fixedRowsBottom'); + var fixedColumns = this.wtSettings.getSetting('fixedColumnsLeft'); - if (multiline && countQuotes(rows[r][0]) & 1) { - //& 1 is a bitwise way of performing mod 2 - multiline = false; - arr[a][last] = arr[a][last].substring(0, arr[a][last].length - 1).replace(/""/g, '"'); - } - } else { - if (c === cLen - 1 && rows[r][c].indexOf('"') === 0 && countQuotes(rows[r][c]) & 1) { - arr[a].push(rows[r][c].substring(1).replace(/""/g, '"')); - multiline = true; - } else { - arr[a].push(rows[r][c].replace(/""/g, '"')); - multiline = false; - } - } + if (coords.row < fixedRowsTop && coords.col < fixedColumns) { + return this.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell(coords); + } else if (coords.row < fixedRowsTop) { + return this.wtOverlays.topOverlay.clone.wtTable.getCell(coords); + } else if (coords.col < fixedColumns && coords.row >= totalRows - fixedRowsBottom) { + if (this.wtOverlays.bottomLeftCornerOverlay && this.wtOverlays.bottomLeftCornerOverlay.clone) { + return this.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.getCell(coords); } - if (!multiline) { - a += 1; + } else if (coords.col < fixedColumns) { + return this.wtOverlays.leftOverlay.clone.wtTable.getCell(coords); + } else if (coords.row < totalRows && coords.row > totalRows - fixedRowsBottom) { + if (this.wtOverlays.bottomOverlay && this.wtOverlays.bottomOverlay.clone) { + return this.wtOverlays.bottomOverlay.clone.wtTable.getCell(coords); } } - return arr; - }, + return this.wtTable.getCell(coords); + } /** - * Encode array into valid spreadsheet string + * @param {Object} settings + * @param {*} value + * @returns {Walkontable} + */ + + }, { + key: 'update', + value: function update(settings, value) { + return this.wtSettings.update(settings, value); + } + + /** + * Scroll the viewport to a row at the given index in the data source + * + * @param {Number} row + * @returns {Walkontable} + */ + + }, { + key: 'scrollVertical', + value: function scrollVertical(row) { + this.wtOverlays.topOverlay.scrollTo(row); + this.getSetting('onScrollVertically'); + + return this; + } + + /** + * Scroll the viewport to a column at the given index in the data source + * + * @param {Number} column + * @returns {Walkontable} + */ + + }, { + key: 'scrollHorizontal', + value: function scrollHorizontal(column) { + this.wtOverlays.leftOverlay.scrollTo(column); + this.getSetting('onScrollHorizontally'); + + return this; + } + + /** + * Scrolls the viewport to a cell (rerenders if needed) + * + * @param {CellCoords} coords + * @returns {Walkontable} + */ + + }, { + key: 'scrollViewport', + value: function scrollViewport(coords) { + this.wtScroll.scrollViewport(coords); + + return this; + } + + /** + * @returns {Array} + */ + + }, { + key: 'getViewport', + value: function getViewport() { + return [this.wtTable.getFirstVisibleRow(), this.wtTable.getFirstVisibleColumn(), this.wtTable.getLastVisibleRow(), this.wtTable.getLastVisibleColumn()]; + } + + /** + * Get overlay name * - * @param arr * @returns {String} */ - stringify: function stringify(arr) { - var r, - rLen, - c, - cLen, - str = '', - val; - for (r = 0, rLen = arr.length; r < rLen; r += 1) { - cLen = arr[r].length; + }, { + key: 'getOverlayName', + value: function getOverlayName() { + return this.cloneOverlay ? this.cloneOverlay.type : 'master'; + } - for (c = 0; c < cLen; c += 1) { - if (c > 0) { - str += '\t'; - } - val = arr[r][c]; + /** + * Check overlay type of this Walkontable instance. + * + * @param {String} name Clone type @see {Overlay.CLONE_TYPES}. + * @returns {Boolean} + */ - if (typeof val === 'string') { - if (val.indexOf('\n') > -1) { - str += '"' + val.replace(/"/g, '""') + '"'; - } else { - str += val; - } - } else if (val === null || val === void 0) { - // void 0 resolves to undefined - str += ''; - } else { - str += val; - } - } + }, { + key: 'isOverlayName', + value: function isOverlayName(name) { + if (this.cloneOverlay) { + return this.cloneOverlay.type === name; + } - if (r !== rLen - 1) { - str += '\n'; + return false; + } + + /** + * Export settings as class names added to the parent element of the table. + */ + + }, { + key: 'exportSettingsAsClassNames', + value: function exportSettingsAsClassNames() { + var _this = this; + + var toExport = { + rowHeaders: ['array'], + columnHeaders: ['array'] + }; + var allClassNames = []; + var newClassNames = []; + + (0, _object.objectEach)(toExport, function (optionType, key) { + if (optionType.indexOf('array') > -1 && _this.getSetting(key).length) { + newClassNames.push('ht' + (0, _string.toUpperCaseFirst)(key)); } - } + allClassNames.push('ht' + (0, _string.toUpperCaseFirst)(key)); + }); + (0, _element.removeClass)(this.wtTable.wtRootElement.parentNode, allClassNames); + (0, _element.addClass)(this.wtTable.wtRootElement.parentNode, newClassNames); + } - return str; + /** + * Get/Set Walkontable instance setting + * + * @param {String} key + * @param {*} [param1] + * @param {*} [param2] + * @param {*} [param3] + * @param {*} [param4] + * @returns {*} + */ + + }, { + key: 'getSetting', + value: function getSetting(key, param1, param2, param3, param4) { + // this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips + return this.wtSettings.getSetting(key, param1, param2, param3, param4); } - }; - if (true) { - exports.parse = SheetClip.parse; - exports.stringify = SheetClip.stringify; - } else { - global.SheetClip = SheetClip; - } -})(window); + /** + * Checks if setting exists + * + * @param {String} key + * @returns {Boolean} + */ + + }, { + key: 'hasSetting', + value: function hasSetting(key) { + return this.wtSettings.has(key); + } + + /** + * Destroy instance + */ + + }, { + key: 'destroy', + value: function destroy() { + this.wtOverlays.destroy(); + this.wtEvent.destroy(); + } + }]); + + return Walkontable; +}(); + +exports.default = Walkontable; /***/ }), -/* 135 */ +/* 160 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +exports.__esModule = true; -/*! - * https://github.com/Starcounter-Jack/JSON-Patch - * json-patch-duplex.js version: 0.5.7 - * (c) 2013 Joachim Wester - * MIT license +var _element = __webpack_require__(0); + +var _function = __webpack_require__(35); + +var _browser = __webpack_require__(26); + +var _eventManager = __webpack_require__(4); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * */ -var __extends = undefined && undefined.__extends || function (d, b) { - for (var p in b) { - if (b.hasOwnProperty(p)) d[p] = b[p]; - }function __() { - this.constructor = d; - } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var OriginalError = Error; -var jsonpatch; -(function (jsonpatch) { - var _objectKeys = function _objectKeys(obj) { - if (_isArray(obj)) { - var keys = new Array(obj.length); - for (var k = 0; k < keys.length; k++) { - keys[k] = "" + k; - } - return keys; - } - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - keys.push(i); - } - } - return keys; - }; - function _equals(a, b) { - switch (typeof a === 'undefined' ? 'undefined' : _typeof(a)) { - case 'undefined': //backward compatibility, but really I think we should return false - case 'boolean': - case 'string': - case 'number': - return a === b; - case 'object': - if (a === null) return b === null; - if (_isArray(a)) { - if (!_isArray(b) || a.length !== b.length) return false; - for (var i = 0, l = a.length; i < l; i++) { - if (!_equals(a[i], b[i])) return false; - }return true; - } - var bKeys = _objectKeys(b); - var bLength = bKeys.length; - if (_objectKeys(a).length !== bLength) return false; - for (var i = 0; i < bLength; i++) { - if (!_equals(a[i], b[i])) return false; - }return true; - default: - return false; - } - } - /* We use a Javascript hash to store each - function. Each hash entry (property) uses - the operation identifiers specified in rfc6902. - In this way, we can map each patch operation - to its dedicated function in efficient way. - */ - /* The operations applicable to an object */ - var objOps = { - add: function add(obj, key) { - obj[key] = this.value; - return true; - }, - remove: function remove(obj, key) { - delete obj[key]; - return true; - }, - replace: function replace(obj, key) { - obj[key] = this.value; - return true; - }, - move: function move(obj, key, tree) { - var temp = { op: "_get", path: this.from }; - apply(tree, [temp]); - apply(tree, [{ op: "remove", path: this.from }]); - apply(tree, [{ op: "add", path: this.path, value: temp.value }]); - return true; - }, - copy: function copy(obj, key, tree) { - var temp = { op: "_get", path: this.from }; - apply(tree, [temp]); - apply(tree, [{ op: "add", path: this.path, value: temp.value }]); - return true; - }, - test: function test(obj, key) { - return _equals(obj[key], this.value); - }, - _get: function _get(obj, key) { - this.value = obj[key]; - } - }; - /* The operations applicable to an array. Many are the same as for the object */ - var arrOps = { - add: function add(arr, i) { - arr.splice(i, 0, this.value); - return true; - }, - remove: function remove(arr, i) { - arr.splice(i, 1); - return true; - }, - replace: function replace(arr, i) { - arr[i] = this.value; - return true; - }, - move: objOps.move, - copy: objOps.copy, - test: objOps.test, - _get: objOps._get - }; - /* The operations applicable to object root. Many are the same as for the object */ - var rootOps = { - add: function add(obj) { - rootOps.remove.call(this, obj); - for (var key in this.value) { - if (this.value.hasOwnProperty(key)) { - obj[key] = this.value[key]; - } - } - return true; - }, - remove: function remove(obj) { - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - objOps.remove.call(this, obj, key); - } - } - return true; - }, - replace: function replace(obj) { - apply(obj, [{ op: "remove", path: this.path }]); - apply(obj, [{ op: "add", path: this.path, value: this.value }]); - return true; - }, - move: objOps.move, - copy: objOps.copy, - test: function test(obj) { - return JSON.stringify(obj) === JSON.stringify(this.value); - }, - _get: function _get(obj) { - this.value = obj; - } - }; - var observeOps = { - add: function add(patches, path) { - var patch = { - op: "add", - path: path + escapePathComponent(this.name), - value: this.object[this.name] }; - patches.push(patch); - }, - 'delete': function _delete(patches, path) { - var patch = { - op: "remove", - path: path + escapePathComponent(this.name) - }; - patches.push(patch); - }, - update: function update(patches, path) { - var patch = { - op: "replace", - path: path + escapePathComponent(this.name), - value: this.object[this.name] - }; - patches.push(patch); - } - }; - function escapePathComponent(str) { - if (str.indexOf('/') === -1 && str.indexOf('~') === -1) return str; - return str.replace(/~/g, '~0').replace(/\//g, '~1'); - } - function _getPathRecursive(root, obj) { - var found; - for (var key in root) { - if (root.hasOwnProperty(key)) { - if (root[key] === obj) { - return escapePathComponent(key) + '/'; - } else if (_typeof(root[key]) === 'object') { - found = _getPathRecursive(root[key], obj); - if (found != '') { - return escapePathComponent(key) + '/' + found; - } - } - } - } - return ''; - } - function getPath(root, obj) { - if (root === obj) { - return '/'; - } - var path = _getPathRecursive(root, obj); - if (path === '') { - throw new OriginalError("Object not found in root"); - } - return '/' + path; - } - var beforeDict = []; - var Mirror = function () { - function Mirror(obj) { - this.observers = []; - this.obj = obj; - } - return Mirror; - }(); - var ObserverInfo = function () { - function ObserverInfo(callback, observer) { - this.callback = callback; - this.observer = observer; - } - return ObserverInfo; - }(); - function getMirror(obj) { - for (var i = 0, ilen = beforeDict.length; i < ilen; i++) { - if (beforeDict[i].obj === obj) { - return beforeDict[i]; - } - } +function Event(instance) { + var that = this; + var eventManager = new _eventManager2.default(instance); + + this.instance = instance; + + var dblClickOrigin = [null, null]; + this.dblClickTimeout = [null, null]; + + var onMouseDown = function onMouseDown(event) { + var activeElement = document.activeElement; + var getParentNode = (0, _function.partial)(_element.getParent, event.realTarget); + var realTarget = event.realTarget; + + // ignore focusable element from mouse down processing (https://github.com/handsontable/handsontable/issues/3555) + if (realTarget === activeElement || getParentNode(0) === activeElement || getParentNode(1) === activeElement) { + return; } - function getObserverFromMirror(mirror, callback) { - for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) { - if (mirror.observers[j].callback === callback) { - return mirror.observers[j].observer; - } - } + + var cell = that.parentCell(realTarget); + + if ((0, _element.hasClass)(realTarget, 'corner')) { + that.instance.getSetting('onCellCornerMouseDown', event, realTarget); + } else if (cell.TD) { + if (that.instance.hasSetting('onCellMouseDown')) { + that.instance.getSetting('onCellMouseDown', event, cell.coords, cell.TD, that.instance); + } } - function removeObserverFromMirror(mirror, observer) { - for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) { - if (mirror.observers[j].observer === observer) { - mirror.observers.splice(j, 1); - return; - } - } + + if (event.button !== 2) { + // if not right mouse button + if (cell.TD) { + dblClickOrigin[0] = cell.TD; + clearTimeout(that.dblClickTimeout[0]); + that.dblClickTimeout[0] = setTimeout(function () { + dblClickOrigin[0] = null; + }, 1000); + } } - function unobserve(root, observer) { - observer.unobserve(); + }; + + var onTouchMove = function onTouchMove(event) { + that.instance.touchMoving = true; + }; + + var longTouchTimeout; + + var onTouchStart = function onTouchStart(event) { + var container = this; + + eventManager.addEventListener(this, 'touchmove', onTouchMove); + + // Prevent cell selection when scrolling with touch event - not the best solution performance-wise + that.checkIfTouchMove = setTimeout(function () { + if (that.instance.touchMoving === true) { + that.instance.touchMoving = void 0; + + eventManager.removeEventListener('touchmove', onTouchMove, false); + } + + onMouseDown(event); + }, 30); + }; + + var onMouseOver = function onMouseOver(event) { + var table, td, mainWOT; + + if (that.instance.hasSetting('onCellMouseOver')) { + table = that.instance.wtTable.TABLE; + td = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table); + mainWOT = that.instance.cloneSource || that.instance; + + if (td && td !== mainWOT.lastMouseOver && (0, _element.isChildOf)(td, table)) { + mainWOT.lastMouseOver = td; + + that.instance.getSetting('onCellMouseOver', event, that.instance.wtTable.getCoords(td), td, that.instance); + } } - jsonpatch.unobserve = unobserve; - function deepClone(obj) { - if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === "object") { - return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5 - } else { - return obj; //no need to clone primitives - } + }; + + var onMouseOut = function onMouseOut(event) { + var table = void 0; + var lastTD = void 0; + var nextTD = void 0; + + if (that.instance.hasSetting('onCellMouseOut')) { + table = that.instance.wtTable.TABLE; + lastTD = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table); + nextTD = (0, _element.closestDown)(event.relatedTarget, ['TD', 'TH'], table); + + if (lastTD && lastTD !== nextTD && (0, _element.isChildOf)(lastTD, table)) { + that.instance.getSetting('onCellMouseOut', event, that.instance.wtTable.getCoords(lastTD), lastTD, that.instance); + } } - function observe(obj, callback) { - var patches = []; - var root = obj; - var observer; - var mirror = getMirror(obj); - if (!mirror) { - mirror = new Mirror(obj); - beforeDict.push(mirror); + }; + + var onMouseUp = function onMouseUp(event) { + if (event.button !== 2) { + // if not right mouse button + var cell = that.parentCell(event.realTarget); + + if (cell.TD === dblClickOrigin[0] && cell.TD === dblClickOrigin[1]) { + if ((0, _element.hasClass)(event.realTarget, 'corner')) { + that.instance.getSetting('onCellCornerDblClick', event, cell.coords, cell.TD, that.instance); } else { - observer = getObserverFromMirror(mirror, callback); - } - if (observer) { - return observer; - } - observer = {}; - mirror.value = deepClone(obj); - if (callback) { - observer.callback = callback; - observer.next = null; - var intervals = this.intervals || [100, 1000, 10000, 60000]; - if (intervals.push === void 0) { - throw new OriginalError("jsonpatch.intervals must be an array"); - } - var currentInterval = 0; - var dirtyCheck = function dirtyCheck() { - generate(observer); - }; - var fastCheck = function fastCheck() { - clearTimeout(observer.next); - observer.next = setTimeout(function () { - dirtyCheck(); - currentInterval = 0; - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); - }, 0); - }; - var slowCheck = function slowCheck() { - dirtyCheck(); - if (currentInterval == intervals.length) currentInterval = intervals.length - 1; - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); - }; - if (typeof window !== 'undefined') { - if (window.addEventListener) { - window.addEventListener('mousedown', fastCheck); - window.addEventListener('mouseup', fastCheck); - window.addEventListener('keydown', fastCheck); - } else { - document.documentElement.attachEvent('onmousedown', fastCheck); - document.documentElement.attachEvent('onmouseup', fastCheck); - document.documentElement.attachEvent('onkeydown', fastCheck); - } - } - observer.next = setTimeout(slowCheck, intervals[currentInterval++]); - } - observer.patches = patches; - observer.object = obj; - observer.unobserve = function () { - generate(observer); - clearTimeout(observer.next); - removeObserverFromMirror(mirror, observer); - if (typeof window !== 'undefined') { - if (window.removeEventListener) { - window.removeEventListener('mousedown', fastCheck); - window.removeEventListener('mouseup', fastCheck); - window.removeEventListener('keydown', fastCheck); - } else { - document.documentElement.detachEvent('onmousedown', fastCheck); - document.documentElement.detachEvent('onmouseup', fastCheck); - document.documentElement.detachEvent('onkeydown', fastCheck); - } - } - }; - mirror.observers.push(new ObserverInfo(callback, observer)); - return observer; - } - jsonpatch.observe = observe; - function generate(observer) { - var mirror; - for (var i = 0, ilen = beforeDict.length; i < ilen; i++) { - if (beforeDict[i].obj === observer.object) { - mirror = beforeDict[i]; - break; - } - } - _generate(mirror.value, observer.object, observer.patches, ""); - if (observer.patches.length) { - apply(mirror.value, observer.patches); - } - var temp = observer.patches; - if (temp.length > 0) { - observer.patches = []; - if (observer.callback) { - observer.callback(temp); - } - } - return temp; - } - jsonpatch.generate = generate; - // Dirty check if obj is different from mirror, generate patches and update mirror - function _generate(mirror, obj, patches, path) { - var newKeys = _objectKeys(obj); - var oldKeys = _objectKeys(mirror); - var changed = false; - var deleted = false; - //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)" - for (var t = oldKeys.length - 1; t >= 0; t--) { - var key = oldKeys[t]; - var oldVal = mirror[key]; - if (obj.hasOwnProperty(key)) { - var newVal = obj[key]; - if ((typeof oldVal === 'undefined' ? 'undefined' : _typeof(oldVal)) == "object" && oldVal != null && (typeof newVal === 'undefined' ? 'undefined' : _typeof(newVal)) == "object" && newVal != null) { - _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key)); - } else { - if (oldVal != newVal) { - changed = true; - patches.push({ op: "replace", path: path + "/" + escapePathComponent(key), value: deepClone(newVal) }); - } - } - } else { - patches.push({ op: "remove", path: path + "/" + escapePathComponent(key) }); - deleted = true; // property has been deleted - } - } - if (!deleted && newKeys.length == oldKeys.length) { - return; - } - for (var t = 0; t < newKeys.length; t++) { - var key = newKeys[t]; - if (!mirror.hasOwnProperty(key)) { - patches.push({ op: "add", path: path + "/" + escapePathComponent(key), value: deepClone(obj[key]) }); - } - } - } - var _isArray; - if (Array.isArray) { - _isArray = Array.isArray; - } else { - _isArray = function _isArray(obj) { - return obj.push && typeof obj.length === 'number'; - }; - } - //3x faster than cached /^\d+$/.test(str) - function isInteger(str) { - var i = 0; - var len = str.length; - var charCode; - while (i < len) { - charCode = str.charCodeAt(i); - if (charCode >= 48 && charCode <= 57) { - i++; - continue; - } - return false; - } - return true; - } - /// Apply a json-patch operation on an object tree - function apply(tree, patches, validate) { - var result = false, - p = 0, - plen = patches.length, - patch, - key; - while (p < plen) { - patch = patches[p]; - p++; - // Find the object - var path = patch.path || ""; - var keys = path.split('/'); - var obj = tree; - var t = 1; //skip empty element - http://jsperf.com/to-shift-or-not-to-shift - var len = keys.length; - var existingPathFragment = undefined; - while (true) { - key = keys[t]; - if (validate) { - if (existingPathFragment === undefined) { - if (obj[key] === undefined) { - existingPathFragment = keys.slice(0, t).join('/'); - } else if (t == len - 1) { - existingPathFragment = patch.path; - } - if (existingPathFragment !== undefined) { - this.validator(patch, p - 1, tree, existingPathFragment); - } - } - } - t++; - if (key === undefined) { - if (t >= len) { - result = rootOps[patch.op].call(patch, obj, key, tree); // Apply patch - break; - } - } - if (_isArray(obj)) { - if (key === '-') { - key = obj.length; - } else { - if (validate && !isInteger(key)) { - throw new JsonPatchError("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", p - 1, patch.path, patch); - } - key = parseInt(key, 10); - } - if (t >= len) { - if (validate && patch.op === "add" && key > obj.length) { - throw new JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", p - 1, patch.path, patch); - } - result = arrOps[patch.op].call(patch, obj, key, tree); // Apply patch - break; - } - } else { - if (key && key.indexOf('~') != -1) key = key.replace(/~1/g, '/').replace(/~0/g, '~'); // escape chars - if (t >= len) { - result = objOps[patch.op].call(patch, obj, key, tree); // Apply patch - break; - } - } - obj = obj[key]; - } - } - return result; - } - jsonpatch.apply = apply; - function compare(tree1, tree2) { - var patches = []; - _generate(tree1, tree2, patches, ''); - return patches; - } - jsonpatch.compare = compare; - var JsonPatchError = function (_super) { - __extends(JsonPatchError, _super); - function JsonPatchError(message, name, index, operation, tree) { - _super.call(this, message); - this.message = message; - this.name = name; - this.index = index; - this.operation = operation; - this.tree = tree; - } - return JsonPatchError; - }(OriginalError); - jsonpatch.JsonPatchError = JsonPatchError; - jsonpatch.Error = JsonPatchError; - /** - * Recursively checks whether an object has any undefined values inside. - */ - function hasUndefined(obj) { - if (obj === undefined) { - return true; - } - if (typeof obj == "array" || (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) == "object") { - for (var i in obj) { - if (hasUndefined(obj[i])) { - return true; - } - } + that.instance.getSetting('onCellDblClick', event, cell.coords, cell.TD, that.instance); } - return false; + + dblClickOrigin[0] = null; + dblClickOrigin[1] = null; + } else if (cell.TD === dblClickOrigin[0]) { + that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance); + + dblClickOrigin[1] = cell.TD; + clearTimeout(that.dblClickTimeout[1]); + that.dblClickTimeout[1] = setTimeout(function () { + dblClickOrigin[1] = null; + }, 500); + } else if (cell.TD && that.instance.hasSetting('onCellMouseUp')) { + that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance); + } } - /** - * Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error. - * @param {object} operation - operation object (patch) - * @param {number} index - index of operation in the sequence - * @param {object} [tree] - object where the operation is supposed to be applied - * @param {string} [existingPathFragment] - comes along with `tree` - */ - function validator(operation, index, tree, existingPathFragment) { - if ((typeof operation === 'undefined' ? 'undefined' : _typeof(operation)) !== 'object' || operation === null || _isArray(operation)) { - throw new JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, tree); - } else if (!objOps[operation.op]) { - throw new JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, tree); - } else if (typeof operation.path !== 'string') { - throw new JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, tree); - } else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') { - throw new JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, tree); - } else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) { - throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, tree); - } else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && hasUndefined(operation.value)) { - throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', index, operation, tree); - } else if (tree) { - if (operation.op == "add") { - var pathLen = operation.path.split("/").length; - var existingPathLen = existingPathFragment.split("/").length; - if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) { - throw new JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, tree); - } - } else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') { - if (operation.path !== existingPathFragment) { - throw new JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, tree); - } - } else if (operation.op === 'move' || operation.op === 'copy') { - var existingValue = { op: "_get", path: operation.from, value: undefined }; - var error = jsonpatch.validate([existingValue], tree); - if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') { - throw new JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, tree); - } - } - } + }; + + var onTouchEnd = function onTouchEnd(event) { + clearTimeout(longTouchTimeout); + // that.instance.longTouch == void 0; + + event.preventDefault(); + onMouseUp(event); + + // eventManager.removeEventListener(that.instance.wtTable.holder, "mouseup", onMouseUp); + }; + + eventManager.addEventListener(this.instance.wtTable.holder, 'mousedown', onMouseDown); + eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseover', onMouseOver); + eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseout', onMouseOut); + eventManager.addEventListener(this.instance.wtTable.holder, 'mouseup', onMouseUp); + + // check if full HOT instance, or detached WOT AND run on mobile device + if (this.instance.wtTable.holder.parentNode.parentNode && (0, _browser.isMobileBrowser)() && !that.instance.wtTable.isWorkingOnClone()) { + var classSelector = '.' + this.instance.wtTable.holder.parentNode.className.split(' ').join('.'); + + eventManager.addEventListener(this.instance.wtTable.holder, 'touchstart', function (event) { + that.instance.touchApplied = true; + if ((0, _element.isChildOf)(event.target, classSelector)) { + onTouchStart.call(event.target, event); + } + }); + eventManager.addEventListener(this.instance.wtTable.holder, 'touchend', function (event) { + that.instance.touchApplied = false; + if ((0, _element.isChildOf)(event.target, classSelector)) { + onTouchEnd.call(event.target, event); + } + }); + + if (!that.instance.momentumScrolling) { + that.instance.momentumScrolling = {}; } - jsonpatch.validator = validator; - /** - * Validates a sequence of operations. If `tree` parameter is provided, the sequence is additionally validated against the object tree. - * If error is encountered, returns a JsonPatchError object - * @param sequence - * @param tree - * @returns {JsonPatchError|undefined} - */ - function validate(sequence, tree) { - try { - if (!_isArray(sequence)) { - throw new JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY'); - } - if (tree) { - tree = JSON.parse(JSON.stringify(tree)); //clone tree so that we can safely try applying operations - apply.call(this, tree, sequence, true); - } else { - for (var i = 0; i < sequence.length; i++) { - this.validator(sequence[i], i); - } - } - } catch (e) { - if (e instanceof JsonPatchError) { - return e; - } else { - throw e; - } + eventManager.addEventListener(this.instance.wtTable.holder, 'scroll', function (event) { + clearTimeout(that.instance.momentumScrolling._timeout); + + if (!that.instance.momentumScrolling.ongoing) { + that.instance.getSetting('onBeforeTouchScroll'); + } + that.instance.momentumScrolling.ongoing = true; + + that.instance.momentumScrolling._timeout = setTimeout(function () { + if (!that.instance.touchApplied) { + that.instance.momentumScrolling.ongoing = false; + + that.instance.getSetting('onAfterMomentumScroll'); } + }, 200); + }); + } + + eventManager.addEventListener(window, 'resize', function () { + if (that.instance.getSetting('stretchH') !== 'none') { + that.instance.draw(); } - jsonpatch.validate = validate; -})(jsonpatch || (jsonpatch = {})); -if (true) { - exports.apply = jsonpatch.apply; - exports.observe = jsonpatch.observe; - exports.unobserve = jsonpatch.unobserve; - exports.generate = jsonpatch.generate; - exports.compare = jsonpatch.compare; - exports.validate = jsonpatch.validate; - exports.validator = jsonpatch.validator; - exports.JsonPatchError = jsonpatch.JsonPatchError; - exports.Error = jsonpatch.Error; + }); + + this.destroy = function () { + clearTimeout(this.dblClickTimeout[0]); + clearTimeout(this.dblClickTimeout[1]); + + eventManager.destroy(); + }; } +Event.prototype.parentCell = function (elem) { + var cell = {}; + var TABLE = this.instance.wtTable.TABLE; + var TD = (0, _element.closestDown)(elem, ['TD', 'TH'], TABLE); + + if (TD) { + cell.coords = this.instance.wtTable.getCoords(TD); + cell.TD = TD; + } else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'current')) { + cell.coords = this.instance.selections.current.cellRange.highlight; // selections.current is current selected cell + cell.TD = this.instance.wtTable.getCell(cell.coords); + } else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'area')) { + if (this.instance.selections.area.cellRange) { + cell.coords = this.instance.selections.area.cellRange.to; // selections.area is area selected cells + cell.TD = this.instance.wtTable.getCell(cell.coords); + } + } + + return cell; +}; + +exports.default = Event; + /***/ }), -/* 136 */ +/* 161 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -35480,21 +34741,17 @@ var _createClass = function () { function defineProperties(target, props) { for var _element = __webpack_require__(0); -var _event = __webpack_require__(7); +var _array = __webpack_require__(2); -var _object = __webpack_require__(1); +var _unicode = __webpack_require__(17); -var _browser = __webpack_require__(25); +var _browser = __webpack_require__(26); var _eventManager = __webpack_require__(4); var _eventManager2 = _interopRequireDefault(_eventManager); -var _coords = __webpack_require__(42); - -var _coords2 = _interopRequireDefault(_coords); - -var _base = __webpack_require__(28); +var _base = __webpack_require__(31); var _base2 = _interopRequireDefault(_base); @@ -35503,840 +34760,830 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * + * @class Overlays */ -var Border = function () { +var Overlays = function () { /** * @param {Walkontable} wotInstance - * @param {Object} settings */ - function Border(wotInstance, settings) { - _classCallCheck(this, Border); + function Overlays(wotInstance) { + _classCallCheck(this, Overlays); - if (!settings) { - return; - } - this.eventManager = new _eventManager2.default(wotInstance); - this.instance = wotInstance; this.wot = wotInstance; - this.settings = settings; - this.mouseDown = false; - this.main = null; - this.top = null; - this.left = null; - this.bottom = null; - this.right = null; + // legacy support + this.instance = this.wot; + this.eventManager = new _eventManager2.default(this.wot); + + this.wot.update('scrollbarWidth', (0, _element.getScrollbarWidth)()); + this.wot.update('scrollbarHeight', (0, _element.getScrollbarWidth)()); - this.topStyle = null; - this.leftStyle = null; - this.bottomStyle = null; - this.rightStyle = null; + this.scrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE); - this.cornerDefaultStyle = { - width: '5px', - height: '5px', - borderWidth: '2px', - borderStyle: 'solid', - borderColor: '#FFF' + this.prepareOverlays(); + + this.destroyed = false; + this.keyPressed = false; + this.spreaderLastSize = { + width: null, + height: null + }; + this.overlayScrollPositions = { + master: { + top: 0, + left: 0 + }, + top: { + top: null, + left: 0 + }, + bottom: { + top: null, + left: 0 + }, + left: { + top: 0, + left: null + } }; - this.corner = null; - this.cornerStyle = null; - this.createBorders(settings); + this.pendingScrollCallbacks = { + master: { + top: 0, + left: 0 + }, + top: { + left: 0 + }, + bottom: { + left: 0 + }, + left: { + top: 0 + } + }; + + this.verticalScrolling = false; + this.horizontalScrolling = false; + this.delegatedScrollCallback = false; + + this.registeredListeners = []; + this.registerListeners(); } /** - * Register all necessary events + * Prepare overlays based on user settings. + * + * @returns {Boolean} Returns `true` if changes applied to overlay needs scroll synchronization. */ - _createClass(Border, [{ - key: 'registerListeners', - value: function registerListeners() { - var _this2 = this; + _createClass(Overlays, [{ + key: 'prepareOverlays', + value: function prepareOverlays() { + var syncScroll = false; - this.eventManager.addEventListener(document.body, 'mousedown', function () { - return _this2.onMouseDown(); - }); - this.eventManager.addEventListener(document.body, 'mouseup', function () { - return _this2.onMouseUp(); - }); + if (this.topOverlay) { + syncScroll = this.topOverlay.updateStateOfRendering() || syncScroll; + } else { + this.topOverlay = _base2.default.createOverlay(_base2.default.CLONE_TOP, this.wot); + } - var _loop = function _loop(c, len) { - _this2.eventManager.addEventListener(_this2.main.childNodes[c], 'mouseenter', function (event) { - return _this2.onMouseEnter(event, _this2.main.childNodes[c]); - }); - }; + if (!_base2.default.hasOverlay(_base2.default.CLONE_BOTTOM)) { + this.bottomOverlay = { + needFullRender: false, + updateStateOfRendering: function updateStateOfRendering() { + return false; + } + }; + } + if (!_base2.default.hasOverlay(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) { + this.bottomLeftCornerOverlay = { + needFullRender: false, + updateStateOfRendering: function updateStateOfRendering() { + return false; + } + }; + } - for (var c = 0, len = this.main.childNodes.length; c < len; c++) { - _loop(c, len); + if (this.bottomOverlay) { + syncScroll = this.bottomOverlay.updateStateOfRendering() || syncScroll; + } else { + this.bottomOverlay = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM, this.wot); } - } - /** - * Mouse down listener - * - * @private - */ + if (this.leftOverlay) { + syncScroll = this.leftOverlay.updateStateOfRendering() || syncScroll; + } else { + this.leftOverlay = _base2.default.createOverlay(_base2.default.CLONE_LEFT, this.wot); + } - }, { - key: 'onMouseDown', - value: function onMouseDown() { - this.mouseDown = true; - } + if (this.topOverlay.needFullRender && this.leftOverlay.needFullRender) { + if (this.topLeftCornerOverlay) { + syncScroll = this.topLeftCornerOverlay.updateStateOfRendering() || syncScroll; + } else { + this.topLeftCornerOverlay = _base2.default.createOverlay(_base2.default.CLONE_TOP_LEFT_CORNER, this.wot); + } + } - /** - * Mouse up listener - * - * @private - */ + if (this.bottomOverlay.needFullRender && this.leftOverlay.needFullRender) { + if (this.bottomLeftCornerOverlay) { + syncScroll = this.bottomLeftCornerOverlay.updateStateOfRendering() || syncScroll; + } else { + this.bottomLeftCornerOverlay = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM_LEFT_CORNER, this.wot); + } + } - }, { - key: 'onMouseUp', - value: function onMouseUp() { - this.mouseDown = false; + if (this.wot.getSetting('debug') && !this.debug) { + this.debug = _base2.default.createOverlay(_base2.default.CLONE_DEBUG, this.wot); + } + + return syncScroll; } /** - * Mouse enter listener for fragment selection functionality. - * - * @private - * @param {Event} event Dom event - * @param {HTMLElement} parentElement Part of border element. + * Refresh and redraw table */ }, { - key: 'onMouseEnter', - value: function onMouseEnter(event, parentElement) { - if (!this.mouseDown || !this.wot.getSetting('hideBorderOnMouseDownOver')) { + key: 'refreshAll', + value: function refreshAll() { + if (!this.wot.drawn) { return; } - event.preventDefault(); - (0, _event.stopImmediatePropagation)(event); + if (!this.wot.wtTable.holder.parentNode) { + // Walkontable was detached from DOM, but this handler was not removed + this.destroy(); - var _this = this; - var bounds = parentElement.getBoundingClientRect(); - // Hide border to prevents selection jumping when fragmentSelection is enabled. - parentElement.style.display = 'none'; + return; + } + this.wot.draw(true); - function isOutside(event) { - if (event.clientY < Math.floor(bounds.top)) { - return true; - } - if (event.clientY > Math.ceil(bounds.top + bounds.height)) { - return true; - } - if (event.clientX < Math.floor(bounds.left)) { - return true; - } - if (event.clientX > Math.ceil(bounds.left + bounds.width)) { - return true; - } + if (this.verticalScrolling) { + this.leftOverlay.onScroll(); } - function handler(event) { - if (isOutside(event)) { - _this.eventManager.removeEventListener(document.body, 'mousemove', handler); - parentElement.style.display = 'block'; - } + if (this.horizontalScrolling) { + this.topOverlay.onScroll(); } - this.eventManager.addEventListener(document.body, 'mousemove', handler); + this.verticalScrolling = false; + this.horizontalScrolling = false; } /** - * Create border elements - * - * @param {Object} settings + * Register all necessary event listeners. */ }, { - key: 'createBorders', - value: function createBorders(settings) { - this.main = document.createElement('div'); + key: 'registerListeners', + value: function registerListeners() { + var _this = this; - var borderDivs = ['top', 'left', 'bottom', 'right', 'corner']; - var style = this.main.style; - style.position = 'absolute'; - style.top = 0; - style.left = 0; + var topOverlayScrollable = this.topOverlay.mainTableScrollableElement; + var leftOverlayScrollable = this.leftOverlay.mainTableScrollableElement; - for (var i = 0; i < 5; i++) { - var position = borderDivs[i]; - var div = document.createElement('div'); - div.className = 'wtBorder ' + (this.settings.className || ''); // + borderDivs[i]; + var listenersToRegister = []; + listenersToRegister.push([document.documentElement, 'keydown', function (event) { + return _this.onKeyDown(event); + }]); + listenersToRegister.push([document.documentElement, 'keyup', function () { + return _this.onKeyUp(); + }]); + listenersToRegister.push([document, 'visibilitychange', function () { + return _this.onKeyUp(); + }]); + listenersToRegister.push([topOverlayScrollable, 'scroll', function (event) { + return _this.onTableScroll(event); + }]); - if (this.settings[position] && this.settings[position].hide) { - div.className += ' hidden'; - } - style = div.style; - style.backgroundColor = this.settings[position] && this.settings[position].color ? this.settings[position].color : settings.border.color; - style.height = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px'; - style.width = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px'; + if (topOverlayScrollable !== leftOverlayScrollable) { + listenersToRegister.push([leftOverlayScrollable, 'scroll', function (event) { + return _this.onTableScroll(event); + }]); + } - this.main.appendChild(div); + if (this.topOverlay.needFullRender) { + listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'scroll', function (event) { + return _this.onTableScroll(event); + }]); + listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'wheel', function (event) { + return _this.onTableScroll(event); + }]); } - this.top = this.main.childNodes[0]; - this.left = this.main.childNodes[1]; - this.bottom = this.main.childNodes[2]; - this.right = this.main.childNodes[3]; - this.topStyle = this.top.style; - this.leftStyle = this.left.style; - this.bottomStyle = this.bottom.style; - this.rightStyle = this.right.style; + if (this.bottomOverlay.needFullRender) { + listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'scroll', function (event) { + return _this.onTableScroll(event); + }]); + listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'wheel', function (event) { + return _this.onTableScroll(event); + }]); + } - this.corner = this.main.childNodes[4]; - this.corner.className += ' corner'; - this.cornerStyle = this.corner.style; - this.cornerStyle.width = this.cornerDefaultStyle.width; - this.cornerStyle.height = this.cornerDefaultStyle.height; - this.cornerStyle.border = [this.cornerDefaultStyle.borderWidth, this.cornerDefaultStyle.borderStyle, this.cornerDefaultStyle.borderColor].join(' '); + if (this.leftOverlay.needFullRender) { + listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'scroll', function (event) { + return _this.onTableScroll(event); + }]); + listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'wheel', function (event) { + return _this.onTableScroll(event); + }]); + } - if ((0, _browser.isMobileBrowser)()) { - this.createMultipleSelectorHandles(); + if (this.topLeftCornerOverlay && this.topLeftCornerOverlay.needFullRender) { + listenersToRegister.push([this.topLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) { + return _this.onTableScroll(event); + }]); } - this.disappear(); - if (!this.wot.wtTable.bordersHolder) { - this.wot.wtTable.bordersHolder = document.createElement('div'); - this.wot.wtTable.bordersHolder.className = 'htBorders'; - this.wot.wtTable.spreader.appendChild(this.wot.wtTable.bordersHolder); + if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.needFullRender) { + listenersToRegister.push([this.bottomLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) { + return _this.onTableScroll(event); + }]); } - this.wot.wtTable.bordersHolder.insertBefore(this.main, this.wot.wtTable.bordersHolder.firstChild); - } - /** - * Create multiple selector handler for mobile devices - */ + if (this.topOverlay.trimmingContainer !== window && this.leftOverlay.trimmingContainer !== window) { + // This is necessary? + // eventManager.addEventListener(window, 'scroll', (event) => this.refreshAll(event)); + listenersToRegister.push([window, 'wheel', function (event) { + var overlay = void 0; + var deltaY = event.wheelDeltaY || event.deltaY; + var deltaX = event.wheelDeltaX || event.deltaX; - }, { - key: 'createMultipleSelectorHandles', - value: function createMultipleSelectorHandles() { - this.selectionHandles = { - topLeft: document.createElement('DIV'), - topLeftHitArea: document.createElement('DIV'), - bottomRight: document.createElement('DIV'), - bottomRightHitArea: document.createElement('DIV') - }; - var width = 10; - var hitAreaWidth = 40; + if (_this.topOverlay.clone.wtTable.holder.contains(event.realTarget)) { + overlay = 'top'; + } else if (_this.bottomOverlay.clone && _this.bottomOverlay.clone.wtTable.holder.contains(event.realTarget)) { + overlay = 'bottom'; + } else if (_this.leftOverlay.clone.wtTable.holder.contains(event.realTarget)) { + overlay = 'left'; + } else if (_this.topLeftCornerOverlay && _this.topLeftCornerOverlay.clone && _this.topLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) { + overlay = 'topLeft'; + } else if (_this.bottomLeftCornerOverlay && _this.bottomLeftCornerOverlay.clone && _this.bottomLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) { + overlay = 'bottomLeft'; + } - this.selectionHandles.topLeft.className = 'topLeftSelectionHandle'; - this.selectionHandles.topLeftHitArea.className = 'topLeftSelectionHandle-HitArea'; - this.selectionHandles.bottomRight.className = 'bottomRightSelectionHandle'; - this.selectionHandles.bottomRightHitArea.className = 'bottomRightSelectionHandle-HitArea'; + if (overlay == 'top' && deltaY !== 0 || overlay == 'left' && deltaX !== 0 || overlay == 'bottom' && deltaY !== 0 || (overlay === 'topLeft' || overlay === 'bottomLeft') && (deltaY !== 0 || deltaX !== 0)) { - this.selectionHandles.styles = { - topLeft: this.selectionHandles.topLeft.style, - topLeftHitArea: this.selectionHandles.topLeftHitArea.style, - bottomRight: this.selectionHandles.bottomRight.style, - bottomRightHitArea: this.selectionHandles.bottomRightHitArea.style - }; + event.preventDefault(); + } + }]); + } - var hitAreaStyle = { - position: 'absolute', - height: hitAreaWidth + 'px', - width: hitAreaWidth + 'px', - 'border-radius': parseInt(hitAreaWidth / 1.5, 10) + 'px' - }; + while (listenersToRegister.length) { + var listener = listenersToRegister.pop(); + this.eventManager.addEventListener(listener[0], listener[1], listener[2]); - for (var prop in hitAreaStyle) { - if ((0, _object.hasOwnProperty)(hitAreaStyle, prop)) { - this.selectionHandles.styles.bottomRightHitArea[prop] = hitAreaStyle[prop]; - this.selectionHandles.styles.topLeftHitArea[prop] = hitAreaStyle[prop]; - } + this.registeredListeners.push(listener); } + } - var handleStyle = { - position: 'absolute', - height: width + 'px', - width: width + 'px', - 'border-radius': parseInt(width / 1.5, 10) + 'px', - background: '#F5F5FF', - border: '1px solid #4285c8' - }; + /** + * Deregister all previously registered listeners. + */ - for (var _prop in handleStyle) { - if ((0, _object.hasOwnProperty)(handleStyle, _prop)) { - this.selectionHandles.styles.bottomRight[_prop] = handleStyle[_prop]; - this.selectionHandles.styles.topLeft[_prop] = handleStyle[_prop]; - } + }, { + key: 'deregisterListeners', + value: function deregisterListeners() { + while (this.registeredListeners.length) { + var listener = this.registeredListeners.pop(); + this.eventManager.removeEventListener(listener[0], listener[1], listener[2]); } - this.main.appendChild(this.selectionHandles.topLeft); - this.main.appendChild(this.selectionHandles.bottomRight); - this.main.appendChild(this.selectionHandles.topLeftHitArea); - this.main.appendChild(this.selectionHandles.bottomRightHitArea); } + + /** + * Scroll listener + * + * @param {Event} event + */ + }, { - key: 'isPartRange', - value: function isPartRange(row, col) { - if (this.wot.selections.area.cellRange) { - if (row != this.wot.selections.area.cellRange.to.row || col != this.wot.selections.area.cellRange.to.col) { - return true; + key: 'onTableScroll', + value: function onTableScroll(event) { + // if mobile browser, do not update scroll positions, as the overlays are hidden during the scroll + if ((0, _browser.isMobileBrowser)()) { + return; + } + var masterHorizontal = this.leftOverlay.mainTableScrollableElement; + var masterVertical = this.topOverlay.mainTableScrollableElement; + var target = event.target; + + // For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered + // by hot.refreshBorder + if (this.keyPressed) { + if (masterVertical !== window && target !== window && !event.target.contains(masterVertical) || masterHorizontal !== window && target !== window && !event.target.contains(masterHorizontal)) { + return; } } - return false; + if (event.type === 'scroll') { + this.syncScrollPositions(event); + } else { + this.translateMouseWheelToScroll(event); + } } + + /** + * Key down listener + */ + }, { - key: 'updateMultipleSelectionHandlesPosition', - value: function updateMultipleSelectionHandlesPosition(row, col, top, left, width, height) { - var handleWidth = parseInt(this.selectionHandles.styles.topLeft.width, 10); - var hitAreaWidth = parseInt(this.selectionHandles.styles.topLeftHitArea.width, 10); + key: 'onKeyDown', + value: function onKeyDown(event) { + this.keyPressed = (0, _unicode.isKey)(event.keyCode, 'ARROW_UP|ARROW_RIGHT|ARROW_DOWN|ARROW_LEFT'); + } - this.selectionHandles.styles.topLeft.top = parseInt(top - handleWidth, 10) + 'px'; - this.selectionHandles.styles.topLeft.left = parseInt(left - handleWidth, 10) + 'px'; + /** + * Key up listener + */ - this.selectionHandles.styles.topLeftHitArea.top = parseInt(top - hitAreaWidth / 4 * 3, 10) + 'px'; - this.selectionHandles.styles.topLeftHitArea.left = parseInt(left - hitAreaWidth / 4 * 3, 10) + 'px'; + }, { + key: 'onKeyUp', + value: function onKeyUp() { + this.keyPressed = false; + } - this.selectionHandles.styles.bottomRight.top = parseInt(top + height, 10) + 'px'; - this.selectionHandles.styles.bottomRight.left = parseInt(left + width, 10) + 'px'; + /** + * Translate wheel event into scroll event and sync scroll overlays position + * + * @private + * @param {Event} event + * @returns {Boolean} + */ - this.selectionHandles.styles.bottomRightHitArea.top = parseInt(top + height - hitAreaWidth / 4, 10) + 'px'; - this.selectionHandles.styles.bottomRightHitArea.left = parseInt(left + width - hitAreaWidth / 4, 10) + 'px'; + }, { + key: 'translateMouseWheelToScroll', + value: function translateMouseWheelToScroll(event) { + var topOverlay = this.topOverlay.clone.wtTable.holder; + var bottomOverlay = this.bottomOverlay.clone ? this.bottomOverlay.clone.wtTable.holder : null; + var leftOverlay = this.leftOverlay.clone.wtTable.holder; + var topLeftCornerOverlay = this.topLeftCornerOverlay && this.topLeftCornerOverlay.clone ? this.topLeftCornerOverlay.clone.wtTable.holder : null; + var bottomLeftCornerOverlay = this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone ? this.bottomLeftCornerOverlay.clone.wtTable.holder : null; + var mouseWheelSpeedRatio = -0.2; + var deltaY = event.wheelDeltaY || -1 * event.deltaY; + var deltaX = event.wheelDeltaX || -1 * event.deltaX; + var parentHolder = null; + var eventMockup = { type: 'wheel' }; + var tempElem = event.target; + var delta = null; - if (this.settings.border.multipleSelectionHandlesVisible && this.settings.border.multipleSelectionHandlesVisible()) { - this.selectionHandles.styles.topLeft.display = 'block'; - this.selectionHandles.styles.topLeftHitArea.display = 'block'; + // Fix for extremely slow header scrolling with a mousewheel on Firefox + if (event.deltaMode === 1) { + deltaY *= 120; + deltaX *= 120; + } - if (this.isPartRange(row, col)) { - this.selectionHandles.styles.bottomRight.display = 'none'; - this.selectionHandles.styles.bottomRightHitArea.display = 'none'; - } else { - this.selectionHandles.styles.bottomRight.display = 'block'; - this.selectionHandles.styles.bottomRightHitArea.display = 'block'; + while (tempElem != document && tempElem != null) { + if (tempElem.className.indexOf('wtHolder') > -1) { + parentHolder = tempElem; + break; } - } else { - this.selectionHandles.styles.topLeft.display = 'none'; - this.selectionHandles.styles.bottomRight.display = 'none'; - this.selectionHandles.styles.topLeftHitArea.display = 'none'; - this.selectionHandles.styles.bottomRightHitArea.display = 'none'; + tempElem = tempElem.parentNode; } + eventMockup.target = parentHolder; - if (row == this.wot.wtSettings.getSetting('fixedRowsTop') || col == this.wot.wtSettings.getSetting('fixedColumnsLeft')) { - this.selectionHandles.styles.topLeft.zIndex = '9999'; - this.selectionHandles.styles.topLeftHitArea.zIndex = '9999'; + if (parentHolder === topLeftCornerOverlay || parentHolder === bottomLeftCornerOverlay) { + this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaX, 'x'); + this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaY, 'y'); } else { - this.selectionHandles.styles.topLeft.zIndex = ''; - this.selectionHandles.styles.topLeftHitArea.zIndex = ''; + if (parentHolder === topOverlay || parentHolder === bottomOverlay) { + delta = deltaY; + } else if (parentHolder === leftOverlay) { + delta = deltaX; + } + + this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * delta); } + + return false; } /** - * Show border around one or many cells + * Synchronize scroll position between master table and overlay table. * - * @param {Array} corners + * @private + * @param {Event|Object} event + * @param {Number} [fakeScrollValue=null] + * @param {String} [fakeScrollDirection=null] `x` or `y`. */ }, { - key: 'appear', - value: function appear(corners) { - if (this.disabled) { + key: 'syncScrollPositions', + value: function syncScrollPositions(event) { + var fakeScrollValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var fakeScrollDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + if (this.destroyed) { return; } - var isMultiple, fromTD, toTD, fromOffset, toOffset, containerOffset, top, minTop, left, minLeft, height, width, fromRow, fromColumn, toRow, toColumn, trimmingContainer, cornerOverlappingContainer, ilen; - - ilen = this.wot.wtTable.getRenderedRowsCount(); - - for (var i = 0; i < ilen; i++) { - var s = this.wot.wtTable.rowFilter.renderedToSource(i); + if (arguments.length === 0) { + this.syncScrollWithMaster(); - if (s >= corners[0] && s <= corners[2]) { - fromRow = s; - break; - } + return; } + var masterHorizontal = this.leftOverlay.mainTableScrollableElement; + var masterVertical = this.topOverlay.mainTableScrollableElement; + var target = event.target; + var tempScrollValue = 0; + var scrollValueChanged = false; + var topOverlay = void 0; + var leftOverlay = void 0; + var topLeftCornerOverlay = void 0; + var bottomLeftCornerOverlay = void 0; + var bottomOverlay = void 0; + var delegatedScroll = false; + var preventOverflow = this.wot.getSetting('preventOverflow'); - for (var _i = ilen - 1; _i >= 0; _i--) { - var _s = this.wot.wtTable.rowFilter.renderedToSource(_i); - - if (_s >= corners[0] && _s <= corners[2]) { - toRow = _s; - break; - } + if (this.topOverlay.needFullRender) { + topOverlay = this.topOverlay.clone.wtTable.holder; } - ilen = this.wot.wtTable.getRenderedColumnsCount(); - - for (var _i2 = 0; _i2 < ilen; _i2++) { - var _s2 = this.wot.wtTable.columnFilter.renderedToSource(_i2); - - if (_s2 >= corners[1] && _s2 <= corners[3]) { - fromColumn = _s2; - break; - } + if (this.bottomOverlay.needFullRender) { + bottomOverlay = this.bottomOverlay.clone.wtTable.holder; } - for (var _i3 = ilen - 1; _i3 >= 0; _i3--) { - var _s3 = this.wot.wtTable.columnFilter.renderedToSource(_i3); - - if (_s3 >= corners[1] && _s3 <= corners[3]) { - toColumn = _s3; - break; - } + if (this.leftOverlay.needFullRender) { + leftOverlay = this.leftOverlay.clone.wtTable.holder; } - if (fromRow === void 0 || fromColumn === void 0) { - this.disappear(); - return; + if (this.leftOverlay.needFullRender && this.topOverlay.needFullRender) { + topLeftCornerOverlay = this.topLeftCornerOverlay.clone.wtTable.holder; } - isMultiple = fromRow !== toRow || fromColumn !== toColumn; - fromTD = this.wot.wtTable.getCell(new _coords2.default(fromRow, fromColumn)); - toTD = isMultiple ? this.wot.wtTable.getCell(new _coords2.default(toRow, toColumn)) : fromTD; - fromOffset = (0, _element.offset)(fromTD); - toOffset = isMultiple ? (0, _element.offset)(toTD) : fromOffset; - containerOffset = (0, _element.offset)(this.wot.wtTable.TABLE); - - minTop = fromOffset.top; - height = toOffset.top + (0, _element.outerHeight)(toTD) - minTop; - minLeft = fromOffset.left; - width = toOffset.left + (0, _element.outerWidth)(toTD) - minLeft; - - top = minTop - containerOffset.top - 1; - left = minLeft - containerOffset.left - 1; - var style = (0, _element.getComputedStyle)(fromTD); - if (parseInt(style.borderTopWidth, 10) > 0) { - top += 1; - height = height > 0 ? height - 1 : 0; - } - if (parseInt(style.borderLeftWidth, 10) > 0) { - left += 1; - width = width > 0 ? width - 1 : 0; + if (this.leftOverlay.needFullRender && this.bottomOverlay.needFullRender) { + bottomLeftCornerOverlay = this.bottomLeftCornerOverlay.clone.wtTable.holder; } - this.topStyle.top = top + 'px'; - this.topStyle.left = left + 'px'; - this.topStyle.width = width + 'px'; - this.topStyle.display = 'block'; - - this.leftStyle.top = top + 'px'; - this.leftStyle.left = left + 'px'; - this.leftStyle.height = height + 'px'; - this.leftStyle.display = 'block'; + if (target === document) { + target = window; + } - var delta = Math.floor(this.settings.border.width / 2); + if (target === masterHorizontal || target === masterVertical) { + if (preventOverflow) { + tempScrollValue = (0, _element.getScrollLeft)(this.scrollableElement); + } else { + tempScrollValue = (0, _element.getScrollLeft)(target); + } - this.bottomStyle.top = top + height - delta + 'px'; - this.bottomStyle.left = left + 'px'; - this.bottomStyle.width = width + 'px'; - this.bottomStyle.display = 'block'; + // if scrolling the master table - populate the scroll values to both top and left overlays + this.horizontalScrolling = true; + this.overlayScrollPositions.master.left = tempScrollValue; + scrollValueChanged = true; - this.rightStyle.top = top + 'px'; - this.rightStyle.left = left + width - delta + 'px'; - this.rightStyle.height = height + 1 + 'px'; - this.rightStyle.display = 'block'; + if (this.pendingScrollCallbacks.master.left > 0) { + this.pendingScrollCallbacks.master.left--; + } else { + if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) { - if ((0, _browser.isMobileBrowser)() || !this.hasSetting(this.settings.border.cornerVisible) || this.isPartRange(toRow, toColumn)) { - this.cornerStyle.display = 'none'; - } else { - this.cornerStyle.top = top + height - 4 + 'px'; - this.cornerStyle.left = left + width - 4 + 'px'; - this.cornerStyle.borderRightWidth = this.cornerDefaultStyle.borderWidth; - this.cornerStyle.width = this.cornerDefaultStyle.width; + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.top.left++; + } - // Hide the fill handle, so the possible further adjustments won't force unneeded scrollbars. - this.cornerStyle.display = 'none'; + topOverlay.scrollLeft = tempScrollValue; + delegatedScroll = masterHorizontal !== window; + } - trimmingContainer = (0, _element.getTrimmingContainer)(this.wot.wtTable.TABLE); + if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) { - if (toColumn === this.wot.getSetting('totalColumns') - 1) { - cornerOverlappingContainer = toTD.offsetLeft + (0, _element.outerWidth)(toTD) + parseInt(this.cornerDefaultStyle.width, 10) / 2 >= (0, _element.innerWidth)(trimmingContainer); + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.bottom.left++; + } - if (cornerOverlappingContainer) { - this.cornerStyle.left = Math.floor(left + width - 3 - parseInt(this.cornerDefaultStyle.width, 10) / 2) + 'px'; - this.cornerStyle.borderRightWidth = 0; + bottomOverlay.scrollLeft = tempScrollValue; + delegatedScroll = masterHorizontal !== window; } } - if (toRow === this.wot.getSetting('totalRows') - 1) { - cornerOverlappingContainer = toTD.offsetTop + (0, _element.outerHeight)(toTD) + parseInt(this.cornerDefaultStyle.height, 10) / 2 >= (0, _element.innerHeight)(trimmingContainer); + tempScrollValue = (0, _element.getScrollTop)(target); - if (cornerOverlappingContainer) { - this.cornerStyle.top = Math.floor(top + height - 3 - parseInt(this.cornerDefaultStyle.height, 10) / 2) + 'px'; - this.cornerStyle.borderBottomWidth = 0; + this.verticalScrolling = true; + this.overlayScrollPositions.master.top = tempScrollValue; + scrollValueChanged = true; + + if (this.pendingScrollCallbacks.master.top > 0) { + this.pendingScrollCallbacks.master.top--; + } else if (leftOverlay && leftOverlay.scrollTop !== tempScrollValue) { + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.left.top++; } + + leftOverlay.scrollTop = tempScrollValue; + delegatedScroll = masterVertical !== window; } + } else if (target === bottomOverlay) { + tempScrollValue = (0, _element.getScrollLeft)(target); - this.cornerStyle.display = 'block'; - } + // if scrolling the bottom overlay - populate the horizontal scroll to the master table + this.horizontalScrolling = true; + this.overlayScrollPositions.bottom.left = tempScrollValue; + scrollValueChanged = true; - if ((0, _browser.isMobileBrowser)()) { - this.updateMultipleSelectionHandlesPosition(fromRow, fromColumn, top, left, width, height); - } - } + if (this.pendingScrollCallbacks.bottom.left > 0) { + this.pendingScrollCallbacks.bottom.left--; + } else { + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.master.left++; + } - /** - * Hide border - */ + masterHorizontal.scrollLeft = tempScrollValue; - }, { - key: 'disappear', - value: function disappear() { - this.topStyle.display = 'none'; - this.leftStyle.display = 'none'; - this.bottomStyle.display = 'none'; - this.rightStyle.display = 'none'; - this.cornerStyle.display = 'none'; + if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) { + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.top.left++; + } - if ((0, _browser.isMobileBrowser)()) { - this.selectionHandles.styles.topLeft.display = 'none'; - this.selectionHandles.styles.bottomRight.display = 'none'; - } - } + topOverlay.scrollLeft = tempScrollValue; + delegatedScroll = masterVertical !== window; + } + } - /** - * @param {Function} setting - * @returns {*} - */ + // "fake" scroll value calculated from the mousewheel event + if (fakeScrollValue !== null) { + scrollValueChanged = true; + masterVertical.scrollTop += fakeScrollValue; + } + } else if (target === topOverlay) { + tempScrollValue = (0, _element.getScrollLeft)(target); - }, { - key: 'hasSetting', - value: function hasSetting(setting) { - if (typeof setting === 'function') { - return setting(); - } + // if scrolling the top overlay - populate the horizontal scroll to the master table + this.horizontalScrolling = true; + this.overlayScrollPositions.top.left = tempScrollValue; + scrollValueChanged = true; - return !!setting; - } - }]); + if (this.pendingScrollCallbacks.top.left > 0) { + this.pendingScrollCallbacks.top.left--; + } else { - return Border; -}(); + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.master.left++; + } -exports.default = Border; + masterHorizontal.scrollLeft = tempScrollValue; + } -/***/ }), -/* 137 */ -/***/ (function(module, exports, __webpack_require__) { + // "fake" scroll value calculated from the mousewheel event + if (fakeScrollValue !== null) { + scrollValueChanged = true; + masterVertical.scrollTop += fakeScrollValue; + } -"use strict"; + if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) { + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.bottom.left++; + } + bottomOverlay.scrollLeft = tempScrollValue; + delegatedScroll = masterVertical !== window; + } + } else if (target === leftOverlay) { + tempScrollValue = (0, _element.getScrollTop)(target); -exports.__esModule = true; + // if scrolling the left overlay - populate the vertical scroll to the master table + if (this.overlayScrollPositions.left.top !== tempScrollValue) { + this.verticalScrolling = true; + this.overlayScrollPositions.left.top = tempScrollValue; + scrollValueChanged = true; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + if (this.pendingScrollCallbacks.left.top > 0) { + this.pendingScrollCallbacks.left.top--; + } else { + if (fakeScrollValue == null) { + this.pendingScrollCallbacks.master.top++; + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + masterVertical.scrollTop = tempScrollValue; + } + } -var privatePool = new WeakMap(); + // "fake" scroll value calculated from the mousewheel event + if (fakeScrollValue !== null) { + scrollValueChanged = true; + masterVertical.scrollLeft += fakeScrollValue; + } + } else if (target === topLeftCornerOverlay || target === bottomLeftCornerOverlay) { + if (fakeScrollValue !== null) { + scrollValueChanged = true; -/** - * Calculates indexes of columns to render OR columns that are visible. - * To redo the calculation, you need to create a new calculator. - * - * @class ViewportColumnsCalculator - */ + if (fakeScrollDirection === 'x') { + masterVertical.scrollLeft += fakeScrollValue; + } else if (fakeScrollDirection === 'y') { + masterVertical.scrollTop += fakeScrollValue; + } + } + } -var ViewportColumnsCalculator = function () { - _createClass(ViewportColumnsCalculator, null, [{ - key: 'DEFAULT_WIDTH', + if (!this.keyPressed && scrollValueChanged && event.type === 'scroll') { + if (this.delegatedScrollCallback) { + this.delegatedScrollCallback = false; + } else { + this.refreshAll(); + } - /** - * Default column width - * - * @type {Number} - */ - get: function get() { - return 50; + if (delegatedScroll) { + this.delegatedScrollCallback = true; + } + } } /** - * @param {Number} viewportWidth Width of the viewport - * @param {Number} scrollOffset Current horizontal scroll position of the viewport - * @param {Number} totalColumns Total number of rows - * @param {Function} columnWidthFn Function that returns the width of the column at a given index (in px) - * @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin) - * @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport - * @param {Boolean} stretchH - * @param {Function} [stretchingColumnWidthFn] Function that returns the new width of the stretched column. + * Synchronize overlay scrollbars with the master scrollbar */ - }]); - - function ViewportColumnsCalculator(viewportWidth, scrollOffset, totalColumns, columnWidthFn, overrideFn, onlyFullyVisible, stretchH) { - var stretchingColumnWidthFn = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : function (width) { - return width; - }; - - _classCallCheck(this, ViewportColumnsCalculator); - - privatePool.set(this, { - viewportWidth: viewportWidth, - scrollOffset: scrollOffset, - totalColumns: totalColumns, - columnWidthFn: columnWidthFn, - overrideFn: overrideFn, - onlyFullyVisible: onlyFullyVisible, - stretchingColumnWidthFn: stretchingColumnWidthFn - }); - - /** - * Number of rendered/visible columns - * - * @type {Number} - */ - this.count = 0; + }, { + key: 'syncScrollWithMaster', + value: function syncScrollWithMaster() { + var master = this.topOverlay.mainTableScrollableElement; + var scrollLeft = master.scrollLeft, + scrollTop = master.scrollTop; - /** - * Index of the first rendered/visible column (can be overwritten using overrideFn) - * - * @type {Number|null} - */ - this.startColumn = null; - /** - * Index of the last rendered/visible column (can be overwritten using overrideFn) - * - * @type {null} - */ - this.endColumn = null; + if (this.topOverlay.needFullRender) { + this.topOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; + } + if (this.bottomOverlay.needFullRender) { + this.bottomOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; + } + if (this.leftOverlay.needFullRender) { + this.leftOverlay.clone.wtTable.holder.scrollTop = scrollTop; + } + } /** - * Position of the first rendered/visible column (in px) - * - * @type {Number|null} + * Update the main scrollable elements for all the overlays. */ - this.startPosition = null; - - this.stretchAllRatio = 0; - this.stretchLastWidth = 0; - this.stretch = stretchH; - this.totalTargetWidth = 0; - this.needVerifyLastColumnWidth = true; - this.stretchAllColumnsWidth = []; - - this.calculate(); - } - - /** - * Calculates viewport - */ - - - _createClass(ViewportColumnsCalculator, [{ - key: 'calculate', - value: function calculate() { - var sum = 0; - var needReverse = true; - var startPositions = []; - var columnWidth = void 0; - - var priv = privatePool.get(this); - var onlyFullyVisible = priv.onlyFullyVisible; - var overrideFn = priv.overrideFn; - var scrollOffset = priv.scrollOffset; - var totalColumns = priv.totalColumns; - var viewportWidth = priv.viewportWidth; - for (var i = 0; i < totalColumns; i++) { - columnWidth = this._getColumnWidth(i); + }, { + key: 'updateMainScrollableElements', + value: function updateMainScrollableElements() { + this.deregisterListeners(); - if (sum <= scrollOffset && !onlyFullyVisible) { - this.startColumn = i; - } + this.leftOverlay.updateMainScrollableElement(); + this.topOverlay.updateMainScrollableElement(); - // +1 pixel for row header width compensation for horizontal scroll > 0 - var compensatedViewportWidth = scrollOffset > 0 ? viewportWidth + 1 : viewportWidth; + if (this.bottomOverlay.needFullRender) { + this.bottomOverlay.updateMainScrollableElement(); + } - if (sum >= scrollOffset && sum + columnWidth <= scrollOffset + compensatedViewportWidth) { - if (this.startColumn == null) { - this.startColumn = i; - } - this.endColumn = i; - } - startPositions.push(sum); - sum += columnWidth; + this.scrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE); - if (!onlyFullyVisible) { - this.endColumn = i; - } - if (sum >= scrollOffset + viewportWidth) { - needReverse = false; - break; - } - } + this.registerListeners(); + } - if (this.endColumn === totalColumns - 1 && needReverse) { - this.startColumn = this.endColumn; + /** + * + */ - while (this.startColumn > 0) { - var viewportSum = startPositions[this.endColumn] + columnWidth - startPositions[this.startColumn - 1]; + }, { + key: 'destroy', + value: function destroy() { + this.eventManager.destroy(); + this.topOverlay.destroy(); - if (viewportSum <= viewportWidth || !onlyFullyVisible) { - this.startColumn--; - } - if (viewportSum > viewportWidth) { - break; - } - } + if (this.bottomOverlay.clone) { + this.bottomOverlay.destroy(); } + this.leftOverlay.destroy(); - if (this.startColumn !== null && overrideFn) { - overrideFn(this); + if (this.topLeftCornerOverlay) { + this.topLeftCornerOverlay.destroy(); } - this.startPosition = startPositions[this.startColumn]; - if (this.startPosition == void 0) { - this.startPosition = null; + if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) { + this.bottomLeftCornerOverlay.destroy(); } - if (this.startColumn !== null) { - this.count = this.endColumn - this.startColumn + 1; + + if (this.debug) { + this.debug.destroy(); } + this.destroyed = true; } /** - * Recalculate columns stretching. - * - * @param {Number} totalWidth + * @param {Boolean} [fastDraw=false] */ }, { - key: 'refreshStretching', - value: function refreshStretching(totalWidth) { - if (this.stretch === 'none') { - return; - } - this.totalTargetWidth = totalWidth; - - var priv = privatePool.get(this); - var totalColumns = priv.totalColumns; - var sumAll = 0; + key: 'refresh', + value: function refresh() { + var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - for (var i = 0; i < totalColumns; i++) { - var columnWidth = this._getColumnWidth(i); - var permanentColumnWidth = priv.stretchingColumnWidthFn(void 0, i); + if (this.topOverlay.areElementSizesAdjusted && this.leftOverlay.areElementSizesAdjusted) { + var container = this.wot.wtTable.wtRootElement.parentNode || this.wot.wtTable.wtRootElement; + var width = container.clientWidth; + var height = container.clientHeight; - if (typeof permanentColumnWidth === 'number') { - totalWidth -= permanentColumnWidth; - } else { - sumAll += columnWidth; + if (width !== this.spreaderLastSize.width || height !== this.spreaderLastSize.height) { + this.spreaderLastSize.width = width; + this.spreaderLastSize.height = height; + this.adjustElementsSize(); } } - var remainingSize = totalWidth - sumAll; - - if (this.stretch === 'all' && remainingSize > 0) { - this.stretchAllRatio = totalWidth / sumAll; - this.stretchAllColumnsWidth = []; - this.needVerifyLastColumnWidth = true; - } else if (this.stretch === 'last' && totalWidth !== Infinity) { - var _columnWidth = this._getColumnWidth(totalColumns - 1); - var lastColumnWidth = remainingSize + _columnWidth; - this.stretchLastWidth = lastColumnWidth >= 0 ? lastColumnWidth : _columnWidth; + if (this.bottomOverlay.clone) { + this.bottomOverlay.refresh(fastDraw); } - } - /** - * Get stretched column width based on stretchH (all or last) setting passed in handsontable instance. - * - * @param {Number} column - * @param {Number} baseWidth - * @returns {Number|null} - */ + this.leftOverlay.refresh(fastDraw); + this.topOverlay.refresh(fastDraw); - }, { - key: 'getStretchedColumnWidth', - value: function getStretchedColumnWidth(column, baseWidth) { - var result = null; + if (this.topLeftCornerOverlay) { + this.topLeftCornerOverlay.refresh(fastDraw); + } - if (this.stretch === 'all' && this.stretchAllRatio !== 0) { - result = this._getStretchedAllColumnWidth(column, baseWidth); - } else if (this.stretch === 'last' && this.stretchLastWidth !== 0) { - result = this._getStretchedLastColumnWidth(column); + if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) { + this.bottomLeftCornerOverlay.refresh(fastDraw); } - return result; + if (this.debug) { + this.debug.refresh(fastDraw); + } } /** - * @param {Number} column - * @param {Number} baseWidth - * @returns {Number} - * @private + * Adjust overlays elements size and master table size + * + * @param {Boolean} [force=false] */ }, { - key: '_getStretchedAllColumnWidth', - value: function _getStretchedAllColumnWidth(column, baseWidth) { - var sumRatioWidth = 0; - var priv = privatePool.get(this); - var totalColumns = priv.totalColumns; + key: 'adjustElementsSize', + value: function adjustElementsSize() { + var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - if (!this.stretchAllColumnsWidth[column]) { - var stretchedWidth = Math.round(baseWidth * this.stretchAllRatio); - var newStretchedWidth = priv.stretchingColumnWidthFn(stretchedWidth, column); + var totalColumns = this.wot.getSetting('totalColumns'); + var totalRows = this.wot.getSetting('totalRows'); + var headerRowSize = this.wot.wtViewport.getRowHeaderWidth(); + var headerColumnSize = this.wot.wtViewport.getColumnHeaderHeight(); + var hiderStyle = this.wot.wtTable.hider.style; - if (newStretchedWidth === void 0) { - this.stretchAllColumnsWidth[column] = stretchedWidth; - } else { - this.stretchAllColumnsWidth[column] = isNaN(newStretchedWidth) ? this._getColumnWidth(column) : newStretchedWidth; - } - } + hiderStyle.width = headerRowSize + this.leftOverlay.sumCellSizes(0, totalColumns) + 'px'; + hiderStyle.height = headerColumnSize + this.topOverlay.sumCellSizes(0, totalRows) + 1 + 'px'; - if (this.stretchAllColumnsWidth.length === totalColumns && this.needVerifyLastColumnWidth) { - this.needVerifyLastColumnWidth = false; + this.topOverlay.adjustElementsSize(force); + this.leftOverlay.adjustElementsSize(force); - for (var i = 0; i < this.stretchAllColumnsWidth.length; i++) { - sumRatioWidth += this.stretchAllColumnsWidth[i]; - } - if (sumRatioWidth !== this.totalTargetWidth) { - this.stretchAllColumnsWidth[this.stretchAllColumnsWidth.length - 1] += this.totalTargetWidth - sumRatioWidth; - } + if (this.bottomOverlay.clone) { + this.bottomOverlay.adjustElementsSize(force); } - - return this.stretchAllColumnsWidth[column]; } /** - * @param {Number} column - * @returns {Number|null} - * @private + * */ }, { - key: '_getStretchedLastColumnWidth', - value: function _getStretchedLastColumnWidth(column) { - var priv = privatePool.get(this); - var totalColumns = priv.totalColumns; + key: 'applyToDOM', + value: function applyToDOM() { + if (!this.topOverlay.areElementSizesAdjusted || !this.leftOverlay.areElementSizesAdjusted) { + this.adjustElementsSize(); + } + this.topOverlay.applyToDOM(); - if (column === totalColumns - 1) { - return this.stretchLastWidth; + if (this.bottomOverlay.clone) { + this.bottomOverlay.applyToDOM(); } - return null; + this.leftOverlay.applyToDOM(); } /** - * @param {Number} column Column index. - * @returns {Number} - * @private + * Get the parent overlay of the provided element. + * + * @param {HTMLElement} element + * @returns {Object|null} */ }, { - key: '_getColumnWidth', - value: function _getColumnWidth(column) { - var width = privatePool.get(this).columnWidthFn(column); - - if (width === void 0) { - width = ViewportColumnsCalculator.DEFAULT_WIDTH; + key: 'getParentOverlay', + value: function getParentOverlay(element) { + if (!element) { + return null; } - return width; + var overlays = [this.topOverlay, this.leftOverlay, this.bottomOverlay, this.topLeftCornerOverlay, this.bottomLeftCornerOverlay]; + var result = null; + + (0, _array.arrayEach)(overlays, function (elem, i) { + if (!elem) { + return; + } + + if (elem.clone && elem.clone.wtTable.TABLE.contains(element)) { + result = elem.clone; + } + }); + + return result; } }]); - return ViewportColumnsCalculator; + return Overlays; }(); -exports.default = ViewportColumnsCalculator; +exports.default = Overlays; /***/ }), -/* 138 */ +/* 162 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -36346,177 +35593,288 @@ exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var _element = __webpack_require__(0); -var privatePool = new WeakMap(); +var _number = __webpack_require__(6); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * Calculates indexes of rows to render OR rows that are visible. - * To redo the calculation, you need to create a new calculator. - * - * @class ViewportRowsCalculator + * @class Scroll */ +var Scroll = function () { + /** + * @param {Walkontable} wotInstance + */ + function Scroll(wotInstance) { + _classCallCheck(this, Scroll); -var ViewportRowsCalculator = function () { - _createClass(ViewportRowsCalculator, null, [{ - key: "DEFAULT_HEIGHT", + this.wot = wotInstance; - /** - * Default row height - * - * @type {Number} - */ - get: function get() { - return 23; - } + // legacy support + this.instance = wotInstance; + } - /** - * @param {Number} viewportHeight Height of the viewport - * @param {Number} scrollOffset Current vertical scroll position of the viewport - * @param {Number} totalRows Total number of rows - * @param {Function} rowHeightFn Function that returns the height of the row at a given index (in px) - * @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin) - * @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport - * @param {Number} horizontalScrollbarHeight - */ + /** + * Scrolls viewport to a cell by minimum number of cells + * + * @param {CellCoords} coords + */ - }]); - function ViewportRowsCalculator(viewportHeight, scrollOffset, totalRows, rowHeightFn, overrideFn, onlyFullyVisible, horizontalScrollbarHeight) { - _classCallCheck(this, ViewportRowsCalculator); + _createClass(Scroll, [{ + key: 'scrollViewport', + value: function scrollViewport(coords) { + if (!this.wot.drawn) { + return; + } - privatePool.set(this, { - viewportHeight: viewportHeight, - scrollOffset: scrollOffset, - totalRows: totalRows, - rowHeightFn: rowHeightFn, - overrideFn: overrideFn, - onlyFullyVisible: onlyFullyVisible, - horizontalScrollbarHeight: horizontalScrollbarHeight - }); + var _getVariables2 = this._getVariables(), + topOverlay = _getVariables2.topOverlay, + leftOverlay = _getVariables2.leftOverlay, + totalRows = _getVariables2.totalRows, + totalColumns = _getVariables2.totalColumns, + fixedRowsTop = _getVariables2.fixedRowsTop, + fixedRowsBottom = _getVariables2.fixedRowsBottom, + fixedColumnsLeft = _getVariables2.fixedColumnsLeft; - /** - * Number of rendered/visible rows - * - * @type {Number} - */ - this.count = 0; + if (coords.row < 0 || coords.row > Math.max(totalRows - 1, 0)) { + throw new Error('row ' + coords.row + ' does not exist'); + } + + if (coords.col < 0 || coords.col > Math.max(totalColumns - 1, 0)) { + throw new Error('column ' + coords.col + ' does not exist'); + } + + if (coords.row >= fixedRowsTop && coords.row < this.getFirstVisibleRow()) { + topOverlay.scrollTo(coords.row); + } else if (coords.row > this.getLastVisibleRow() && coords.row < totalRows - fixedRowsBottom) { + topOverlay.scrollTo(coords.row, true); + } + + if (coords.col >= fixedColumnsLeft && coords.col < this.getFirstVisibleColumn()) { + leftOverlay.scrollTo(coords.col); + } else if (coords.col > this.getLastVisibleColumn()) { + leftOverlay.scrollTo(coords.col, true); + } + } /** - * Index of the first rendered/visible row (can be overwritten using overrideFn) + * Get first visible row based on virtual dom and how table is visible in browser window viewport. * - * @type {Number|null} + * @returns {Number} */ - this.startRow = null; + + }, { + key: 'getFirstVisibleRow', + value: function getFirstVisibleRow() { + var _getVariables3 = this._getVariables(), + topOverlay = _getVariables3.topOverlay, + wtTable = _getVariables3.wtTable, + wtViewport = _getVariables3.wtViewport, + totalRows = _getVariables3.totalRows, + fixedRowsTop = _getVariables3.fixedRowsTop; + + var firstVisibleRow = wtTable.getFirstVisibleRow(); + + if (topOverlay.mainTableScrollableElement === window) { + var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); + var totalTableHeight = (0, _element.innerHeight)(wtTable.hider); + var windowHeight = (0, _element.innerHeight)(window); + var windowScrollTop = (0, _element.getScrollTop)(window); + + // Only calculate firstVisibleRow when table didn't filled (from up) whole viewport space + if (rootElementOffset.top + totalTableHeight - windowHeight <= windowScrollTop) { + var rowsHeight = wtViewport.getColumnHeaderHeight(); + + rowsHeight += topOverlay.sumCellSizes(0, fixedRowsTop); + + (0, _number.rangeEachReverse)(totalRows, 1, function (row) { + rowsHeight += topOverlay.sumCellSizes(row - 1, row); + + if (rootElementOffset.top + totalTableHeight - rowsHeight <= windowScrollTop) { + // Return physical row + 1 + firstVisibleRow = row; + + return false; + } + }); + } + } + + return firstVisibleRow; + } /** - * Index of the last rendered/visible row (can be overwritten using overrideFn) + * Get last visible row based on virtual dom and how table is visible in browser window viewport. * - * @type {null} + * @returns {Number} */ - this.endRow = null; + + }, { + key: 'getLastVisibleRow', + value: function getLastVisibleRow() { + var _getVariables4 = this._getVariables(), + topOverlay = _getVariables4.topOverlay, + wtTable = _getVariables4.wtTable, + wtViewport = _getVariables4.wtViewport, + totalRows = _getVariables4.totalRows; + + var lastVisibleRow = wtTable.getLastVisibleRow(); + + if (topOverlay.mainTableScrollableElement === window) { + var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); + var windowHeight = (0, _element.innerHeight)(window); + var windowScrollTop = (0, _element.getScrollTop)(window); + + // Only calculate lastVisibleRow when table didn't filled (from bottom) whole viewport space + if (rootElementOffset.top > windowScrollTop) { + var rowsHeight = wtViewport.getColumnHeaderHeight(); + + (0, _number.rangeEach)(1, totalRows, function (row) { + rowsHeight += topOverlay.sumCellSizes(row - 1, row); + + if (rootElementOffset.top + rowsHeight - windowScrollTop >= windowHeight) { + // Return physical row - 1 (-2 because rangeEach gives row index + 1 - sumCellSizes requirements) + lastVisibleRow = row - 2; + + return false; + } + }); + } + } + + return lastVisibleRow; + } /** - * Position of the first rendered/visible row (in px) + * Get first visible column based on virtual dom and how table is visible in browser window viewport. * - * @type {Number|null} + * @returns {Number} */ - this.startPosition = null; - this.calculate(); - } + }, { + key: 'getFirstVisibleColumn', + value: function getFirstVisibleColumn() { + var _getVariables5 = this._getVariables(), + leftOverlay = _getVariables5.leftOverlay, + wtTable = _getVariables5.wtTable, + wtViewport = _getVariables5.wtViewport, + totalColumns = _getVariables5.totalColumns, + fixedColumnsLeft = _getVariables5.fixedColumnsLeft; - /** - * Calculates viewport - */ + var firstVisibleColumn = wtTable.getFirstVisibleColumn(); + if (leftOverlay.mainTableScrollableElement === window) { + var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); + var totalTableWidth = (0, _element.innerWidth)(wtTable.hider); + var windowWidth = (0, _element.innerWidth)(window); + var windowScrollLeft = (0, _element.getScrollLeft)(window); - _createClass(ViewportRowsCalculator, [{ - key: "calculate", - value: function calculate() { - var sum = 0; - var needReverse = true; - var startPositions = []; + // Only calculate firstVisibleColumn when table didn't filled (from left) whole viewport space + if (rootElementOffset.left + totalTableWidth - windowWidth <= windowScrollLeft) { + var columnsWidth = wtViewport.getRowHeaderWidth(); - var priv = privatePool.get(this); - var onlyFullyVisible = priv.onlyFullyVisible; - var overrideFn = priv.overrideFn; - var rowHeightFn = priv.rowHeightFn; - var scrollOffset = priv.scrollOffset; - var totalRows = priv.totalRows; - var viewportHeight = priv.viewportHeight; - var horizontalScrollbarHeight = priv.horizontalScrollbarHeight || 0; - var rowHeight = void 0; + (0, _number.rangeEachReverse)(totalColumns, 1, function (column) { + columnsWidth += leftOverlay.sumCellSizes(column - 1, column); - // Calculate the number (start and end index) of rows needed - for (var i = 0; i < totalRows; i++) { - rowHeight = rowHeightFn(i); + if (rootElementOffset.left + totalTableWidth - columnsWidth <= windowScrollLeft) { + // Return physical column + 1 + firstVisibleColumn = column; - if (rowHeight === undefined) { - rowHeight = ViewportRowsCalculator.DEFAULT_HEIGHT; - } - if (sum <= scrollOffset && !onlyFullyVisible) { - this.startRow = i; + return false; + } + }); } + } - // the row is within the "visible range" - if (sum >= scrollOffset && sum + rowHeight <= scrollOffset + viewportHeight - horizontalScrollbarHeight) { - if (this.startRow === null) { - this.startRow = i; - } - this.endRow = i; - } - startPositions.push(sum); - sum += rowHeight; + return firstVisibleColumn; + } - if (!onlyFullyVisible) { - this.endRow = i; - } - if (sum >= scrollOffset + viewportHeight - horizontalScrollbarHeight) { - needReverse = false; - break; - } - } + /** + * Get last visible column based on virtual dom and how table is visible in browser window viewport. + * + * @returns {Number} + */ - // If the estimation has reached the last row and there is still some space available in the viewport, - // we need to render in reverse in order to fill the whole viewport with rows - if (this.endRow === totalRows - 1 && needReverse) { - this.startRow = this.endRow; + }, { + key: 'getLastVisibleColumn', + value: function getLastVisibleColumn() { + var _getVariables6 = this._getVariables(), + leftOverlay = _getVariables6.leftOverlay, + wtTable = _getVariables6.wtTable, + wtViewport = _getVariables6.wtViewport, + totalColumns = _getVariables6.totalColumns; - while (this.startRow > 0) { - // rowHeight is the height of the last row - var viewportSum = startPositions[this.endRow] + rowHeight - startPositions[this.startRow - 1]; + var lastVisibleColumn = wtTable.getLastVisibleColumn(); - if (viewportSum <= viewportHeight - horizontalScrollbarHeight || !onlyFullyVisible) { - this.startRow--; - } - if (viewportSum >= viewportHeight - horizontalScrollbarHeight) { - break; - } + if (leftOverlay.mainTableScrollableElement === window) { + var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); + var windowWidth = (0, _element.innerWidth)(window); + var windowScrollLeft = (0, _element.getScrollLeft)(window); + + // Only calculate lastVisibleColumn when table didn't filled (from right) whole viewport space + if (rootElementOffset.left > windowScrollLeft) { + var columnsWidth = wtViewport.getRowHeaderWidth(); + + (0, _number.rangeEach)(1, totalColumns, function (column) { + columnsWidth += leftOverlay.sumCellSizes(column - 1, column); + + if (rootElementOffset.left + columnsWidth - windowScrollLeft >= windowWidth) { + // Return physical column - 1 (-2 because rangeEach gives column index + 1 - sumCellSizes requirements) + lastVisibleColumn = column - 2; + + return false; + } + }); } } - if (this.startRow !== null && overrideFn) { - overrideFn(this); - } - this.startPosition = startPositions[this.startRow]; + return lastVisibleColumn; + } + + /** + * Returns collection of variables used to rows and columns visibility calculations. + * + * @returns {Object} + * @private + */ + + }, { + key: '_getVariables', + value: function _getVariables() { + var wot = this.wot; + var topOverlay = wot.wtOverlays.topOverlay; + var leftOverlay = wot.wtOverlays.leftOverlay; + var wtTable = wot.wtTable; + var wtViewport = wot.wtViewport; + var totalRows = wot.getSetting('totalRows'); + var totalColumns = wot.getSetting('totalColumns'); + var fixedRowsTop = wot.getSetting('fixedRowsTop'); + var fixedRowsBottom = wot.getSetting('fixedRowsBottom'); + var fixedColumnsLeft = wot.getSetting('fixedColumnsLeft'); - if (this.startPosition == void 0) { - this.startPosition = null; - } - if (this.startRow !== null) { - this.count = this.endRow - this.startRow + 1; - } + return { + topOverlay: topOverlay, + leftOverlay: leftOverlay, + wtTable: wtTable, + wtViewport: wtViewport, + totalRows: totalRows, + totalColumns: totalColumns, + fixedRowsTop: fixedRowsTop, + fixedRowsBottom: fixedRowsBottom, + fixedColumnsLeft: fixedColumnsLeft + }; } }]); - return ViewportRowsCalculator; + return Scroll; }(); -exports.default = ViewportRowsCalculator; +exports.default = Scroll; /***/ }), -/* 139 */ +/* 163 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -36530,818 +35888,950 @@ var _element = __webpack_require__(0); var _object = __webpack_require__(1); -var _string = __webpack_require__(27); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var _event = __webpack_require__(140); +/** + * @class Settings + */ +var Settings = function () { + /** + * @param {Walkontable} wotInstance + * @param {Object} settings + */ + function Settings(wotInstance, settings) { + var _this = this; -var _event2 = _interopRequireDefault(_event); + _classCallCheck(this, Settings); -var _overlays = __webpack_require__(143); + this.wot = wotInstance; -var _overlays2 = _interopRequireDefault(_overlays); + // legacy support + this.instance = wotInstance; -var _scroll = __webpack_require__(144); + // default settings. void 0 means it is required, null means it can be empty + this.defaults = { + table: void 0, + debug: false, // shows WalkontableDebugOverlay -var _scroll2 = _interopRequireDefault(_scroll); + // presentation mode + externalRowCalculator: false, + stretchH: 'none', // values: all, last, none + currentRowClassName: null, + currentColumnClassName: null, + preventOverflow: function preventOverflow() { + return false; + }, -var _settings = __webpack_require__(145); -var _settings2 = _interopRequireDefault(_settings); + // data source + data: void 0, + freezeOverlays: false, + fixedColumnsLeft: 0, + fixedRowsTop: 0, + fixedRowsBottom: 0, + minSpareRows: 0, -var _table = __webpack_require__(146); + // this must be array of functions: [function (row, TH) {}] + rowHeaders: function rowHeaders() { + return []; + }, -var _table2 = _interopRequireDefault(_table); -var _viewport = __webpack_require__(148); + // this must be array of functions: [function (column, TH) {}] + columnHeaders: function columnHeaders() { + return []; + }, -var _viewport2 = _interopRequireDefault(_viewport); + totalRows: void 0, + totalColumns: void 0, + cellRenderer: function cellRenderer(row, column, TD) { + var cellData = _this.getSetting('data', row, column); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + (0, _element.fastInnerText)(TD, cellData === void 0 || cellData === null ? '' : cellData); + }, -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + // columnWidth: 50, + columnWidth: function columnWidth(col) { + // return undefined means use default size for the rendered cell content + }, + rowHeight: function rowHeight(row) { + // return undefined means use default size for the rendered cell content + }, -/** - * @class Walkontable - */ -var Walkontable = function () { - /** - * @param {Object} settings - */ - function Walkontable(settings) { - _classCallCheck(this, Walkontable); + defaultRowHeight: 23, + defaultColumnWidth: 50, + selections: null, + hideBorderOnMouseDownOver: false, + viewportRowCalculatorOverride: null, + viewportColumnCalculatorOverride: null, - var originalHeaders = []; + // callbacks + onCellMouseDown: null, + onCellMouseOver: null, + onCellMouseOut: null, + onCellMouseUp: null, - // this is the namespace for global events - this.guid = 'wt_' + (0, _string.randomString)(); + // onCellMouseOut: null, + onCellDblClick: null, + onCellCornerMouseDown: null, + onCellCornerDblClick: null, + beforeDraw: null, + onDraw: null, + onBeforeDrawBorders: null, + onScrollVertically: null, + onScrollHorizontally: null, + onBeforeTouchScroll: null, + onAfterMomentumScroll: null, + onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(width) { + return width; + }, + onModifyRowHeaderWidth: null, - // bootstrap from settings - if (settings.cloneSource) { - this.cloneSource = settings.cloneSource; - this.cloneOverlay = settings.cloneOverlay; - this.wtSettings = settings.cloneSource.wtSettings; - this.wtTable = new _table2.default(this, settings.table, settings.wtRootElement); - this.wtScroll = new _scroll2.default(this); - this.wtViewport = settings.cloneSource.wtViewport; - this.wtEvent = new _event2.default(this); - this.selections = this.cloneSource.selections; - } else { - this.wtSettings = new _settings2.default(this, settings); - this.wtTable = new _table2.default(this, settings.table); - this.wtScroll = new _scroll2.default(this); - this.wtViewport = new _viewport2.default(this); - this.wtEvent = new _event2.default(this); - this.selections = this.getSetting('selections'); - this.wtOverlays = new _overlays2.default(this); - this.exportSettingsAsClassNames(); - } + // constants + scrollbarWidth: 10, + scrollbarHeight: 10, - // find original headers - if (this.wtTable.THEAD.childNodes.length && this.wtTable.THEAD.childNodes[0].childNodes.length) { - for (var c = 0, clen = this.wtTable.THEAD.childNodes[0].childNodes.length; c < clen; c++) { - originalHeaders.push(this.wtTable.THEAD.childNodes[0].childNodes[c].innerHTML); - } - if (!this.getSetting('columnHeaders').length) { - this.update('columnHeaders', [function (column, TH) { - (0, _element.fastInnerText)(TH, originalHeaders[column]); - }]); + renderAllRows: false, + groups: false, + rowHeaderWidth: null, + columnHeaderHeight: null, + headerClassName: null + }; + + // reference to settings + this.settings = {}; + + for (var i in this.defaults) { + if ((0, _object.hasOwnProperty)(this.defaults, i)) { + if (settings[i] !== void 0) { + this.settings[i] = settings[i]; + } else if (this.defaults[i] === void 0) { + throw new Error('A required setting "' + i + '" was not provided'); + } else { + this.settings[i] = this.defaults[i]; + } } } - this.drawn = false; - this.drawInterrupted = false; } /** - * Force rerender of Walkontable + * Update settings * - * @param {Boolean} [fastDraw=false] When `true`, try to refresh only the positions of borders without rerendering - * the data. It will only work if Table.draw() does not force - * rendering anyway + * @param {Object} settings + * @param {*} value * @returns {Walkontable} */ - _createClass(Walkontable, [{ - key: 'draw', - value: function draw() { - var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - - this.drawInterrupted = false; - - if (!fastDraw && !(0, _element.isVisible)(this.wtTable.TABLE)) { - // draw interrupted because TABLE is not visible - this.drawInterrupted = true; + _createClass(Settings, [{ + key: 'update', + value: function update(settings, value) { + if (value === void 0) { + // settings is object + for (var i in settings) { + if ((0, _object.hasOwnProperty)(settings, i)) { + this.settings[i] = settings[i]; + } + } } else { - this.wtTable.draw(fastDraw); + // if value is defined then settings is the key + this.settings[settings] = value; } - - return this; + return this.wot; } /** - * Returns the TD at coords. If topmost is set to true, returns TD from the topmost overlay layer, - * if not set or set to false, returns TD from the master table. + * Get setting by name * - * @param {CellCoords} coords - * @param {Boolean} [topmost=false] - * @returns {Object} + * @param {String} key + * @param {*} param1 + * @param {*} param2 + * @param {*} param3 + * @param {*} param4 + * @returns {*} */ }, { - key: 'getCell', - value: function getCell(coords) { - var topmost = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (!topmost) { - return this.wtTable.getCell(coords); - } - - var totalRows = this.wtSettings.getSetting('totalRows'); - var fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop'); - var fixedRowsBottom = this.wtSettings.getSetting('fixedRowsBottom'); - var fixedColumns = this.wtSettings.getSetting('fixedColumnsLeft'); - - if (coords.row < fixedRowsTop && coords.col < fixedColumns) { - return this.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell(coords); - } else if (coords.row < fixedRowsTop) { - return this.wtOverlays.topOverlay.clone.wtTable.getCell(coords); - } else if (coords.col < fixedColumns && coords.row >= totalRows - fixedRowsBottom) { - if (this.wtOverlays.bottomLeftCornerOverlay && this.wtOverlays.bottomLeftCornerOverlay.clone) { - return this.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.getCell(coords); - } - } else if (coords.col < fixedColumns) { - return this.wtOverlays.leftOverlay.clone.wtTable.getCell(coords); - } else if (coords.row < totalRows && coords.row > totalRows - fixedRowsBottom) { - if (this.wtOverlays.bottomOverlay && this.wtOverlays.bottomOverlay.clone) { - return this.wtOverlays.bottomOverlay.clone.wtTable.getCell(coords); - } + key: 'getSetting', + value: function getSetting(key, param1, param2, param3, param4) { + if (typeof this.settings[key] === 'function') { + // this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips + return this.settings[key](param1, param2, param3, param4); + } else if (param1 !== void 0 && Array.isArray(this.settings[key])) { + // perhaps this can be removed, it is only used in tests + return this.settings[key][param1]; } - return this.wtTable.getCell(coords); + return this.settings[key]; } /** - * @param {Object} settings - * @param {*} value - * @returns {Walkontable} + * Checks if setting exists + * + * @param {Boolean} key + * @returns {Boolean} */ }, { - key: 'update', - value: function update(settings, value) { - return this.wtSettings.update(settings, value); + key: 'has', + value: function has(key) { + return !!this.settings[key]; } + }]); - /** - * Scroll the viewport to a row at the given index in the data source - * - * @param {Number} row - * @returns {Walkontable} - */ + return Settings; +}(); - }, { - key: 'scrollVertical', - value: function scrollVertical(row) { - this.wtOverlays.topOverlay.scrollTo(row); - this.getSetting('onScrollVertically'); +exports.default = Settings; - return this; - } +/***/ }), +/* 164 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Scroll the viewport to a column at the given index in the data source - * - * @param {Number} column - * @returns {Walkontable} - */ +"use strict"; - }, { - key: 'scrollHorizontal', - value: function scrollHorizontal(column) { - this.wtOverlays.leftOverlay.scrollTo(column); - this.getSetting('onScrollHorizontally'); - return this; - } +exports.__esModule = true; - /** - * Scrolls the viewport to a cell (rerenders if needed) - * - * @param {CellCoords} coords - * @returns {Walkontable} - */ +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - }, { - key: 'scrollViewport', - value: function scrollViewport(coords) { - this.wtScroll.scrollViewport(coords); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - return this; - } +var _element = __webpack_require__(0); - /** - * @returns {Array} - */ +var _function = __webpack_require__(35); - }, { - key: 'getViewport', - value: function getViewport() { - return [this.wtTable.getFirstVisibleRow(), this.wtTable.getFirstVisibleColumn(), this.wtTable.getLastVisibleRow(), this.wtTable.getLastVisibleColumn()]; - } +var _coords = __webpack_require__(49); - /** - * Get overlay name - * - * @returns {String} - */ +var _coords2 = _interopRequireDefault(_coords); - }, { - key: 'getOverlayName', - value: function getOverlayName() { - return this.cloneOverlay ? this.cloneOverlay.type : 'master'; - } +var _range = __webpack_require__(79); - /** - * Check overlay type of this Walkontable instance. - * - * @param {String} name Clone type @see {Overlay.CLONE_TYPES}. - * @returns {Boolean} - */ +var _range2 = _interopRequireDefault(_range); - }, { - key: 'isOverlayName', - value: function isOverlayName(name) { - if (this.cloneOverlay) { - return this.cloneOverlay.type === name; - } +var _column = __webpack_require__(157); - return false; - } +var _column2 = _interopRequireDefault(_column); - /** - * Export settings as class names added to the parent element of the table. - */ +var _row = __webpack_require__(158); - }, { - key: 'exportSettingsAsClassNames', - value: function exportSettingsAsClassNames() { - var _this = this; +var _row2 = _interopRequireDefault(_row); - var toExport = { - rowHeaders: ['array'], - columnHeaders: ['array'] - }; - var allClassNames = []; - var newClassNames = []; +var _tableRenderer = __webpack_require__(165); - (0, _object.objectEach)(toExport, function (optionType, key) { - if (optionType.indexOf('array') > -1 && _this.getSetting(key).length) { - newClassNames.push('ht' + (0, _string.toUpperCaseFirst)(key)); - } - allClassNames.push('ht' + (0, _string.toUpperCaseFirst)(key)); - }); - (0, _element.removeClass)(this.wtTable.wtRootElement.parentNode, allClassNames); - (0, _element.addClass)(this.wtTable.wtRootElement.parentNode, newClassNames); - } +var _tableRenderer2 = _interopRequireDefault(_tableRenderer); - /** - * Get/Set Walkontable instance setting - * - * @param {String} key - * @param {*} [param1] - * @param {*} [param2] - * @param {*} [param3] - * @param {*} [param4] - * @returns {*} - */ +var _base = __webpack_require__(31); - }, { - key: 'getSetting', - value: function getSetting(key, param1, param2, param3, param4) { - // this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips - return this.wtSettings.getSetting(key, param1, param2, param3, param4); - } +var _base2 = _interopRequireDefault(_base); - /** - * Checks if setting exists - * - * @param {String} key - * @returns {Boolean} - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - }, { - key: 'hasSetting', - value: function hasSetting(key) { - return this.wtSettings.has(key); - } +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - /** - * Destroy instance - */ +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - }, { - key: 'destroy', - value: function destroy() { - this.wtOverlays.destroy(); - this.wtEvent.destroy(); - } - }]); +/** + * + */ +var Table = function () { + /** + * @param {Walkontable} wotInstance + * @param {HTMLTableElement} table + */ + function Table(wotInstance, table) { + var _this = this; - return Walkontable; -}(); + _classCallCheck(this, Table); -exports.default = Walkontable; + this.wot = wotInstance; -/***/ }), -/* 140 */ -/***/ (function(module, exports, __webpack_require__) { + // legacy support + this.instance = this.wot; + this.TABLE = table; + this.TBODY = null; + this.THEAD = null; + this.COLGROUP = null; + this.tableOffset = 0; + this.holderOffset = 0; -"use strict"; + (0, _element.removeTextNodes)(this.TABLE); + + this.spreader = this.createSpreader(this.TABLE); + this.hider = this.createHider(this.spreader); + this.holder = this.createHolder(this.hider); + + this.wtRootElement = this.holder.parentNode; + this.alignOverlaysWithTrimmingContainer(); + this.fixTableDomTree(); + + this.colgroupChildrenLength = this.COLGROUP.childNodes.length; + this.theadChildrenLength = this.THEAD.firstChild ? this.THEAD.firstChild.childNodes.length : 0; + this.tbodyChildrenLength = this.TBODY.childNodes.length; + + this.rowFilter = null; + this.columnFilter = null; + this.correctHeaderWidth = false; + + var origRowHeaderWidth = this.wot.wtSettings.settings.rowHeaderWidth; + + // Fix for jumping row headers (https://github.com/handsontable/handsontable/issues/3850) + this.wot.wtSettings.settings.rowHeaderWidth = function () { + return _this._modifyRowHeaderWidth(origRowHeaderWidth); + }; + } + + /** + * + */ + + + _createClass(Table, [{ + key: 'fixTableDomTree', + value: function fixTableDomTree() { + this.TBODY = this.TABLE.querySelector('tbody'); + + if (!this.TBODY) { + this.TBODY = document.createElement('tbody'); + this.TABLE.appendChild(this.TBODY); + } + this.THEAD = this.TABLE.querySelector('thead'); + + if (!this.THEAD) { + this.THEAD = document.createElement('thead'); + this.TABLE.insertBefore(this.THEAD, this.TBODY); + } + this.COLGROUP = this.TABLE.querySelector('colgroup'); + + if (!this.COLGROUP) { + this.COLGROUP = document.createElement('colgroup'); + this.TABLE.insertBefore(this.COLGROUP, this.THEAD); + } + if (this.wot.getSetting('columnHeaders').length && !this.THEAD.childNodes.length) { + this.THEAD.appendChild(document.createElement('TR')); + } + } -exports.__esModule = true; + /** + * @param table + * @returns {HTMLElement} + */ -var _element = __webpack_require__(0); + }, { + key: 'createSpreader', + value: function createSpreader(table) { + var parent = table.parentNode; + var spreader = void 0; -var _function = __webpack_require__(35); + if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) { + spreader = document.createElement('div'); + spreader.className = 'wtSpreader'; -var _browser = __webpack_require__(25); + if (parent) { + // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it + parent.insertBefore(spreader, table); + } + spreader.appendChild(table); + } + spreader.style.position = 'relative'; -var _eventManager = __webpack_require__(4); + return spreader; + } -var _eventManager2 = _interopRequireDefault(_eventManager); + /** + * @param spreader + * @returns {HTMLElement} + */ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + }, { + key: 'createHider', + value: function createHider(spreader) { + var parent = spreader.parentNode; + var hider = void 0; -/** - * - */ -function Event(instance) { - var that = this; - var eventManager = new _eventManager2.default(instance); + if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) { + hider = document.createElement('div'); + hider.className = 'wtHider'; - this.instance = instance; + if (parent) { + // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it + parent.insertBefore(hider, spreader); + } + hider.appendChild(spreader); + } - var dblClickOrigin = [null, null]; - this.dblClickTimeout = [null, null]; + return hider; + } - var onMouseDown = function onMouseDown(event) { - var activeElement = document.activeElement; - var getParentNode = (0, _function.partial)(_element.getParent, event.realTarget); - var realTarget = event.realTarget; + /** + * + * @param hider + * @returns {HTMLElement} + */ - // ignore focusable element from mouse down processing (https://github.com/handsontable/handsontable/issues/3555) - if (realTarget === activeElement || getParentNode(0) === activeElement || getParentNode(1) === activeElement) { - return; - } + }, { + key: 'createHolder', + value: function createHolder(hider) { + var parent = hider.parentNode; + var holder = void 0; - var cell = that.parentCell(realTarget); + if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) { + holder = document.createElement('div'); + holder.style.position = 'relative'; + holder.className = 'wtHolder'; - if ((0, _element.hasClass)(realTarget, 'corner')) { - that.instance.getSetting('onCellCornerMouseDown', event, realTarget); - } else if (cell.TD) { - if (that.instance.hasSetting('onCellMouseDown')) { - that.instance.getSetting('onCellMouseDown', event, cell.coords, cell.TD, that.instance); + if (parent) { + // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it + parent.insertBefore(holder, hider); + } + if (!this.isWorkingOnClone()) { + holder.parentNode.className += 'ht_master handsontable'; + } + holder.appendChild(hider); } - } - if (event.button !== 2) { - // if not right mouse button - if (cell.TD) { - dblClickOrigin[0] = cell.TD; - clearTimeout(that.dblClickTimeout[0]); - that.dblClickTimeout[0] = setTimeout(function () { - dblClickOrigin[0] = null; - }, 1000); - } + return holder; } - }; - - var onTouchMove = function onTouchMove(event) { - that.instance.touchMoving = true; - }; - - var longTouchTimeout; - - var onTouchStart = function onTouchStart(event) { - var container = this; + }, { + key: 'alignOverlaysWithTrimmingContainer', + value: function alignOverlaysWithTrimmingContainer() { + var trimmingElement = (0, _element.getTrimmingContainer)(this.wtRootElement); - eventManager.addEventListener(this, 'touchmove', onTouchMove); + if (!this.isWorkingOnClone()) { + this.holder.parentNode.style.position = 'relative'; - // Prevent cell selection when scrolling with touch event - not the best solution performance-wise - that.checkIfTouchMove = setTimeout(function () { - if (that.instance.touchMoving === true) { - that.instance.touchMoving = void 0; + if (trimmingElement === window) { + var preventOverflow = this.wot.getSetting('preventOverflow'); - eventManager.removeEventListener('touchmove', onTouchMove, false); + if (!preventOverflow) { + this.holder.style.overflow = 'visible'; + this.wtRootElement.style.overflow = 'visible'; + } + } else { + this.holder.style.width = (0, _element.getStyle)(trimmingElement, 'width'); + this.holder.style.height = (0, _element.getStyle)(trimmingElement, 'height'); + this.holder.style.overflow = ''; + } } + } + }, { + key: 'isWorkingOnClone', + value: function isWorkingOnClone() { + return !!this.wot.cloneSource; + } - onMouseDown(event); - }, 30); - }; + /** + * Redraws the table + * + * @param {Boolean} fastDraw If TRUE, will try to avoid full redraw and only update the border positions. If FALSE or UNDEFINED, will perform a full redraw + * @returns {Table} + */ - var onMouseOver = function onMouseOver(event) { - var table, td, mainWOT; + }, { + key: 'draw', + value: function draw(fastDraw) { + var _wot = this.wot, + wtOverlays = _wot.wtOverlays, + wtViewport = _wot.wtViewport; - if (that.instance.hasSetting('onCellMouseOver')) { - table = that.instance.wtTable.TABLE; - td = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table); - mainWOT = that.instance.cloneSource || that.instance; + var totalRows = this.instance.getSetting('totalRows'); + var rowHeaders = this.wot.getSetting('rowHeaders').length; + var columnHeaders = this.wot.getSetting('columnHeaders').length; + var syncScroll = false; - if (td && td !== mainWOT.lastMouseOver && (0, _element.isChildOf)(td, table)) { - mainWOT.lastMouseOver = td; + if (!this.isWorkingOnClone()) { + this.holderOffset = (0, _element.offset)(this.holder); + fastDraw = wtViewport.createRenderCalculators(fastDraw); - that.instance.getSetting('onCellMouseOver', event, that.instance.wtTable.getCoords(td), td, that.instance); - } - } - }; + if (rowHeaders && !this.wot.getSetting('fixedColumnsLeft')) { + var leftScrollPos = wtOverlays.leftOverlay.getScrollPosition(); + var previousState = this.correctHeaderWidth; - var onMouseOut = function onMouseOut(event) { - var table = void 0; - var lastTD = void 0; - var nextTD = void 0; + this.correctHeaderWidth = leftScrollPos > 0; - if (that.instance.hasSetting('onCellMouseOut')) { - table = that.instance.wtTable.TABLE; - lastTD = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table); - nextTD = (0, _element.closestDown)(event.relatedTarget, ['TD', 'TH'], table); + if (previousState !== this.correctHeaderWidth) { + fastDraw = false; + } + } + } - if (lastTD && lastTD !== nextTD && (0, _element.isChildOf)(lastTD, table)) { - that.instance.getSetting('onCellMouseOut', event, that.instance.wtTable.getCoords(lastTD), lastTD, that.instance); + if (!this.isWorkingOnClone()) { + syncScroll = wtOverlays.prepareOverlays(); } - } - }; - var onMouseUp = function onMouseUp(event) { - if (event.button !== 2) { - // if not right mouse button - var cell = that.parentCell(event.realTarget); + if (fastDraw) { + if (!this.isWorkingOnClone()) { + // in case we only scrolled without redraw, update visible rows information in oldRowsCalculator + wtViewport.createVisibleCalculators(); + } + if (wtOverlays) { + wtOverlays.refresh(true); + } + } else { + if (this.isWorkingOnClone()) { + this.tableOffset = this.wot.cloneSource.wtTable.tableOffset; + } else { + this.tableOffset = (0, _element.offset)(this.TABLE); + } + var startRow = void 0; - if (cell.TD === dblClickOrigin[0] && cell.TD === dblClickOrigin[1]) { - if ((0, _element.hasClass)(event.realTarget, 'corner')) { - that.instance.getSetting('onCellCornerDblClick', event, cell.coords, cell.TD, that.instance); + if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER)) { + startRow = 0; + } else if (_base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) { + startRow = Math.max(totalRows - this.wot.getSetting('fixedRowsBottom'), 0); } else { - that.instance.getSetting('onCellDblClick', event, cell.coords, cell.TD, that.instance); + startRow = wtViewport.rowsRenderCalculator.startRow; } + var startColumn = void 0; - dblClickOrigin[0] = null; - dblClickOrigin[1] = null; - } else if (cell.TD === dblClickOrigin[0]) { - that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance); + if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_LEFT) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) { + startColumn = 0; + } else { + startColumn = wtViewport.columnsRenderCalculator.startColumn; + } + this.rowFilter = new _row2.default(startRow, totalRows, columnHeaders); + this.columnFilter = new _column2.default(startColumn, this.wot.getSetting('totalColumns'), rowHeaders); - dblClickOrigin[1] = cell.TD; - clearTimeout(that.dblClickTimeout[1]); - that.dblClickTimeout[1] = setTimeout(function () { - dblClickOrigin[1] = null; - }, 500); - } else if (cell.TD && that.instance.hasSetting('onCellMouseUp')) { - that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance); + this.alignOverlaysWithTrimmingContainer(); + this._doDraw(); // creates calculator after draw } - } - }; - - var onTouchEnd = function onTouchEnd(event) { - clearTimeout(longTouchTimeout); - // that.instance.longTouch == void 0; + this.refreshSelections(fastDraw); - event.preventDefault(); - onMouseUp(event); + if (!this.isWorkingOnClone()) { + wtOverlays.topOverlay.resetFixedPosition(); - // eventManager.removeEventListener(that.instance.wtTable.holder, "mouseup", onMouseUp); - }; + if (wtOverlays.bottomOverlay.clone) { + wtOverlays.bottomOverlay.resetFixedPosition(); + } - eventManager.addEventListener(this.instance.wtTable.holder, 'mousedown', onMouseDown); - eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseover', onMouseOver); - eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseout', onMouseOut); - eventManager.addEventListener(this.instance.wtTable.holder, 'mouseup', onMouseUp); + wtOverlays.leftOverlay.resetFixedPosition(); - // check if full HOT instance, or detached WOT AND run on mobile device - if (this.instance.wtTable.holder.parentNode.parentNode && (0, _browser.isMobileBrowser)() && !that.instance.wtTable.isWorkingOnClone()) { - var classSelector = '.' + this.instance.wtTable.holder.parentNode.className.split(' ').join('.'); + if (wtOverlays.topLeftCornerOverlay) { + wtOverlays.topLeftCornerOverlay.resetFixedPosition(); + } - eventManager.addEventListener(this.instance.wtTable.holder, 'touchstart', function (event) { - that.instance.touchApplied = true; - if ((0, _element.isChildOf)(event.target, classSelector)) { - onTouchStart.call(event.target, event); + if (wtOverlays.bottomLeftCornerOverlay && wtOverlays.bottomLeftCornerOverlay.clone) { + wtOverlays.bottomLeftCornerOverlay.resetFixedPosition(); + } } - }); - eventManager.addEventListener(this.instance.wtTable.holder, 'touchend', function (event) { - that.instance.touchApplied = false; - if ((0, _element.isChildOf)(event.target, classSelector)) { - onTouchEnd.call(event.target, event); + if (syncScroll) { + wtOverlays.syncScrollWithMaster(); } - }); + this.wot.drawn = true; - if (!that.instance.momentumScrolling) { - that.instance.momentumScrolling = {}; + return this; } - eventManager.addEventListener(this.instance.wtTable.holder, 'scroll', function (event) { - clearTimeout(that.instance.momentumScrolling._timeout); + }, { + key: '_doDraw', + value: function _doDraw() { + var wtRenderer = new _tableRenderer2.default(this); - if (!that.instance.momentumScrolling.ongoing) { - that.instance.getSetting('onBeforeTouchScroll'); - } - that.instance.momentumScrolling.ongoing = true; + wtRenderer.render(); + } + }, { + key: 'removeClassFromCells', + value: function removeClassFromCells(className) { + var nodes = this.TABLE.querySelectorAll('.' + className); - that.instance.momentumScrolling._timeout = setTimeout(function () { - if (!that.instance.touchApplied) { - that.instance.momentumScrolling.ongoing = false; + for (var i = 0, len = nodes.length; i < len; i++) { + (0, _element.removeClass)(nodes[i], className); + } + } + }, { + key: 'refreshSelections', + value: function refreshSelections(fastDraw) { + if (!this.wot.selections) { + return; + } + var len = this.wot.selections.length; - that.instance.getSetting('onAfterMomentumScroll'); + if (fastDraw) { + for (var i = 0; i < len; i++) { + // there was no rerender, so we need to remove classNames by ourselves + if (this.wot.selections[i].settings.className) { + this.removeClassFromCells(this.wot.selections[i].settings.className); + } + if (this.wot.selections[i].settings.highlightHeaderClassName) { + this.removeClassFromCells(this.wot.selections[i].settings.highlightHeaderClassName); + } + if (this.wot.selections[i].settings.highlightRowClassName) { + this.removeClassFromCells(this.wot.selections[i].settings.highlightRowClassName); + } + if (this.wot.selections[i].settings.highlightColumnClassName) { + this.removeClassFromCells(this.wot.selections[i].settings.highlightColumnClassName); + } } - }, 200); - }); - } - - eventManager.addEventListener(window, 'resize', function () { - if (that.instance.getSetting('stretchH') !== 'none') { - that.instance.draw(); + } + for (var _i = 0; _i < len; _i++) { + this.wot.selections[_i].draw(this.wot, fastDraw); + } } - }); - this.destroy = function () { - clearTimeout(this.dblClickTimeout[0]); - clearTimeout(this.dblClickTimeout[1]); + /** + * Get cell element at coords. + * + * @param {CellCoords} coords + * @returns {HTMLElement|Number} HTMLElement on success or Number one of the exit codes on error: + * -1 row before viewport + * -2 row after viewport + */ - eventManager.destroy(); - }; -} + }, { + key: 'getCell', + value: function getCell(coords) { + if (this.isRowBeforeRenderedRows(coords.row)) { + // row before rendered rows + return -1; + } else if (this.isRowAfterRenderedRows(coords.row)) { + // row after rendered rows + return -2; + } -Event.prototype.parentCell = function (elem) { - var cell = {}; - var TABLE = this.instance.wtTable.TABLE; - var TD = (0, _element.closestDown)(elem, ['TD', 'TH'], TABLE); + var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(coords.row)]; - if (TD) { - cell.coords = this.instance.wtTable.getCoords(TD); - cell.TD = TD; - } else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'current')) { - cell.coords = this.instance.selections.current.cellRange.highlight; // selections.current is current selected cell - cell.TD = this.instance.wtTable.getCell(cell.coords); - } else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'area')) { - if (this.instance.selections.area.cellRange) { - cell.coords = this.instance.selections.area.cellRange.to; // selections.area is area selected cells - cell.TD = this.instance.wtTable.getCell(cell.coords); + if (TR) { + return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(coords.col)]; + } } - } - return cell; -}; + /** + * getColumnHeader + * + * @param {Number} col Column index + * @param {Number} [level=0] Header level (0 = most distant to the table) + * @returns {Object} HTMLElement on success or undefined on error + */ -exports.default = Event; + }, { + key: 'getColumnHeader', + value: function getColumnHeader(col) { + var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; -/***/ }), -/* 141 */ -/***/ (function(module, exports, __webpack_require__) { + var TR = this.THEAD.childNodes[level]; -"use strict"; + if (TR) { + return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(col)]; + } + } + /** + * getRowHeader + * + * @param {Number} row Row index + * @returns {HTMLElement} HTMLElement on success or Number one of the exit codes on error: `null table doesn't have row headers` + */ -exports.__esModule = true; + }, { + key: 'getRowHeader', + value: function getRowHeader(row) { + if (this.columnFilter.sourceColumnToVisibleRowHeadedColumn(0) === 0) { + return null; + } + var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)]; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + if (TR) { + return TR.childNodes[0]; + } + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** + * Returns cell coords object for a given TD (or a child element of a TD element). + * + * @param {HTMLTableCellElement} TD A cell DOM element (or a child of one). + * @returns {CellCoords|null} The coordinates of the provided TD element (or the closest TD element) or null, if the provided element is not applicable. + */ -/** - * @class ColumnFilter - */ -var ColumnFilter = function () { - /** - * @param {Number} offset - * @param {Number} total - * @param {Number} countTH - */ - function ColumnFilter(offset, total, countTH) { - _classCallCheck(this, ColumnFilter); + }, { + key: 'getCoords', + value: function getCoords(TD) { + if (TD.nodeName !== 'TD' && TD.nodeName !== 'TH') { + TD = (0, _element.closest)(TD, ['TD', 'TH']); + } - this.offset = offset; - this.total = total; - this.countTH = countTH; - } + if (TD === null) { + return null; + } - /** - * @param index - * @returns {Number} - */ + var TR = TD.parentNode; + var CONTAINER = TR.parentNode; + var row = (0, _element.index)(TR); + var col = TD.cellIndex; + + if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_TOP, TD)) { + if (CONTAINER.nodeName === 'THEAD') { + row -= CONTAINER.childNodes.length; + } + } else if (CONTAINER === this.THEAD) { + row = this.rowFilter.visibleColHeadedRowToSourceRow(row); + } else { + row = this.rowFilter.renderedToSource(row); + } + if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_LEFT, TD)) { + col = this.columnFilter.offsettedTH(col); + } else { + col = this.columnFilter.visibleRowHeadedColumnToSourceColumn(col); + } - _createClass(ColumnFilter, [{ - key: "offsetted", - value: function offsetted(index) { - return index + this.offset; + return new _coords2.default(row, col); + } + }, { + key: 'getTrForRow', + value: function getTrForRow(row) { + return this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)]; + } + }, { + key: 'getFirstRenderedRow', + value: function getFirstRenderedRow() { + return this.wot.wtViewport.rowsRenderCalculator.startRow; + } + }, { + key: 'getFirstVisibleRow', + value: function getFirstVisibleRow() { + return this.wot.wtViewport.rowsVisibleCalculator.startRow; + } + }, { + key: 'getFirstRenderedColumn', + value: function getFirstRenderedColumn() { + return this.wot.wtViewport.columnsRenderCalculator.startColumn; } /** - * @param index - * @returns {Number} + * @returns {Number} Returns -1 if no row is visible */ }, { - key: "unOffsetted", - value: function unOffsetted(index) { - return index - this.offset; + key: 'getFirstVisibleColumn', + value: function getFirstVisibleColumn() { + return this.wot.wtViewport.columnsVisibleCalculator.startColumn; } /** - * @param index - * @returns {Number} + * @returns {Number} Returns -1 if no row is visible */ }, { - key: "renderedToSource", - value: function renderedToSource(index) { - return this.offsetted(index); + key: 'getLastRenderedRow', + value: function getLastRenderedRow() { + return this.wot.wtViewport.rowsRenderCalculator.endRow; } - - /** - * @param index - * @returns {Number} - */ - }, { - key: "sourceToRendered", - value: function sourceToRendered(index) { - return this.unOffsetted(index); + key: 'getLastVisibleRow', + value: function getLastVisibleRow() { + return this.wot.wtViewport.rowsVisibleCalculator.endRow; } - - /** - * @param index - * @returns {Number} - */ - }, { - key: "offsettedTH", - value: function offsettedTH(index) { - return index - this.countTH; + key: 'getLastRenderedColumn', + value: function getLastRenderedColumn() { + return this.wot.wtViewport.columnsRenderCalculator.endColumn; } /** - * @param index - * @returns {Number} + * @returns {Number} Returns -1 if no column is visible */ }, { - key: "unOffsettedTH", - value: function unOffsettedTH(index) { - return index + this.countTH; + key: 'getLastVisibleColumn', + value: function getLastVisibleColumn() { + return this.wot.wtViewport.columnsVisibleCalculator.endColumn; } - - /** - * @param index - * @returns {Number} - */ - }, { - key: "visibleRowHeadedColumnToSourceColumn", - value: function visibleRowHeadedColumnToSourceColumn(index) { - return this.renderedToSource(this.offsettedTH(index)); + key: 'isRowBeforeRenderedRows', + value: function isRowBeforeRenderedRows(row) { + return this.rowFilter && this.rowFilter.sourceToRendered(row) < 0 && row >= 0; } - - /** - * @param index - * @returns {Number} - */ - }, { - key: "sourceColumnToVisibleRowHeadedColumn", - value: function sourceColumnToVisibleRowHeadedColumn(index) { - return this.unOffsettedTH(this.sourceToRendered(index)); + key: 'isRowAfterViewport', + value: function isRowAfterViewport(row) { + return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastVisibleRow(); } - }]); - - return ColumnFilter; -}(); - -exports.default = ColumnFilter; - -/***/ }), -/* 142 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * @class RowFilter - */ -var RowFilter = function () { - /** - * @param {Number} offset - * @param {Number} total - * @param {Number} countTH - */ - function RowFilter(offset, total, countTH) { - _classCallCheck(this, RowFilter); - - this.offset = offset; - this.total = total; - this.countTH = countTH; - } - - /** - * @param index - * @returns {Number} - */ + }, { + key: 'isRowAfterRenderedRows', + value: function isRowAfterRenderedRows(row) { + return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastRenderedRow(); + } + }, { + key: 'isColumnBeforeViewport', + value: function isColumnBeforeViewport(column) { + return this.columnFilter && this.columnFilter.sourceToRendered(column) < 0 && column >= 0; + } + }, { + key: 'isColumnAfterViewport', + value: function isColumnAfterViewport(column) { + return this.columnFilter && this.columnFilter.sourceToRendered(column) > this.getLastVisibleColumn(); + } + }, { + key: 'isLastRowFullyVisible', + value: function isLastRowFullyVisible() { + return this.getLastVisibleRow() === this.getLastRenderedRow(); + } + }, { + key: 'isLastColumnFullyVisible', + value: function isLastColumnFullyVisible() { + return this.getLastVisibleColumn() === this.getLastRenderedColumn(); + } + }, { + key: 'getRenderedColumnsCount', + value: function getRenderedColumnsCount() { + var columnsCount = this.wot.wtViewport.columnsRenderCalculator.count; + var totalColumns = this.wot.getSetting('totalColumns'); + if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) { + columnsCount = totalColumns; + } else if (this.wot.isOverlayName(_base2.default.CLONE_LEFT) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) { + return Math.min(this.wot.getSetting('fixedColumnsLeft'), totalColumns); + } - _createClass(RowFilter, [{ - key: "offsetted", - value: function offsetted(index) { - return index + this.offset; + return columnsCount; } + }, { + key: 'getRenderedRowsCount', + value: function getRenderedRowsCount() { + var rowsCount = this.wot.wtViewport.rowsRenderCalculator.count; + var totalRows = this.wot.getSetting('totalRows'); - /** - * @param index - * @returns {Number} - */ + if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) { + rowsCount = totalRows; + } else if (this.wot.isOverlayName(_base2.default.CLONE_TOP) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER)) { + rowsCount = Math.min(this.wot.getSetting('fixedRowsTop'), totalRows); + } else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) { + rowsCount = Math.min(this.wot.getSetting('fixedRowsBottom'), totalRows); + } + return rowsCount; + } }, { - key: "unOffsetted", - value: function unOffsetted(index) { - return index - this.offset; + key: 'getVisibleRowsCount', + value: function getVisibleRowsCount() { + return this.wot.wtViewport.rowsVisibleCalculator.count; } - - /** - * @param index - * @returns {Number} - */ - }, { - key: "renderedToSource", - value: function renderedToSource(index) { - return this.offsetted(index); + key: 'allRowsInViewport', + value: function allRowsInViewport() { + return this.wot.getSetting('totalRows') == this.getVisibleRowsCount(); } /** - * @param index + * Checks if any of the row's cells content exceeds its initial height, and if so, returns the oversized height + * + * @param {Number} sourceRow * @returns {Number} */ }, { - key: "sourceToRendered", - value: function sourceToRendered(index) { - return this.unOffsetted(index); + key: 'getRowHeight', + value: function getRowHeight(sourceRow) { + var height = this.wot.wtSettings.settings.rowHeight(sourceRow); + var oversizedHeight = this.wot.wtViewport.oversizedRows[sourceRow]; + + if (oversizedHeight !== void 0) { + height = height === void 0 ? oversizedHeight : Math.max(height, oversizedHeight); + } + + return height; } + }, { + key: 'getColumnHeaderHeight', + value: function getColumnHeaderHeight(level) { + var height = this.wot.wtSettings.settings.defaultRowHeight; + var oversizedHeight = this.wot.wtViewport.oversizedColumnHeaders[level]; - /** - * @param index - * @returns {Number} - */ + if (oversizedHeight !== void 0) { + height = height ? Math.max(height, oversizedHeight) : oversizedHeight; + } + return height; + } }, { - key: "offsettedTH", - value: function offsettedTH(index) { - return index - this.countTH; + key: 'getVisibleColumnsCount', + value: function getVisibleColumnsCount() { + return this.wot.wtViewport.columnsVisibleCalculator.count; + } + }, { + key: 'allColumnsInViewport', + value: function allColumnsInViewport() { + return this.wot.getSetting('totalColumns') == this.getVisibleColumnsCount(); } + }, { + key: 'getColumnWidth', + value: function getColumnWidth(sourceColumn) { + var width = this.wot.wtSettings.settings.columnWidth; - /** - * @param index - * @returns {Number} - */ + if (typeof width === 'function') { + width = width(sourceColumn); + } else if ((typeof width === 'undefined' ? 'undefined' : _typeof(width)) === 'object') { + width = width[sourceColumn]; + } + return width || this.wot.wtSettings.settings.defaultColumnWidth; + } }, { - key: "unOffsettedTH", - value: function unOffsettedTH(index) { - return index + this.countTH; + key: 'getStretchedColumnWidth', + value: function getStretchedColumnWidth(sourceColumn) { + var columnWidth = this.getColumnWidth(sourceColumn); + var width = columnWidth == null ? this.instance.wtSettings.settings.defaultColumnWidth : columnWidth; + var calculator = this.wot.wtViewport.columnsRenderCalculator; + + if (calculator) { + var stretchedWidth = calculator.getStretchedColumnWidth(sourceColumn, width); + + if (stretchedWidth) { + width = stretchedWidth; + } + } + + return width; } /** - * @param index - * @returns {Number} + * Modify row header widths provided by user in class contructor. + * + * @private */ }, { - key: "visibleColHeadedRowToSourceRow", - value: function visibleColHeadedRowToSourceRow(index) { - return this.renderedToSource(this.offsettedTH(index)); + key: '_modifyRowHeaderWidth', + value: function _modifyRowHeaderWidth(rowHeaderWidthFactory) { + var widths = (0, _function.isFunction)(rowHeaderWidthFactory) ? rowHeaderWidthFactory() : null; + + if (Array.isArray(widths)) { + widths = [].concat(_toConsumableArray(widths)); + widths[widths.length - 1] = this._correctRowHeaderWidth(widths[widths.length - 1]); + } else { + widths = this._correctRowHeaderWidth(widths); + } + + return widths; } /** - * @param index - * @returns {Number} + * Correct row header width if necessary. + * + * @private */ }, { - key: "sourceRowToVisibleColHeadedRow", - value: function sourceRowToVisibleColHeadedRow(index) { - return this.unOffsettedTH(this.sourceToRendered(index)); + key: '_correctRowHeaderWidth', + value: function _correctRowHeaderWidth(width) { + if (typeof width !== 'number') { + width = this.wot.getSetting('defaultColumnWidth'); + } + if (this.correctHeaderWidth) { + width++; + } + + return width; } }]); - return RowFilter; + return Table; }(); -exports.default = RowFilter; +exports.default = Table; /***/ }), -/* 143 */ +/* 165 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -37353,17 +36843,7 @@ var _createClass = function () { function defineProperties(target, props) { for var _element = __webpack_require__(0); -var _array = __webpack_require__(2); - -var _unicode = __webpack_require__(16); - -var _browser = __webpack_require__(25); - -var _eventManager = __webpack_require__(4); - -var _eventManager2 = _interopRequireDefault(_eventManager); - -var _base = __webpack_require__(28); +var _base = __webpack_require__(31); var _base2 = _interopRequireDefault(_base); @@ -37371,831 +36851,728 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var performanceWarningAppeared = false; + /** - * @class Overlays + * @class TableRenderer */ -var Overlays = function () { + +var TableRenderer = function () { /** - * @param {Walkontable} wotInstance + * @param {WalkontableTable} wtTable */ - function Overlays(wotInstance) { - _classCallCheck(this, Overlays); + function TableRenderer(wtTable) { + _classCallCheck(this, TableRenderer); - this.wot = wotInstance; + this.wtTable = wtTable; + this.wot = wtTable.instance; // legacy support - this.instance = this.wot; - this.eventManager = new _eventManager2.default(this.wot); - - this.wot.update('scrollbarWidth', (0, _element.getScrollbarWidth)()); - this.wot.update('scrollbarHeight', (0, _element.getScrollbarWidth)()); - - this.scrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE); - - this.prepareOverlays(); - - this.destroyed = false; - this.keyPressed = false; - this.spreaderLastSize = { - width: null, - height: null - }; - this.overlayScrollPositions = { - master: { - top: 0, - left: 0 - }, - top: { - top: null, - left: 0 - }, - bottom: { - top: null, - left: 0 - }, - left: { - top: 0, - left: null - } - }; - - this.pendingScrollCallbacks = { - master: { - top: 0, - left: 0 - }, - top: { - left: 0 - }, - bottom: { - left: 0 - }, - left: { - top: 0 - } - }; + this.instance = wtTable.instance; - this.verticalScrolling = false; - this.horizontalScrolling = false; - this.delegatedScrollCallback = false; + this.rowFilter = wtTable.rowFilter; + this.columnFilter = wtTable.columnFilter; - this.registeredListeners = []; + this.TABLE = wtTable.TABLE; + this.THEAD = wtTable.THEAD; + this.TBODY = wtTable.TBODY; + this.COLGROUP = wtTable.COLGROUP; - this.registerListeners(); + this.rowHeaders = []; + this.rowHeaderCount = 0; + this.columnHeaders = []; + this.columnHeaderCount = 0; + this.fixedRowsTop = 0; + this.fixedRowsBottom = 0; } /** - * Prepare overlays based on user settings. * - * @returns {Boolean} Returns `true` if changes applied to overlay needs scroll synchronization. */ - _createClass(Overlays, [{ - key: 'prepareOverlays', - value: function prepareOverlays() { - var syncScroll = false; - - if (this.topOverlay) { - syncScroll = this.topOverlay.updateStateOfRendering() || syncScroll; - } else { - this.topOverlay = _base2.default.createOverlay(_base2.default.CLONE_TOP, this.wot); - } - - if (!_base2.default.hasOverlay(_base2.default.CLONE_BOTTOM)) { - this.bottomOverlay = { - needFullRender: false, - updateStateOfRendering: function updateStateOfRendering() { - return false; - } - }; - } - if (!_base2.default.hasOverlay(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) { - this.bottomLeftCornerOverlay = { - needFullRender: false, - updateStateOfRendering: function updateStateOfRendering() { - return false; - } - }; - } - - if (this.bottomOverlay) { - syncScroll = this.bottomOverlay.updateStateOfRendering() || syncScroll; - } else { - this.bottomOverlay = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM, this.wot); - } - - if (this.leftOverlay) { - syncScroll = this.leftOverlay.updateStateOfRendering() || syncScroll; - } else { - this.leftOverlay = _base2.default.createOverlay(_base2.default.CLONE_LEFT, this.wot); - } - - if (this.topOverlay.needFullRender && this.leftOverlay.needFullRender) { - if (this.topLeftCornerOverlay) { - syncScroll = this.topLeftCornerOverlay.updateStateOfRendering() || syncScroll; - } else { - this.topLeftCornerOverlay = _base2.default.createOverlay(_base2.default.CLONE_TOP_LEFT_CORNER, this.wot); - } - } + _createClass(TableRenderer, [{ + key: 'render', + value: function render() { + if (!this.wtTable.isWorkingOnClone()) { + var skipRender = {}; + this.wot.getSetting('beforeDraw', true, skipRender); - if (this.bottomOverlay.needFullRender && this.leftOverlay.needFullRender) { - if (this.bottomLeftCornerOverlay) { - syncScroll = this.bottomLeftCornerOverlay.updateStateOfRendering() || syncScroll; - } else { - this.bottomLeftCornerOverlay = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM_LEFT_CORNER, this.wot); + if (skipRender.skipRender === true) { + return; } } - if (this.wot.getSetting('debug') && !this.debug) { - this.debug = _base2.default.createOverlay(_base2.default.CLONE_DEBUG, this.wot); - } - - return syncScroll; - } - - /** - * Refresh and redraw table - */ - - }, { - key: 'refreshAll', - value: function refreshAll() { - if (!this.wot.drawn) { - return; - } - if (!this.wot.wtTable.holder.parentNode) { - // Walkontable was detached from DOM, but this handler was not removed - this.destroy(); + this.rowHeaders = this.wot.getSetting('rowHeaders'); + this.rowHeaderCount = this.rowHeaders.length; + this.fixedRowsTop = this.wot.getSetting('fixedRowsTop'); + this.fixedRowsBottom = this.wot.getSetting('fixedRowsBottom'); + this.columnHeaders = this.wot.getSetting('columnHeaders'); + this.columnHeaderCount = this.columnHeaders.length; - return; - } - this.wot.draw(true); + var columnsToRender = this.wtTable.getRenderedColumnsCount(); + var rowsToRender = this.wtTable.getRenderedRowsCount(); + var totalColumns = this.wot.getSetting('totalColumns'); + var totalRows = this.wot.getSetting('totalRows'); + var workspaceWidth = void 0; + var adjusted = false; - if (this.verticalScrolling) { - this.leftOverlay.onScroll(); - } + if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) { - if (this.horizontalScrolling) { - this.topOverlay.onScroll(); + // do NOT render headers on the bottom or bottom-left corner overlay + this.columnHeaders = []; + this.columnHeaderCount = 0; } - this.verticalScrolling = false; - this.horizontalScrolling = false; - } - - /** - * Register all necessary event listeners. - */ + if (totalColumns >= 0) { + // prepare COL and TH elements for rendering + this.adjustAvailableNodes(); + adjusted = true; - }, { - key: 'registerListeners', - value: function registerListeners() { - var _this = this; + // adjust column widths according to user widths settings + this.renderColumnHeaders(); - var topOverlayScrollable = this.topOverlay.mainTableScrollableElement; - var leftOverlayScrollable = this.leftOverlay.mainTableScrollableElement; + // Render table rows + this.renderRows(totalRows, rowsToRender, columnsToRender); - var listenersToRegister = []; - listenersToRegister.push([document.documentElement, 'keydown', function (event) { - return _this.onKeyDown(event); - }]); - listenersToRegister.push([document.documentElement, 'keyup', function () { - return _this.onKeyUp(); - }]); - listenersToRegister.push([document, 'visibilitychange', function () { - return _this.onKeyUp(); - }]); - listenersToRegister.push([topOverlayScrollable, 'scroll', function (event) { - return _this.onTableScroll(event); - }]); + if (!this.wtTable.isWorkingOnClone()) { + workspaceWidth = this.wot.wtViewport.getWorkspaceWidth(); + this.wot.wtViewport.containerWidth = null; + } - if (topOverlayScrollable !== leftOverlayScrollable) { - listenersToRegister.push([leftOverlayScrollable, 'scroll', function (event) { - return _this.onTableScroll(event); - }]); + this.adjustColumnWidths(columnsToRender); + this.markOversizedColumnHeaders(); + this.adjustColumnHeaderHeights(); } - if (this.topOverlay.needFullRender) { - listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'scroll', function (event) { - return _this.onTableScroll(event); - }]); - listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'wheel', function (event) { - return _this.onTableScroll(event); - }]); + if (!adjusted) { + this.adjustAvailableNodes(); } + this.removeRedundantRows(rowsToRender); - if (this.bottomOverlay.needFullRender) { - listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'scroll', function (event) { - return _this.onTableScroll(event); - }]); - listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'wheel', function (event) { - return _this.onTableScroll(event); - }]); + if (!this.wtTable.isWorkingOnClone() || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) { + this.markOversizedRows(); } + if (!this.wtTable.isWorkingOnClone()) { + this.wot.wtViewport.createVisibleCalculators(); + this.wot.wtOverlays.refresh(false); - if (this.leftOverlay.needFullRender) { - listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'scroll', function (event) { - return _this.onTableScroll(event); - }]); - listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'wheel', function (event) { - return _this.onTableScroll(event); - }]); - } + this.wot.wtOverlays.applyToDOM(); - if (this.topLeftCornerOverlay && this.topLeftCornerOverlay.needFullRender) { - listenersToRegister.push([this.topLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) { - return _this.onTableScroll(event); - }]); - } + var hiderWidth = (0, _element.outerWidth)(this.wtTable.hider); + var tableWidth = (0, _element.outerWidth)(this.wtTable.TABLE); - if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.needFullRender) { - listenersToRegister.push([this.bottomLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) { - return _this.onTableScroll(event); - }]); - } + if (hiderWidth !== 0 && tableWidth !== hiderWidth) { + // Recalculate the column widths, if width changes made in the overlays removed the scrollbar, thus changing the viewport width. + this.adjustColumnWidths(columnsToRender); + } - if (this.topOverlay.trimmingContainer !== window && this.leftOverlay.trimmingContainer !== window) { - // This is necessary? - // eventManager.addEventListener(window, 'scroll', (event) => this.refreshAll(event)); - listenersToRegister.push([window, 'wheel', function (event) { - var overlay = void 0; - var deltaY = event.wheelDeltaY || event.deltaY; - var deltaX = event.wheelDeltaX || event.deltaX; + if (workspaceWidth !== this.wot.wtViewport.getWorkspaceWidth()) { + // workspace width changed though to shown/hidden vertical scrollbar. Let's reapply stretching + this.wot.wtViewport.containerWidth = null; - if (_this.topOverlay.clone.wtTable.holder.contains(event.realTarget)) { - overlay = 'top'; - } else if (_this.bottomOverlay.clone && _this.bottomOverlay.clone.wtTable.holder.contains(event.realTarget)) { - overlay = 'bottom'; - } else if (_this.leftOverlay.clone.wtTable.holder.contains(event.realTarget)) { - overlay = 'left'; - } else if (_this.topLeftCornerOverlay && _this.topLeftCornerOverlay.clone && _this.topLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) { - overlay = 'topLeft'; - } else if (_this.bottomLeftCornerOverlay && _this.bottomLeftCornerOverlay.clone && _this.bottomLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) { - overlay = 'bottomLeft'; - } + var firstRendered = this.wtTable.getFirstRenderedColumn(); + var lastRendered = this.wtTable.getLastRenderedColumn(); + var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth'); + var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth'); - if (overlay == 'top' && deltaY !== 0 || overlay == 'left' && deltaX !== 0 || overlay == 'bottom' && deltaY !== 0 || (overlay === 'topLeft' || overlay === 'bottomLeft') && (deltaY !== 0 || deltaX !== 0)) { + rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting); - event.preventDefault(); + if (rowHeaderWidthSetting != null) { + for (var i = 0; i < this.rowHeaderCount; i++) { + var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting; + + width = width == null ? defaultColumnWidth : width; + + this.COLGROUP.childNodes[i].style.width = width + 'px'; + } } - }]); - } - while (listenersToRegister.length) { - var listener = listenersToRegister.pop(); - this.eventManager.addEventListener(listener[0], listener[1], listener[2]); + for (var _i = firstRendered; _i < lastRendered; _i++) { + var _width = this.wtTable.getStretchedColumnWidth(_i); + var renderedIndex = this.columnFilter.sourceToRendered(_i); - this.registeredListeners.push(listener); + this.COLGROUP.childNodes[renderedIndex + this.rowHeaderCount].style.width = _width + 'px'; + } + } + + this.wot.getSetting('onDraw', true); + } else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) { + this.wot.cloneSource.wtOverlays.adjustElementsSize(); } } /** - * Deregister all previously registered listeners. + * @param {Number} renderedRowsCount */ }, { - key: 'deregisterListeners', - value: function deregisterListeners() { - while (this.registeredListeners.length) { - var listener = this.registeredListeners.pop(); - this.eventManager.removeEventListener(listener[0], listener[1], listener[2]); + key: 'removeRedundantRows', + value: function removeRedundantRows(renderedRowsCount) { + while (this.wtTable.tbodyChildrenLength > renderedRowsCount) { + this.TBODY.removeChild(this.TBODY.lastChild); + this.wtTable.tbodyChildrenLength--; } } /** - * Scroll listener - * - * @param {Event} event + * @param {Number} totalRows + * @param {Number} rowsToRender + * @param {Number} columnsToRender */ }, { - key: 'onTableScroll', - value: function onTableScroll(event) { - // if mobile browser, do not update scroll positions, as the overlays are hidden during the scroll - if ((0, _browser.isMobileBrowser)()) { - return; - } - var masterHorizontal = this.leftOverlay.mainTableScrollableElement; - var masterVertical = this.topOverlay.mainTableScrollableElement; - var target = event.target; + key: 'renderRows', + value: function renderRows(totalRows, rowsToRender, columnsToRender) { + var lastTD = void 0, + TR = void 0; + var visibleRowIndex = 0; + var sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex); + var isWorkingOnClone = this.wtTable.isWorkingOnClone(); - // For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered - // by hot.refreshBorder - if (this.keyPressed) { - if (masterVertical !== window && target !== window && !event.target.contains(masterVertical) || masterHorizontal !== window && target !== window && !event.target.contains(masterHorizontal)) { - return; + while (sourceRowIndex < totalRows && sourceRowIndex >= 0) { + if (!performanceWarningAppeared && visibleRowIndex > 1000) { + performanceWarningAppeared = true; + console.warn('Performance tip: Handsontable rendered more than 1000 visible rows. Consider limiting the number ' + 'of rendered rows by specifying the table height and/or turning off the "renderAllRows" option.'); } - } + if (rowsToRender !== void 0 && visibleRowIndex === rowsToRender) { + // We have as much rows as needed for this clone + break; + } + TR = this.getOrCreateTrForRow(visibleRowIndex, TR); - if (event.type === 'scroll') { - this.syncScrollPositions(event); - } else { - this.translateMouseWheelToScroll(event); - } - } + // Render row headers + this.renderRowHeaders(sourceRowIndex, TR); + // Add and/or remove TDs to TR to match the desired number + this.adjustColumns(TR, columnsToRender + this.rowHeaderCount); - /** - * Key down listener - */ + lastTD = this.renderCells(sourceRowIndex, TR, columnsToRender); - }, { - key: 'onKeyDown', - value: function onKeyDown(event) { - this.keyPressed = (0, _unicode.isKey)(event.keyCode, 'ARROW_UP|ARROW_RIGHT|ARROW_DOWN|ARROW_LEFT'); - } + if (!isWorkingOnClone || + // Necessary to refresh oversized row heights after editing cell in overlays + this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) { + // Reset the oversized row cache for this row + this.resetOversizedRow(sourceRowIndex); + } - /** - * Key up listener - */ + if (TR.firstChild) { + // if I have 2 fixed columns with one-line content and the 3rd column has a multiline content, this is + // the way to make sure that the overlay will has same row height + var height = this.wot.wtTable.getRowHeight(sourceRowIndex); - }, { - key: 'onKeyUp', - value: function onKeyUp() { - this.keyPressed = false; + if (height) { + // Decrease height. 1 pixel will be "replaced" by 1px border top + height--; + TR.firstChild.style.height = height + 'px'; + } else { + TR.firstChild.style.height = ''; + } + } + visibleRowIndex++; + sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex); + } } /** - * Translate wheel event into scroll event and sync scroll overlays position + * Reset the oversized row cache for the provided index * - * @private - * @param {Event} event - * @returns {Boolean} + * @param {Number} sourceRow Row index */ }, { - key: 'translateMouseWheelToScroll', - value: function translateMouseWheelToScroll(event) { - var topOverlay = this.topOverlay.clone.wtTable.holder; - var bottomOverlay = this.bottomOverlay.clone ? this.bottomOverlay.clone.wtTable.holder : null; - var leftOverlay = this.leftOverlay.clone.wtTable.holder; - var topLeftCornerOverlay = this.topLeftCornerOverlay && this.topLeftCornerOverlay.clone ? this.topLeftCornerOverlay.clone.wtTable.holder : null; - var bottomLeftCornerOverlay = this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone ? this.bottomLeftCornerOverlay.clone.wtTable.holder : null; - var mouseWheelSpeedRatio = -0.2; - var deltaY = event.wheelDeltaY || -1 * event.deltaY; - var deltaX = event.wheelDeltaX || -1 * event.deltaX; - var parentHolder = null; - var eventMockup = { type: 'wheel' }; - var tempElem = event.target; - var delta = null; - - // Fix for extremely slow header scrolling with a mousewheel on Firefox - if (event.deltaMode === 1) { - deltaY *= 120; - deltaX *= 120; - } - - while (tempElem != document && tempElem != null) { - if (tempElem.className.indexOf('wtHolder') > -1) { - parentHolder = tempElem; - break; - } - tempElem = tempElem.parentNode; + key: 'resetOversizedRow', + value: function resetOversizedRow(sourceRow) { + if (this.wot.getSetting('externalRowCalculator')) { + return; } - eventMockup.target = parentHolder; - - if (parentHolder === topLeftCornerOverlay || parentHolder === bottomLeftCornerOverlay) { - this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaX, 'x'); - this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaY, 'y'); - } else { - if (parentHolder === topOverlay || parentHolder === bottomOverlay) { - delta = deltaY; - } else if (parentHolder === leftOverlay) { - delta = deltaX; - } - - this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * delta); + if (this.wot.wtViewport.oversizedRows && this.wot.wtViewport.oversizedRows[sourceRow]) { + this.wot.wtViewport.oversizedRows[sourceRow] = void 0; } - - return false; } /** - * Synchronize scroll position between master table and overlay table. - * - * @private - * @param {Event|Object} event - * @param {Number} [fakeScrollValue=null] - * @param {String} [fakeScrollDirection=null] `x` or `y`. + * Check if any of the rendered rows is higher than expected, and if so, cache them */ }, { - key: 'syncScrollPositions', - value: function syncScrollPositions(event) { - var fakeScrollValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - var fakeScrollDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - - if (this.destroyed) { + key: 'markOversizedRows', + value: function markOversizedRows() { + if (this.wot.getSetting('externalRowCalculator')) { return; } - if (arguments.length === 0) { - this.syncScrollWithMaster(); + var rowCount = this.instance.wtTable.TBODY.childNodes.length; + var expectedTableHeight = rowCount * this.instance.wtSettings.settings.defaultRowHeight; + var actualTableHeight = (0, _element.innerHeight)(this.instance.wtTable.TBODY) - 1; + var previousRowHeight = void 0; + var rowInnerHeight = void 0; + var sourceRowIndex = void 0; + var currentTr = void 0; + var rowHeader = void 0; + var totalRows = this.instance.getSetting('totalRows'); + if (expectedTableHeight === actualTableHeight && !this.instance.getSetting('fixedRowsBottom')) { + // If the actual table height equals rowCount * default single row height, no row is oversized -> no need to iterate over them return; } - var masterHorizontal = this.leftOverlay.mainTableScrollableElement; - var masterVertical = this.topOverlay.mainTableScrollableElement; - var target = event.target; - var tempScrollValue = 0; - var scrollValueChanged = false; - var topOverlay = void 0; - var leftOverlay = void 0; - var topLeftCornerOverlay = void 0; - var bottomLeftCornerOverlay = void 0; - var bottomOverlay = void 0; - var delegatedScroll = false; - var preventOverflow = this.wot.getSetting('preventOverflow'); - if (this.topOverlay.needFullRender) { - topOverlay = this.topOverlay.clone.wtTable.holder; - } + while (rowCount) { + rowCount--; + sourceRowIndex = this.instance.wtTable.rowFilter.renderedToSource(rowCount); + previousRowHeight = this.instance.wtTable.getRowHeight(sourceRowIndex); + currentTr = this.instance.wtTable.getTrForRow(sourceRowIndex); + rowHeader = currentTr.querySelector('th'); - if (this.bottomOverlay.needFullRender) { - bottomOverlay = this.bottomOverlay.clone.wtTable.holder; - } + if (rowHeader) { + rowInnerHeight = (0, _element.innerHeight)(rowHeader); + } else { + rowInnerHeight = (0, _element.innerHeight)(currentTr) - 1; + } - if (this.leftOverlay.needFullRender) { - leftOverlay = this.leftOverlay.clone.wtTable.holder; + if (!previousRowHeight && this.instance.wtSettings.settings.defaultRowHeight < rowInnerHeight || previousRowHeight < rowInnerHeight) { + this.instance.wtViewport.oversizedRows[sourceRowIndex] = ++rowInnerHeight; + } } + } - if (this.leftOverlay.needFullRender && this.topOverlay.needFullRender) { - topLeftCornerOverlay = this.topLeftCornerOverlay.clone.wtTable.holder; - } + /** + * Check if any of the rendered columns is higher than expected, and if so, cache them. + */ - if (this.leftOverlay.needFullRender && this.bottomOverlay.needFullRender) { - bottomLeftCornerOverlay = this.bottomLeftCornerOverlay.clone.wtTable.holder; - } + }, { + key: 'markOversizedColumnHeaders', + value: function markOversizedColumnHeaders() { + var overlayName = this.wot.getOverlayName(); - if (target === document) { - target = window; + if (!this.columnHeaderCount || this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] || this.wtTable.isWorkingOnClone()) { + return; } + var columnCount = this.wtTable.getRenderedColumnsCount(); - if (target === masterHorizontal || target === masterVertical) { - if (preventOverflow) { - tempScrollValue = (0, _element.getScrollLeft)(this.scrollableElement); - } else { - tempScrollValue = (0, _element.getScrollLeft)(target); + for (var i = 0; i < this.columnHeaderCount; i++) { + for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) { + this.markIfOversizedColumnHeader(renderedColumnIndex); } + } + this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] = true; + } - // if scrolling the master table - populate the scroll values to both top and left overlays - this.horizontalScrolling = true; - this.overlayScrollPositions.master.left = tempScrollValue; - scrollValueChanged = true; - - if (this.pendingScrollCallbacks.master.left > 0) { - this.pendingScrollCallbacks.master.left--; - } else { - if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) { - - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.top.left++; - } - - topOverlay.scrollLeft = tempScrollValue; - delegatedScroll = masterHorizontal !== window; - } - - if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) { + /** + * + */ - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.bottom.left++; - } + }, { + key: 'adjustColumnHeaderHeights', + value: function adjustColumnHeaderHeights() { + var columnHeaders = this.wot.getSetting('columnHeaders'); + var children = this.wot.wtTable.THEAD.childNodes; + var oversizedColumnHeaders = this.wot.wtViewport.oversizedColumnHeaders; - bottomOverlay.scrollLeft = tempScrollValue; - delegatedScroll = masterHorizontal !== window; + for (var i = 0, len = columnHeaders.length; i < len; i++) { + if (oversizedColumnHeaders[i]) { + if (!children[i] || children[i].childNodes.length === 0) { + return; } + children[i].childNodes[0].style.height = oversizedColumnHeaders[i] + 'px'; } + } + } - tempScrollValue = (0, _element.getScrollTop)(target); - - this.verticalScrolling = true; - this.overlayScrollPositions.master.top = tempScrollValue; - scrollValueChanged = true; - - if (this.pendingScrollCallbacks.master.top > 0) { - this.pendingScrollCallbacks.master.top--; - } else if (leftOverlay && leftOverlay.scrollTop !== tempScrollValue) { - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.left.top++; - } + /** + * Check if column header for the specified column is higher than expected, and if so, cache it + * + * @param {Number} col Index of column + */ - leftOverlay.scrollTop = tempScrollValue; - delegatedScroll = masterVertical !== window; - } - } else if (target === bottomOverlay) { - tempScrollValue = (0, _element.getScrollLeft)(target); + }, { + key: 'markIfOversizedColumnHeader', + value: function markIfOversizedColumnHeader(col) { + var sourceColIndex = this.wot.wtTable.columnFilter.renderedToSource(col); + var level = this.columnHeaderCount; + var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight; + var previousColHeaderHeight = void 0; + var currentHeader = void 0; + var currentHeaderHeight = void 0; + var columnHeaderHeightSetting = this.wot.getSetting('columnHeaderHeight') || []; - // if scrolling the bottom overlay - populate the horizontal scroll to the master table - this.horizontalScrolling = true; - this.overlayScrollPositions.bottom.left = tempScrollValue; - scrollValueChanged = true; + while (level) { + level--; - if (this.pendingScrollCallbacks.bottom.left > 0) { - this.pendingScrollCallbacks.bottom.left--; - } else { - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.master.left++; - } + previousColHeaderHeight = this.wot.wtTable.getColumnHeaderHeight(level); + currentHeader = this.wot.wtTable.getColumnHeader(sourceColIndex, level); - masterHorizontal.scrollLeft = tempScrollValue; + if (!currentHeader) { + /* eslint-disable no-continue */ + continue; + } + currentHeaderHeight = (0, _element.innerHeight)(currentHeader); - if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) { - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.top.left++; - } + if (!previousColHeaderHeight && defaultRowHeight < currentHeaderHeight || previousColHeaderHeight < currentHeaderHeight) { + this.wot.wtViewport.oversizedColumnHeaders[level] = currentHeaderHeight; + } - topOverlay.scrollLeft = tempScrollValue; - delegatedScroll = masterVertical !== window; + if (Array.isArray(columnHeaderHeightSetting)) { + if (columnHeaderHeightSetting[level] != null) { + this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level]; } + } else if (!isNaN(columnHeaderHeightSetting)) { + this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting; } - // "fake" scroll value calculated from the mousewheel event - if (fakeScrollValue !== null) { - scrollValueChanged = true; - masterVertical.scrollTop += fakeScrollValue; + if (this.wot.wtViewport.oversizedColumnHeaders[level] < (columnHeaderHeightSetting[level] || columnHeaderHeightSetting)) { + this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level] || columnHeaderHeightSetting; } - } else if (target === topOverlay) { - tempScrollValue = (0, _element.getScrollLeft)(target); + } + } - // if scrolling the top overlay - populate the horizontal scroll to the master table - this.horizontalScrolling = true; - this.overlayScrollPositions.top.left = tempScrollValue; - scrollValueChanged = true; + /** + * @param {Number} sourceRowIndex + * @param {HTMLTableRowElement} TR + * @param {Number} columnsToRender + * @returns {HTMLTableCellElement} + */ - if (this.pendingScrollCallbacks.top.left > 0) { - this.pendingScrollCallbacks.top.left--; - } else { + }, { + key: 'renderCells', + value: function renderCells(sourceRowIndex, TR, columnsToRender) { + var TD = void 0; + var sourceColIndex = void 0; - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.master.left++; - } + for (var visibleColIndex = 0; visibleColIndex < columnsToRender; visibleColIndex++) { + sourceColIndex = this.columnFilter.renderedToSource(visibleColIndex); - masterHorizontal.scrollLeft = tempScrollValue; + if (visibleColIndex === 0) { + TD = TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(sourceColIndex)]; + } else { + TD = TD.nextSibling; // http://jsperf.com/nextsibling-vs-indexed-childnodes } - - // "fake" scroll value calculated from the mousewheel event - if (fakeScrollValue !== null) { - scrollValueChanged = true; - masterVertical.scrollTop += fakeScrollValue; + // If the number of headers has been reduced, we need to replace excess TH with TD + if (TD.nodeName == 'TH') { + TD = replaceThWithTd(TD, TR); } + if (!(0, _element.hasClass)(TD, 'hide')) { + TD.className = ''; + } + TD.removeAttribute('style'); + this.wot.wtSettings.settings.cellRenderer(sourceRowIndex, sourceColIndex, TD); + } - if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) { - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.bottom.left++; - } + return TD; + } - bottomOverlay.scrollLeft = tempScrollValue; - delegatedScroll = masterVertical !== window; - } - } else if (target === leftOverlay) { - tempScrollValue = (0, _element.getScrollTop)(target); + /** + * @param {Number} columnsToRender Number of columns to render. + */ - // if scrolling the left overlay - populate the vertical scroll to the master table - if (this.overlayScrollPositions.left.top !== tempScrollValue) { - this.verticalScrolling = true; - this.overlayScrollPositions.left.top = tempScrollValue; - scrollValueChanged = true; + }, { + key: 'adjustColumnWidths', + value: function adjustColumnWidths(columnsToRender) { + var scrollbarCompensation = 0; + var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot; + var mainHolder = sourceInstance.wtTable.holder; + var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth'); + var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth'); - if (this.pendingScrollCallbacks.left.top > 0) { - this.pendingScrollCallbacks.left.top--; - } else { - if (fakeScrollValue == null) { - this.pendingScrollCallbacks.master.top++; - } + if (mainHolder.offsetHeight < mainHolder.scrollHeight) { + scrollbarCompensation = (0, _element.getScrollbarWidth)(); + } + this.wot.wtViewport.columnsRenderCalculator.refreshStretching(this.wot.wtViewport.getViewportWidth() - scrollbarCompensation); - masterVertical.scrollTop = tempScrollValue; - } - } + rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting); - // "fake" scroll value calculated from the mousewheel event - if (fakeScrollValue !== null) { - scrollValueChanged = true; - masterVertical.scrollLeft += fakeScrollValue; - } - } else if (target === topLeftCornerOverlay || target === bottomLeftCornerOverlay) { - if (fakeScrollValue !== null) { - scrollValueChanged = true; + if (rowHeaderWidthSetting != null) { + for (var i = 0; i < this.rowHeaderCount; i++) { + var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting; - if (fakeScrollDirection === 'x') { - masterVertical.scrollLeft += fakeScrollValue; - } else if (fakeScrollDirection === 'y') { - masterVertical.scrollTop += fakeScrollValue; - } + width = width == null ? defaultColumnWidth : width; + + this.COLGROUP.childNodes[i].style.width = width + 'px'; } } - if (!this.keyPressed && scrollValueChanged && event.type === 'scroll') { - if (this.delegatedScrollCallback) { - this.delegatedScrollCallback = false; - } else { - this.refreshAll(); - } + for (var renderedColIndex = 0; renderedColIndex < columnsToRender; renderedColIndex++) { + var _width2 = this.wtTable.getStretchedColumnWidth(this.columnFilter.renderedToSource(renderedColIndex)); - if (delegatedScroll) { - this.delegatedScrollCallback = true; - } + this.COLGROUP.childNodes[renderedColIndex + this.rowHeaderCount].style.width = _width2 + 'px'; } } /** - * Synchronize overlay scrollbars with the master scrollbar + * @param {HTMLTableCellElement} TR */ }, { - key: 'syncScrollWithMaster', - value: function syncScrollWithMaster() { - var master = this.topOverlay.mainTableScrollableElement; - var scrollLeft = master.scrollLeft, - scrollTop = master.scrollTop; + key: 'appendToTbody', + value: function appendToTbody(TR) { + this.TBODY.appendChild(TR); + this.wtTable.tbodyChildrenLength++; + } + /** + * @param {Number} rowIndex + * @param {HTMLTableRowElement} currentTr + * @returns {HTMLTableCellElement} + */ - if (this.topOverlay.needFullRender) { - this.topOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; - } - if (this.bottomOverlay.needFullRender) { - this.bottomOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; + }, { + key: 'getOrCreateTrForRow', + value: function getOrCreateTrForRow(rowIndex, currentTr) { + var TR = void 0; + + if (rowIndex >= this.wtTable.tbodyChildrenLength) { + TR = this.createRow(); + this.appendToTbody(TR); + } else if (rowIndex === 0) { + TR = this.TBODY.firstChild; + } else { + // http://jsperf.com/nextsibling-vs-indexed-childnodes + TR = currentTr.nextSibling; } - if (this.leftOverlay.needFullRender) { - this.leftOverlay.clone.wtTable.holder.scrollTop = scrollTop; + if (TR.className) { + TR.removeAttribute('class'); } + + return TR; } /** - * Update the main scrollable elements for all the overlays. + * @returns {HTMLTableCellElement} */ }, { - key: 'updateMainScrollableElements', - value: function updateMainScrollableElements() { - this.deregisterListeners(); - - this.leftOverlay.updateMainScrollableElement(); - this.topOverlay.updateMainScrollableElement(); + key: 'createRow', + value: function createRow() { + var TR = document.createElement('TR'); - if (this.bottomOverlay.needFullRender) { - this.bottomOverlay.updateMainScrollableElement(); + for (var visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) { + TR.appendChild(document.createElement('TH')); } - this.scrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE); - - this.registerListeners(); + return TR; } /** - * + * @param {Number} row + * @param {Number} col + * @param {HTMLTableCellElement} TH */ }, { - key: 'destroy', - value: function destroy() { - this.eventManager.destroy(); - this.topOverlay.destroy(); + key: 'renderRowHeader', + value: function renderRowHeader(row, col, TH) { + TH.className = ''; + TH.removeAttribute('style'); + this.rowHeaders[col](row, TH, col); + } - if (this.bottomOverlay.clone) { - this.bottomOverlay.destroy(); - } - this.leftOverlay.destroy(); + /** + * @param {Number} row + * @param {HTMLTableCellElement} TR + */ - if (this.topLeftCornerOverlay) { - this.topLeftCornerOverlay.destroy(); + }, { + key: 'renderRowHeaders', + value: function renderRowHeaders(row, TR) { + for (var TH = TR.firstChild, visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) { + // If the number of row headers increased we need to create TH or replace an existing TD node with TH + if (!TH) { + TH = document.createElement('TH'); + TR.appendChild(TH); + } else if (TH.nodeName == 'TD') { + TH = replaceTdWithTh(TH, TR); + } + this.renderRowHeader(row, visibleColIndex, TH); + // http://jsperf.com/nextsibling-vs-indexed-childnodes + TH = TH.nextSibling; } + } - if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) { - this.bottomLeftCornerOverlay.destroy(); - } + /** + * Adjust the number of COL and TH elements to match the number of columns and headers that need to be rendered + */ - if (this.debug) { - this.debug.destroy(); - } - this.destroyed = true; + }, { + key: 'adjustAvailableNodes', + value: function adjustAvailableNodes() { + this.adjustColGroups(); + this.adjustThead(); } /** - * @param {Boolean} [fastDraw=false] + * Renders the column headers */ }, { - key: 'refresh', - value: function refresh() { - var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + key: 'renderColumnHeaders', + value: function renderColumnHeaders() { + if (!this.columnHeaderCount) { + return; + } + var columnCount = this.wtTable.getRenderedColumnsCount(); - if (this.topOverlay.areElementSizesAdjusted && this.leftOverlay.areElementSizesAdjusted) { - var container = this.wot.wtTable.wtRootElement.parentNode || this.wot.wtTable.wtRootElement; - var width = container.clientWidth; - var height = container.clientHeight; + for (var i = 0; i < this.columnHeaderCount; i++) { + var TR = this.getTrForColumnHeaders(i); - if (width !== this.spreaderLastSize.width || height !== this.spreaderLastSize.height) { - this.spreaderLastSize.width = width; - this.spreaderLastSize.height = height; - this.adjustElementsSize(); + for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) { + var sourceCol = this.columnFilter.renderedToSource(renderedColumnIndex); + + this.renderColumnHeader(i, sourceCol, TR.childNodes[renderedColumnIndex + this.rowHeaderCount]); } } + } - if (this.bottomOverlay.clone) { - this.bottomOverlay.refresh(fastDraw); - } + /** + * Adjusts the number of COL elements to match the number of columns that need to be rendered + */ - this.leftOverlay.refresh(fastDraw); - this.topOverlay.refresh(fastDraw); + }, { + key: 'adjustColGroups', + value: function adjustColGroups() { + var columnCount = this.wtTable.getRenderedColumnsCount(); - if (this.topLeftCornerOverlay) { - this.topLeftCornerOverlay.refresh(fastDraw); + while (this.wtTable.colgroupChildrenLength < columnCount + this.rowHeaderCount) { + this.COLGROUP.appendChild(document.createElement('COL')); + this.wtTable.colgroupChildrenLength++; } - - if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) { - this.bottomLeftCornerOverlay.refresh(fastDraw); + while (this.wtTable.colgroupChildrenLength > columnCount + this.rowHeaderCount) { + this.COLGROUP.removeChild(this.COLGROUP.lastChild); + this.wtTable.colgroupChildrenLength--; } - - if (this.debug) { - this.debug.refresh(fastDraw); + if (this.rowHeaderCount) { + (0, _element.addClass)(this.COLGROUP.childNodes[0], 'rowHeader'); } } /** - * Adjust overlays elements size and master table size - * - * @param {Boolean} [force=false] + * Adjusts the number of TH elements in THEAD to match the number of headers and columns that need to be rendered */ }, { - key: 'adjustElementsSize', - value: function adjustElementsSize() { - var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + key: 'adjustThead', + value: function adjustThead() { + var columnCount = this.wtTable.getRenderedColumnsCount(); + var TR = this.THEAD.firstChild; - var totalColumns = this.wot.getSetting('totalColumns'); - var totalRows = this.wot.getSetting('totalRows'); - var headerRowSize = this.wot.wtViewport.getRowHeaderWidth(); - var headerColumnSize = this.wot.wtViewport.getColumnHeaderHeight(); - var hiderStyle = this.wot.wtTable.hider.style; + if (this.columnHeaders.length) { + for (var i = 0, len = this.columnHeaders.length; i < len; i++) { + TR = this.THEAD.childNodes[i]; - hiderStyle.width = headerRowSize + this.leftOverlay.sumCellSizes(0, totalColumns) + 'px'; - hiderStyle.height = headerColumnSize + this.topOverlay.sumCellSizes(0, totalRows) + 1 + 'px'; + if (!TR) { + TR = document.createElement('TR'); + this.THEAD.appendChild(TR); + } + this.theadChildrenLength = TR.childNodes.length; - this.topOverlay.adjustElementsSize(force); - this.leftOverlay.adjustElementsSize(force); + while (this.theadChildrenLength < columnCount + this.rowHeaderCount) { + TR.appendChild(document.createElement('TH')); + this.theadChildrenLength++; + } + while (this.theadChildrenLength > columnCount + this.rowHeaderCount) { + TR.removeChild(TR.lastChild); + this.theadChildrenLength--; + } + } + var theadChildrenLength = this.THEAD.childNodes.length; - if (this.bottomOverlay.clone) { - this.bottomOverlay.adjustElementsSize(force); + if (theadChildrenLength > this.columnHeaders.length) { + for (var _i2 = this.columnHeaders.length; _i2 < theadChildrenLength; _i2++) { + this.THEAD.removeChild(this.THEAD.lastChild); + } + } + } else if (TR) { + (0, _element.empty)(TR); } } /** - * + * @param {Number} index + * @returns {HTMLTableCellElement} */ }, { - key: 'applyToDOM', - value: function applyToDOM() { - if (!this.topOverlay.areElementSizesAdjusted || !this.leftOverlay.areElementSizesAdjusted) { - this.adjustElementsSize(); - } - this.topOverlay.applyToDOM(); + key: 'getTrForColumnHeaders', + value: function getTrForColumnHeaders(index) { + return this.THEAD.childNodes[index]; + } - if (this.bottomOverlay.clone) { - this.bottomOverlay.applyToDOM(); - } + /** + * @param {Number} row + * @param {Number} col + * @param {HTMLTableCellElement} TH + * @returns {*} + */ - this.leftOverlay.applyToDOM(); + }, { + key: 'renderColumnHeader', + value: function renderColumnHeader(row, col, TH) { + TH.className = ''; + TH.removeAttribute('style'); + + return this.columnHeaders[row](col, TH, row); } /** - * Get the parent overlay of the provided element. + * Add and/or remove the TDs to match the desired number * - * @param {HTMLElement} element - * @returns {Object|null} + * @param {HTMLTableCellElement} TR Table row in question + * @param {Number} desiredCount The desired number of TDs in the TR */ }, { - key: 'getParentOverlay', - value: function getParentOverlay(element) { - if (!element) { - return null; - } + key: 'adjustColumns', + value: function adjustColumns(TR, desiredCount) { + var count = TR.childNodes.length; - var overlays = [this.topOverlay, this.leftOverlay, this.bottomOverlay, this.topLeftCornerOverlay, this.bottomLeftCornerOverlay]; - var result = null; + while (count < desiredCount) { + var TD = document.createElement('TD'); - (0, _array.arrayEach)(overlays, function (elem, i) { - if (!elem) { - return; - } + TR.appendChild(TD); + count++; + } + while (count > desiredCount) { + TR.removeChild(TR.lastChild); + count--; + } + } - if (elem.clone && elem.clone.wtTable.TABLE.contains(element)) { - result = elem.clone; - } - }); + /** + * @param {Number} columnsToRender + */ - return result; + }, { + key: 'removeRedundantColumns', + value: function removeRedundantColumns(columnsToRender) { + while (this.wtTable.tbodyChildrenLength > columnsToRender) { + this.TBODY.removeChild(this.TBODY.lastChild); + this.wtTable.tbodyChildrenLength--; + } } }]); - return Overlays; + return TableRenderer; }(); -exports.default = Overlays; +function replaceTdWithTh(TD, TR) { + var TH = document.createElement('TH'); + + TR.insertBefore(TH, TD); + TR.removeChild(TD); + + return TH; +} + +function replaceThWithTd(TH, TR) { + var TD = document.createElement('TD'); + + TR.insertBefore(TD, TH); + TR.removeChild(TH); + + return TD; +} + +exports.default = TableRenderer; /***/ }), -/* 144 */ +/* 166 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -38207,497 +37584,550 @@ var _createClass = function () { function defineProperties(target, props) { for var _element = __webpack_require__(0); -var _number = __webpack_require__(6); +var _object = __webpack_require__(1); + +var _eventManager = __webpack_require__(4); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +var _viewportColumns = __webpack_require__(155); + +var _viewportColumns2 = _interopRequireDefault(_viewportColumns); + +var _viewportRows = __webpack_require__(156); + +var _viewportRows2 = _interopRequireDefault(_viewportRows); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * @class Scroll + * @class Viewport */ -var Scroll = function () { +var Viewport = function () { /** - * @param {Walkontable} wotInstance + * @param wotInstance */ - function Scroll(wotInstance) { - _classCallCheck(this, Scroll); + function Viewport(wotInstance) { + var _this = this; - this.wot = wotInstance; + _classCallCheck(this, Viewport); + this.wot = wotInstance; // legacy support - this.instance = wotInstance; + this.instance = this.wot; + + this.oversizedRows = []; + this.oversizedColumnHeaders = []; + this.hasOversizedColumnHeadersMarked = {}; + this.clientHeight = 0; + this.containerWidth = NaN; + this.rowHeaderWidth = NaN; + this.rowsVisibleCalculator = null; + this.columnsVisibleCalculator = null; + + this.eventManager = new _eventManager2.default(this.wot); + this.eventManager.addEventListener(window, 'resize', function () { + _this.clientHeight = _this.getWorkspaceHeight(); + }); } /** - * Scrolls viewport to a cell by minimum number of cells - * - * @param {CellCoords} coords + * @returns {number} */ - _createClass(Scroll, [{ - key: 'scrollViewport', - value: function scrollViewport(coords) { - if (!this.wot.drawn) { - return; + _createClass(Viewport, [{ + key: 'getWorkspaceHeight', + value: function getWorkspaceHeight() { + var trimmingContainer = this.instance.wtOverlays.topOverlay.trimmingContainer; + var elemHeight = void 0; + var height = 0; + + if (trimmingContainer === window) { + height = document.documentElement.clientHeight; + } else { + elemHeight = (0, _element.outerHeight)(trimmingContainer); + // returns height without DIV scrollbar + height = elemHeight > 0 && trimmingContainer.clientHeight > 0 ? trimmingContainer.clientHeight : Infinity; } - var _getVariables2 = this._getVariables(), - topOverlay = _getVariables2.topOverlay, - leftOverlay = _getVariables2.leftOverlay, - totalRows = _getVariables2.totalRows, - totalColumns = _getVariables2.totalColumns, - fixedRowsTop = _getVariables2.fixedRowsTop, - fixedRowsBottom = _getVariables2.fixedRowsBottom, - fixedColumnsLeft = _getVariables2.fixedColumnsLeft; + return height; + } + }, { + key: 'getWorkspaceWidth', + value: function getWorkspaceWidth() { + var width = void 0; + var totalColumns = this.wot.getSetting('totalColumns'); + var trimmingContainer = this.instance.wtOverlays.leftOverlay.trimmingContainer; + var overflow = void 0; + var stretchSetting = this.wot.getSetting('stretchH'); + var docOffsetWidth = document.documentElement.offsetWidth; + var preventOverflow = this.wot.getSetting('preventOverflow'); - if (coords.row < 0 || coords.row > Math.max(totalRows - 1, 0)) { - throw new Error('row ' + coords.row + ' does not exist'); + if (preventOverflow) { + return (0, _element.outerWidth)(this.instance.wtTable.wtRootElement); + } + + if (this.wot.getSetting('freezeOverlays')) { + width = Math.min(docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth); + } else { + width = Math.min(this.getContainerFillWidth(), docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth); } - if (coords.col < 0 || coords.col > Math.max(totalColumns - 1, 0)) { - throw new Error('column ' + coords.col + ' does not exist'); + if (trimmingContainer === window && totalColumns > 0 && this.sumColumnWidths(0, totalColumns - 1) > width) { + // in case sum of column widths is higher than available stylesheet width, let's assume using the whole window + // otherwise continue below, which will allow stretching + // this is used in `scroll_window.html` + // TODO test me + return document.documentElement.clientWidth; } - if (coords.row >= fixedRowsTop && coords.row < this.getFirstVisibleRow()) { - topOverlay.scrollTo(coords.row); - } else if (coords.row > this.getLastVisibleRow() && coords.row < totalRows - fixedRowsBottom) { - topOverlay.scrollTo(coords.row, true); + if (trimmingContainer !== window) { + overflow = (0, _element.getStyle)(this.instance.wtOverlays.leftOverlay.trimmingContainer, 'overflow'); + + if (overflow == 'scroll' || overflow == 'hidden' || overflow == 'auto') { + // this is used in `scroll.html` + // TODO test me + return Math.max(width, trimmingContainer.clientWidth); + } } - if (coords.col >= fixedColumnsLeft && coords.col < this.getFirstVisibleColumn()) { - leftOverlay.scrollTo(coords.col); - } else if (coords.col > this.getLastVisibleColumn()) { - leftOverlay.scrollTo(coords.col, true); + if (stretchSetting === 'none' || !stretchSetting) { + // if no stretching is used, return the maximum used workspace width + return Math.max(width, (0, _element.outerWidth)(this.instance.wtTable.TABLE)); } + + // if stretching is used, return the actual container width, so the columns can fit inside it + return width; } /** - * Get first visible row based on virtual dom and how table is visible in browser window viewport. + * Checks if viewport has vertical scroll * - * @returns {Number} + * @returns {Boolean} */ }, { - key: 'getFirstVisibleRow', - value: function getFirstVisibleRow() { - var _getVariables3 = this._getVariables(), - topOverlay = _getVariables3.topOverlay, - wtTable = _getVariables3.wtTable, - wtViewport = _getVariables3.wtViewport, - totalRows = _getVariables3.totalRows, - fixedRowsTop = _getVariables3.fixedRowsTop; - - var firstVisibleRow = wtTable.getFirstVisibleRow(); - - if (topOverlay.mainTableScrollableElement === window) { - var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); - var totalTableHeight = (0, _element.innerHeight)(wtTable.hider); - var windowHeight = (0, _element.innerHeight)(window); - var windowScrollTop = (0, _element.getScrollTop)(window); + key: 'hasVerticalScroll', + value: function hasVerticalScroll() { + return this.getWorkspaceActualHeight() > this.getWorkspaceHeight(); + } - // Only calculate firstVisibleRow when table didn't filled (from up) whole viewport space - if (rootElementOffset.top + totalTableHeight - windowHeight <= windowScrollTop) { - var rowsHeight = wtViewport.getColumnHeaderHeight(); + /** + * Checks if viewport has horizontal scroll + * + * @returns {Boolean} + */ - rowsHeight += topOverlay.sumCellSizes(0, fixedRowsTop); + }, { + key: 'hasHorizontalScroll', + value: function hasHorizontalScroll() { + return this.getWorkspaceActualWidth() > this.getWorkspaceWidth(); + } - (0, _number.rangeEachReverse)(totalRows, 1, function (row) { - rowsHeight += topOverlay.sumCellSizes(row - 1, row); + /** + * @param from + * @param length + * @returns {Number} + */ - if (rootElementOffset.top + totalTableHeight - rowsHeight <= windowScrollTop) { - // Return physical row + 1 - firstVisibleRow = row; + }, { + key: 'sumColumnWidths', + value: function sumColumnWidths(from, length) { + var sum = 0; - return false; - } - }); - } + while (from < length) { + sum += this.wot.wtTable.getColumnWidth(from); + from++; } - return firstVisibleRow; + return sum; } /** - * Get last visible row based on virtual dom and how table is visible in browser window viewport. - * * @returns {Number} */ }, { - key: 'getLastVisibleRow', - value: function getLastVisibleRow() { - var _getVariables4 = this._getVariables(), - topOverlay = _getVariables4.topOverlay, - wtTable = _getVariables4.wtTable, - wtViewport = _getVariables4.wtViewport, - totalRows = _getVariables4.totalRows; + key: 'getContainerFillWidth', + value: function getContainerFillWidth() { + if (this.containerWidth) { + return this.containerWidth; + } + var mainContainer = this.instance.wtTable.holder; + var fillWidth = void 0; + var dummyElement = void 0; - var lastVisibleRow = wtTable.getLastVisibleRow(); + dummyElement = document.createElement('div'); + dummyElement.style.width = '100%'; + dummyElement.style.height = '1px'; + mainContainer.appendChild(dummyElement); + fillWidth = dummyElement.offsetWidth; - if (topOverlay.mainTableScrollableElement === window) { - var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); - var windowHeight = (0, _element.innerHeight)(window); - var windowScrollTop = (0, _element.getScrollTop)(window); + this.containerWidth = fillWidth; + mainContainer.removeChild(dummyElement); - // Only calculate lastVisibleRow when table didn't filled (from bottom) whole viewport space - if (rootElementOffset.top > windowScrollTop) { - var rowsHeight = wtViewport.getColumnHeaderHeight(); + return fillWidth; + } - (0, _number.rangeEach)(1, totalRows, function (row) { - rowsHeight += topOverlay.sumCellSizes(row - 1, row); + /** + * @returns {Number} + */ - if (rootElementOffset.top + rowsHeight - windowScrollTop >= windowHeight) { - // Return physical row - 1 (-2 because rangeEach gives row index + 1 - sumCellSizes requirements) - lastVisibleRow = row - 2; + }, { + key: 'getWorkspaceOffset', + value: function getWorkspaceOffset() { + return (0, _element.offset)(this.wot.wtTable.TABLE); + } - return false; - } - }); - } - } + /** + * @returns {Number} + */ - return lastVisibleRow; + }, { + key: 'getWorkspaceActualHeight', + value: function getWorkspaceActualHeight() { + return (0, _element.outerHeight)(this.wot.wtTable.TABLE); } /** - * Get first visible column based on virtual dom and how table is visible in browser window viewport. - * * @returns {Number} */ }, { - key: 'getFirstVisibleColumn', - value: function getFirstVisibleColumn() { - var _getVariables5 = this._getVariables(), - leftOverlay = _getVariables5.leftOverlay, - wtTable = _getVariables5.wtTable, - wtViewport = _getVariables5.wtViewport, - totalColumns = _getVariables5.totalColumns, - fixedColumnsLeft = _getVariables5.fixedColumnsLeft; + key: 'getWorkspaceActualWidth', + value: function getWorkspaceActualWidth() { + return (0, _element.outerWidth)(this.wot.wtTable.TABLE) || (0, _element.outerWidth)(this.wot.wtTable.TBODY) || (0, _element.outerWidth)(this.wot.wtTable.THEAD); // IE8 reports 0 as offsetWidth; + } - var firstVisibleColumn = wtTable.getFirstVisibleColumn(); + /** + * @returns {Number} + */ - if (leftOverlay.mainTableScrollableElement === window) { - var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); - var totalTableWidth = (0, _element.innerWidth)(wtTable.hider); - var windowWidth = (0, _element.innerWidth)(window); - var windowScrollLeft = (0, _element.getScrollLeft)(window); + }, { + key: 'getColumnHeaderHeight', + value: function getColumnHeaderHeight() { + if (isNaN(this.columnHeaderHeight)) { + this.columnHeaderHeight = (0, _element.outerHeight)(this.wot.wtTable.THEAD); + } - // Only calculate firstVisibleColumn when table didn't filled (from left) whole viewport space - if (rootElementOffset.left + totalTableWidth - windowWidth <= windowScrollLeft) { - var columnsWidth = wtViewport.getRowHeaderWidth(); + return this.columnHeaderHeight; + } - (0, _number.rangeEachReverse)(totalColumns, 1, function (column) { - columnsWidth += leftOverlay.sumCellSizes(column - 1, column); + /** + * @returns {Number} + */ - if (rootElementOffset.left + totalTableWidth - columnsWidth <= windowScrollLeft) { - // Return physical column + 1 - firstVisibleColumn = column; + }, { + key: 'getViewportHeight', + value: function getViewportHeight() { + var containerHeight = this.getWorkspaceHeight(); + var columnHeaderHeight = void 0; - return false; - } - }); - } + if (containerHeight === Infinity) { + return containerHeight; + } + columnHeaderHeight = this.getColumnHeaderHeight(); + + if (columnHeaderHeight > 0) { + containerHeight -= columnHeaderHeight; } - return firstVisibleColumn; + return containerHeight; } /** - * Get last visible column based on virtual dom and how table is visible in browser window viewport. - * * @returns {Number} */ }, { - key: 'getLastVisibleColumn', - value: function getLastVisibleColumn() { - var _getVariables6 = this._getVariables(), - leftOverlay = _getVariables6.leftOverlay, - wtTable = _getVariables6.wtTable, - wtViewport = _getVariables6.wtViewport, - totalColumns = _getVariables6.totalColumns; + key: 'getRowHeaderWidth', + value: function getRowHeaderWidth() { + var rowHeadersHeightSetting = this.instance.getSetting('rowHeaderWidth'); + var rowHeaders = this.instance.getSetting('rowHeaders'); - var lastVisibleColumn = wtTable.getLastVisibleColumn(); + if (rowHeadersHeightSetting) { + this.rowHeaderWidth = 0; - if (leftOverlay.mainTableScrollableElement === window) { - var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement); - var windowWidth = (0, _element.innerWidth)(window); - var windowScrollLeft = (0, _element.getScrollLeft)(window); + for (var i = 0, len = rowHeaders.length; i < len; i++) { + this.rowHeaderWidth += rowHeadersHeightSetting[i] || rowHeadersHeightSetting; + } + } - // Only calculate lastVisibleColumn when table didn't filled (from right) whole viewport space - if (rootElementOffset.left > windowScrollLeft) { - var columnsWidth = wtViewport.getRowHeaderWidth(); + if (this.wot.cloneSource) { + return this.wot.cloneSource.wtViewport.getRowHeaderWidth(); + } - (0, _number.rangeEach)(1, totalColumns, function (column) { - columnsWidth += leftOverlay.sumCellSizes(column - 1, column); + if (isNaN(this.rowHeaderWidth)) { - if (rootElementOffset.left + columnsWidth - windowScrollLeft >= windowWidth) { - // Return physical column - 1 (-2 because rangeEach gives column index + 1 - sumCellSizes requirements) - lastVisibleColumn = column - 2; + if (rowHeaders.length) { + var TH = this.instance.wtTable.TABLE.querySelector('TH'); + this.rowHeaderWidth = 0; - return false; + for (var _i = 0, _len = rowHeaders.length; _i < _len; _i++) { + if (TH) { + this.rowHeaderWidth += (0, _element.outerWidth)(TH); + TH = TH.nextSibling; + } else { + // yes this is a cheat but it worked like that before, just taking assumption from CSS instead of measuring. + // TODO: proper fix + this.rowHeaderWidth += 50; } - }); + } + } else { + this.rowHeaderWidth = 0; } } - return lastVisibleColumn; + this.rowHeaderWidth = this.instance.getSetting('onModifyRowHeaderWidth', this.rowHeaderWidth) || this.rowHeaderWidth; + + return this.rowHeaderWidth; } /** - * Returns collection of variables used to rows and columns visibility calculations. - * - * @returns {Object} - * @private + * @returns {Number} */ }, { - key: '_getVariables', - value: function _getVariables() { - var wot = this.wot; - var topOverlay = wot.wtOverlays.topOverlay; - var leftOverlay = wot.wtOverlays.leftOverlay; - var wtTable = wot.wtTable; - var wtViewport = wot.wtViewport; - var totalRows = wot.getSetting('totalRows'); - var totalColumns = wot.getSetting('totalColumns'); - var fixedRowsTop = wot.getSetting('fixedRowsTop'); - var fixedRowsBottom = wot.getSetting('fixedRowsBottom'); - var fixedColumnsLeft = wot.getSetting('fixedColumnsLeft'); - - return { - topOverlay: topOverlay, - leftOverlay: leftOverlay, - wtTable: wtTable, - wtViewport: wtViewport, - totalRows: totalRows, - totalColumns: totalColumns, - fixedRowsTop: fixedRowsTop, - fixedRowsBottom: fixedRowsBottom, - fixedColumnsLeft: fixedColumnsLeft - }; - } - }]); - - return Scroll; -}(); - -exports.default = Scroll; - -/***/ }), -/* 145 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + key: 'getViewportWidth', + value: function getViewportWidth() { + var containerWidth = this.getWorkspaceWidth(); + var rowHeaderWidth = void 0; + if (containerWidth === Infinity) { + return containerWidth; + } + rowHeaderWidth = this.getRowHeaderWidth(); -exports.__esModule = true; + if (rowHeaderWidth > 0) { + return containerWidth - rowHeaderWidth; + } -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + return containerWidth; + } -var _element = __webpack_require__(0); + /** + * Creates: + * - rowsRenderCalculator (before draw, to qualify rows for rendering) + * - rowsVisibleCalculator (after draw, to measure which rows are actually visible) + * + * @returns {ViewportRowsCalculator} + */ -var _object = __webpack_require__(1); + }, { + key: 'createRowsCalculator', + value: function createRowsCalculator() { + var _this2 = this; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; -/** - * @class Settings - */ -var Settings = function () { - /** - * @param {Walkontable} wotInstance - * @param {Object} settings - */ - function Settings(wotInstance, settings) { - var _this = this; + var height = void 0; + var pos = void 0; + var fixedRowsTop = void 0; + var scrollbarHeight = void 0; + var fixedRowsBottom = void 0; + var fixedRowsHeight = void 0; + var totalRows = void 0; - _classCallCheck(this, Settings); + this.rowHeaderWidth = NaN; - this.wot = wotInstance; + if (this.wot.wtSettings.settings.renderAllRows) { + height = Infinity; + } else { + height = this.getViewportHeight(); + } + pos = this.wot.wtOverlays.topOverlay.getScrollPosition() - this.wot.wtOverlays.topOverlay.getTableParentOffset(); - // legacy support - this.instance = wotInstance; + if (pos < 0) { + pos = 0; + } + fixedRowsTop = this.wot.getSetting('fixedRowsTop'); + fixedRowsBottom = this.wot.getSetting('fixedRowsBottom'); + totalRows = this.wot.getSetting('totalRows'); - // default settings. void 0 means it is required, null means it can be empty - this.defaults = { - table: void 0, - debug: false, // shows WalkontableDebugOverlay + if (fixedRowsTop) { + fixedRowsHeight = this.wot.wtOverlays.topOverlay.sumCellSizes(0, fixedRowsTop); + pos += fixedRowsHeight; + height -= fixedRowsHeight; + } - // presentation mode - externalRowCalculator: false, - stretchH: 'none', // values: all, last, none - currentRowClassName: null, - currentColumnClassName: null, - preventOverflow: function preventOverflow() { - return false; - }, + if (fixedRowsBottom && this.wot.wtOverlays.bottomOverlay.clone) { + fixedRowsHeight = this.wot.wtOverlays.bottomOverlay.sumCellSizes(totalRows - fixedRowsBottom, totalRows); + height -= fixedRowsHeight; + } - // data source - data: void 0, - freezeOverlays: false, - fixedColumnsLeft: 0, - fixedRowsTop: 0, - fixedRowsBottom: 0, - minSpareRows: 0, + if (this.wot.wtTable.holder.clientHeight === this.wot.wtTable.holder.offsetHeight) { + scrollbarHeight = 0; + } else { + scrollbarHeight = (0, _element.getScrollbarWidth)(); + } - // this must be array of functions: [function (row, TH) {}] - rowHeaders: function rowHeaders() { - return []; - }, + return new _viewportRows2.default(height, pos, this.wot.getSetting('totalRows'), function (sourceRow) { + return _this2.wot.wtTable.getRowHeight(sourceRow); + }, visible ? null : this.wot.wtSettings.settings.viewportRowCalculatorOverride, visible, scrollbarHeight); + } + /** + * Creates: + * - columnsRenderCalculator (before draw, to qualify columns for rendering) + * - columnsVisibleCalculator (after draw, to measure which columns are actually visible) + * + * @returns {ViewportRowsCalculator} + */ - // this must be array of functions: [function (column, TH) {}] - columnHeaders: function columnHeaders() { - return []; - }, + }, { + key: 'createColumnsCalculator', + value: function createColumnsCalculator() { + var _this3 = this; - totalRows: void 0, - totalColumns: void 0, - cellRenderer: function cellRenderer(row, column, TD) { - var cellData = _this.getSetting('data', row, column); + var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - (0, _element.fastInnerText)(TD, cellData === void 0 || cellData === null ? '' : cellData); - }, + var width = this.getViewportWidth(); + var pos = void 0; + var fixedColumnsLeft = void 0; - // columnWidth: 50, - columnWidth: function columnWidth(col) { - // return undefined means use default size for the rendered cell content - }, - rowHeight: function rowHeight(row) { - // return undefined means use default size for the rendered cell content - }, + this.columnHeaderHeight = NaN; - defaultRowHeight: 23, - defaultColumnWidth: 50, - selections: null, - hideBorderOnMouseDownOver: false, - viewportRowCalculatorOverride: null, - viewportColumnCalculatorOverride: null, + pos = this.wot.wtOverlays.leftOverlay.getScrollPosition() - this.wot.wtOverlays.leftOverlay.getTableParentOffset(); - // callbacks - onCellMouseDown: null, - onCellMouseOver: null, - onCellMouseOut: null, - onCellMouseUp: null, + if (pos < 0) { + pos = 0; + } + fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft'); - // onCellMouseOut: null, - onCellDblClick: null, - onCellCornerMouseDown: null, - onCellCornerDblClick: null, - beforeDraw: null, - onDraw: null, - onBeforeDrawBorders: null, - onScrollVertically: null, - onScrollHorizontally: null, - onBeforeTouchScroll: null, - onAfterMomentumScroll: null, - onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(width) { - return width; - }, - onModifyRowHeaderWidth: null, + if (fixedColumnsLeft) { + var fixedColumnsWidth = this.wot.wtOverlays.leftOverlay.sumCellSizes(0, fixedColumnsLeft); + pos += fixedColumnsWidth; + width -= fixedColumnsWidth; + } + if (this.wot.wtTable.holder.clientWidth !== this.wot.wtTable.holder.offsetWidth) { + width -= (0, _element.getScrollbarWidth)(); + } - // constants - scrollbarWidth: 10, - scrollbarHeight: 10, + return new _viewportColumns2.default(width, pos, this.wot.getSetting('totalColumns'), function (sourceCol) { + return _this3.wot.wtTable.getColumnWidth(sourceCol); + }, visible ? null : this.wot.wtSettings.settings.viewportColumnCalculatorOverride, visible, this.wot.getSetting('stretchH'), function (stretchedWidth, column) { + return _this3.wot.getSetting('onBeforeStretchingColumnWidth', stretchedWidth, column); + }); + } - renderAllRows: false, - groups: false, - rowHeaderWidth: null, - columnHeaderHeight: null, - headerClassName: null - }; + /** + * Creates rowsRenderCalculator and columnsRenderCalculator (before draw, to determine what rows and + * cols should be rendered) + * + * @param fastDraw {Boolean} If `true`, will try to avoid full redraw and only update the border positions. + * If `false` or `undefined`, will perform a full redraw + * @returns fastDraw {Boolean} The fastDraw value, possibly modified + */ - // reference to settings - this.settings = {}; + }, { + key: 'createRenderCalculators', + value: function createRenderCalculators() { + var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - for (var i in this.defaults) { - if ((0, _object.hasOwnProperty)(this.defaults, i)) { - if (settings[i] !== void 0) { - this.settings[i] = settings[i]; - } else if (this.defaults[i] === void 0) { - throw new Error('A required setting "' + i + '" was not provided'); - } else { - this.settings[i] = this.defaults[i]; + if (fastDraw) { + var proposedRowsVisibleCalculator = this.createRowsCalculator(true); + var proposedColumnsVisibleCalculator = this.createColumnsCalculator(true); + + if (!(this.areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) && this.areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator))) { + fastDraw = false; } } + + if (!fastDraw) { + this.rowsRenderCalculator = this.createRowsCalculator(); + this.columnsRenderCalculator = this.createColumnsCalculator(); + } + // delete temporarily to make sure that renderers always use rowsRenderCalculator, not rowsVisibleCalculator + this.rowsVisibleCalculator = null; + this.columnsVisibleCalculator = null; + + return fastDraw; } - } - /** - * Update settings - * - * @param {Object} settings - * @param {*} value - * @returns {Walkontable} - */ + /** + * Creates rowsVisibleCalculator and columnsVisibleCalculator (after draw, to determine what are + * the actually visible rows and columns) + */ + }, { + key: 'createVisibleCalculators', + value: function createVisibleCalculators() { + this.rowsVisibleCalculator = this.createRowsCalculator(true); + this.columnsVisibleCalculator = this.createColumnsCalculator(true); + } - _createClass(Settings, [{ - key: 'update', - value: function update(settings, value) { - if (value === void 0) { - // settings is object - for (var i in settings) { - if ((0, _object.hasOwnProperty)(settings, i)) { - this.settings[i] = settings[i]; - } + /** + * Returns information whether proposedRowsVisibleCalculator viewport + * is contained inside rows rendered in previous draw (cached in rowsRenderCalculator) + * + * @param {Object} proposedRowsVisibleCalculator + * @returns {Boolean} Returns `true` if all proposed visible rows are already rendered (meaning: redraw is not needed). + * Returns `false` if at least one proposed visible row is not already rendered (meaning: redraw is needed) + */ + + }, { + key: 'areAllProposedVisibleRowsAlreadyRendered', + value: function areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) { + if (this.rowsVisibleCalculator) { + if (proposedRowsVisibleCalculator.startRow < this.rowsRenderCalculator.startRow || proposedRowsVisibleCalculator.startRow === this.rowsRenderCalculator.startRow && proposedRowsVisibleCalculator.startRow > 0) { + return false; + } else if (proposedRowsVisibleCalculator.endRow > this.rowsRenderCalculator.endRow || proposedRowsVisibleCalculator.endRow === this.rowsRenderCalculator.endRow && proposedRowsVisibleCalculator.endRow < this.wot.getSetting('totalRows') - 1) { + return false; } - } else { - // if value is defined then settings is the key - this.settings[settings] = value; + return true; } - return this.wot; + + return false; } /** - * Get setting by name + * Returns information whether proposedColumnsVisibleCalculator viewport + * is contained inside column rendered in previous draw (cached in columnsRenderCalculator) * - * @param {String} key - * @param {*} param1 - * @param {*} param2 - * @param {*} param3 - * @param {*} param4 - * @returns {*} + * @param {Object} proposedColumnsVisibleCalculator + * @returns {Boolean} Returns `true` if all proposed visible columns are already rendered (meaning: redraw is not needed). + * Returns `false` if at least one proposed visible column is not already rendered (meaning: redraw is needed) */ }, { - key: 'getSetting', - value: function getSetting(key, param1, param2, param3, param4) { - if (typeof this.settings[key] === 'function') { - // this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips - return this.settings[key](param1, param2, param3, param4); - } else if (param1 !== void 0 && Array.isArray(this.settings[key])) { - // perhaps this can be removed, it is only used in tests - return this.settings[key][param1]; + key: 'areAllProposedVisibleColumnsAlreadyRendered', + value: function areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator) { + if (this.columnsVisibleCalculator) { + if (proposedColumnsVisibleCalculator.startColumn < this.columnsRenderCalculator.startColumn || proposedColumnsVisibleCalculator.startColumn === this.columnsRenderCalculator.startColumn && proposedColumnsVisibleCalculator.startColumn > 0) { + return false; + } else if (proposedColumnsVisibleCalculator.endColumn > this.columnsRenderCalculator.endColumn || proposedColumnsVisibleCalculator.endColumn === this.columnsRenderCalculator.endColumn && proposedColumnsVisibleCalculator.endColumn < this.wot.getSetting('totalColumns') - 1) { + return false; + } + return true; } - return this.settings[key]; + return false; } /** - * Checks if setting exists - * - * @param {Boolean} key - * @returns {Boolean} + * Resets values in keys of the hasOversizedColumnHeadersMarked object after updateSettings. */ }, { - key: 'has', - value: function has(key) { - return !!this.settings[key]; + key: 'resetHasOversizedColumnHeadersMarked', + value: function resetHasOversizedColumnHeadersMarked() { + (0, _object.objectEach)(this.hasOversizedColumnHeadersMarked, function (value, key, object) { + object[key] = void 0; + }); } }]); - return Settings; + return Viewport; }(); -exports.default = Settings; +exports.default = Viewport; /***/ }), -/* 146 */ +/* 167 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -38705,745 +38135,542 @@ exports.default = Settings; exports.__esModule = true; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _element = __webpack_require__(0); -var _function = __webpack_require__(35); - -var _coords = __webpack_require__(42); - -var _coords2 = _interopRequireDefault(_coords); - -var _range = __webpack_require__(68); - -var _range2 = _interopRequireDefault(_range); +var _event = __webpack_require__(8); -var _column = __webpack_require__(141); +var _object = __webpack_require__(1); -var _column2 = _interopRequireDefault(_column); +var _browser = __webpack_require__(26); -var _row = __webpack_require__(142); +var _eventManager = __webpack_require__(4); -var _row2 = _interopRequireDefault(_row); +var _eventManager2 = _interopRequireDefault(_eventManager); -var _tableRenderer = __webpack_require__(147); +var _coords = __webpack_require__(49); -var _tableRenderer2 = _interopRequireDefault(_tableRenderer); +var _coords2 = _interopRequireDefault(_coords); -var _base = __webpack_require__(28); +var _base = __webpack_require__(31); var _base2 = _interopRequireDefault(_base); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * */ -var Table = function () { +var Border = function () { /** * @param {Walkontable} wotInstance - * @param {HTMLTableElement} table + * @param {Object} settings */ - function Table(wotInstance, table) { - var _this = this; - - _classCallCheck(this, Table); + function Border(wotInstance, settings) { + _classCallCheck(this, Border); + if (!settings) { + return; + } + this.eventManager = new _eventManager2.default(wotInstance); + this.instance = wotInstance; this.wot = wotInstance; + this.settings = settings; + this.mouseDown = false; + this.main = null; - // legacy support - this.instance = this.wot; - this.TABLE = table; - this.TBODY = null; - this.THEAD = null; - this.COLGROUP = null; - this.tableOffset = 0; - this.holderOffset = 0; - - (0, _element.removeTextNodes)(this.TABLE); - - this.spreader = this.createSpreader(this.TABLE); - this.hider = this.createHider(this.spreader); - this.holder = this.createHolder(this.hider); - - this.wtRootElement = this.holder.parentNode; - this.alignOverlaysWithTrimmingContainer(); - this.fixTableDomTree(); - - this.colgroupChildrenLength = this.COLGROUP.childNodes.length; - this.theadChildrenLength = this.THEAD.firstChild ? this.THEAD.firstChild.childNodes.length : 0; - this.tbodyChildrenLength = this.TBODY.childNodes.length; - - this.rowFilter = null; - this.columnFilter = null; - this.correctHeaderWidth = false; + this.top = null; + this.left = null; + this.bottom = null; + this.right = null; - var origRowHeaderWidth = this.wot.wtSettings.settings.rowHeaderWidth; + this.topStyle = null; + this.leftStyle = null; + this.bottomStyle = null; + this.rightStyle = null; - // Fix for jumping row headers (https://github.com/handsontable/handsontable/issues/3850) - this.wot.wtSettings.settings.rowHeaderWidth = function () { - return _this._modifyRowHeaderWidth(origRowHeaderWidth); + this.cornerDefaultStyle = { + width: '5px', + height: '5px', + borderWidth: '2px', + borderStyle: 'solid', + borderColor: '#FFF' }; + this.corner = null; + this.cornerStyle = null; + + this.createBorders(settings); + this.registerListeners(); } /** - * + * Register all necessary events */ - _createClass(Table, [{ - key: 'fixTableDomTree', - value: function fixTableDomTree() { - this.TBODY = this.TABLE.querySelector('tbody'); - - if (!this.TBODY) { - this.TBODY = document.createElement('tbody'); - this.TABLE.appendChild(this.TBODY); - } - this.THEAD = this.TABLE.querySelector('thead'); - - if (!this.THEAD) { - this.THEAD = document.createElement('thead'); - this.TABLE.insertBefore(this.THEAD, this.TBODY); - } - this.COLGROUP = this.TABLE.querySelector('colgroup'); - - if (!this.COLGROUP) { - this.COLGROUP = document.createElement('colgroup'); - this.TABLE.insertBefore(this.COLGROUP, this.THEAD); - } - - if (this.wot.getSetting('columnHeaders').length && !this.THEAD.childNodes.length) { - this.THEAD.appendChild(document.createElement('TR')); - } - } - - /** - * @param table - * @returns {HTMLElement} - */ + _createClass(Border, [{ + key: 'registerListeners', + value: function registerListeners() { + var _this2 = this; - }, { - key: 'createSpreader', - value: function createSpreader(table) { - var parent = table.parentNode; - var spreader = void 0; + this.eventManager.addEventListener(document.body, 'mousedown', function () { + return _this2.onMouseDown(); + }); + this.eventManager.addEventListener(document.body, 'mouseup', function () { + return _this2.onMouseUp(); + }); - if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) { - spreader = document.createElement('div'); - spreader.className = 'wtSpreader'; + var _loop = function _loop(c, len) { + _this2.eventManager.addEventListener(_this2.main.childNodes[c], 'mouseenter', function (event) { + return _this2.onMouseEnter(event, _this2.main.childNodes[c]); + }); + }; - if (parent) { - // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it - parent.insertBefore(spreader, table); - } - spreader.appendChild(table); + for (var c = 0, len = this.main.childNodes.length; c < len; c++) { + _loop(c, len); } - spreader.style.position = 'relative'; - - return spreader; } /** - * @param spreader - * @returns {HTMLElement} + * Mouse down listener + * + * @private */ }, { - key: 'createHider', - value: function createHider(spreader) { - var parent = spreader.parentNode; - var hider = void 0; - - if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) { - hider = document.createElement('div'); - hider.className = 'wtHider'; - - if (parent) { - // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it - parent.insertBefore(hider, spreader); - } - hider.appendChild(spreader); - } - - return hider; + key: 'onMouseDown', + value: function onMouseDown() { + this.mouseDown = true; } /** + * Mouse up listener * - * @param hider - * @returns {HTMLElement} + * @private */ }, { - key: 'createHolder', - value: function createHolder(hider) { - var parent = hider.parentNode; - var holder = void 0; - - if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) { - holder = document.createElement('div'); - holder.style.position = 'relative'; - holder.className = 'wtHolder'; - - if (parent) { - // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it - parent.insertBefore(holder, hider); - } - if (!this.isWorkingOnClone()) { - holder.parentNode.className += 'ht_master handsontable'; - } - holder.appendChild(hider); - } - - return holder; - } - }, { - key: 'alignOverlaysWithTrimmingContainer', - value: function alignOverlaysWithTrimmingContainer() { - var trimmingElement = (0, _element.getTrimmingContainer)(this.wtRootElement); - - if (!this.isWorkingOnClone()) { - this.holder.parentNode.style.position = 'relative'; - - if (trimmingElement === window) { - var preventOverflow = this.wot.getSetting('preventOverflow'); - - if (!preventOverflow) { - this.holder.style.overflow = 'visible'; - this.wtRootElement.style.overflow = 'visible'; - } - } else { - this.holder.style.width = (0, _element.getStyle)(trimmingElement, 'width'); - this.holder.style.height = (0, _element.getStyle)(trimmingElement, 'height'); - this.holder.style.overflow = ''; - } - } - } - }, { - key: 'isWorkingOnClone', - value: function isWorkingOnClone() { - return !!this.wot.cloneSource; + key: 'onMouseUp', + value: function onMouseUp() { + this.mouseDown = false; } /** - * Redraws the table + * Mouse enter listener for fragment selection functionality. * - * @param {Boolean} fastDraw If TRUE, will try to avoid full redraw and only update the border positions. If FALSE or UNDEFINED, will perform a full redraw - * @returns {Table} + * @private + * @param {Event} event Dom event + * @param {HTMLElement} parentElement Part of border element. */ }, { - key: 'draw', - value: function draw(fastDraw) { - var _wot = this.wot, - wtOverlays = _wot.wtOverlays, - wtViewport = _wot.wtViewport; - - var totalRows = this.instance.getSetting('totalRows'); - var rowHeaders = this.wot.getSetting('rowHeaders').length; - var columnHeaders = this.wot.getSetting('columnHeaders').length; - var syncScroll = false; - - if (!this.isWorkingOnClone()) { - this.holderOffset = (0, _element.offset)(this.holder); - fastDraw = wtViewport.createRenderCalculators(fastDraw); - - if (rowHeaders && !this.wot.getSetting('fixedColumnsLeft')) { - var leftScrollPos = wtOverlays.leftOverlay.getScrollPosition(); - var previousState = this.correctHeaderWidth; - - this.correctHeaderWidth = leftScrollPos > 0; - - if (previousState !== this.correctHeaderWidth) { - fastDraw = false; - } - } - } - - if (!this.isWorkingOnClone()) { - syncScroll = wtOverlays.prepareOverlays(); - } - - if (fastDraw) { - if (!this.isWorkingOnClone()) { - // in case we only scrolled without redraw, update visible rows information in oldRowsCalculator - wtViewport.createVisibleCalculators(); - } - if (wtOverlays) { - wtOverlays.refresh(true); - } - } else { - if (this.isWorkingOnClone()) { - this.tableOffset = this.wot.cloneSource.wtTable.tableOffset; - } else { - this.tableOffset = (0, _element.offset)(this.TABLE); - } - var startRow = void 0; - - if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER)) { - startRow = 0; - } else if (_base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) { - startRow = Math.max(totalRows - this.wot.getSetting('fixedRowsBottom'), 0); - } else { - startRow = wtViewport.rowsRenderCalculator.startRow; - } - var startColumn = void 0; - - if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_LEFT) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) { - startColumn = 0; - } else { - startColumn = wtViewport.columnsRenderCalculator.startColumn; - } - this.rowFilter = new _row2.default(startRow, totalRows, columnHeaders); - this.columnFilter = new _column2.default(startColumn, this.wot.getSetting('totalColumns'), rowHeaders); - - this.alignOverlaysWithTrimmingContainer(); - this._doDraw(); // creates calculator after draw + key: 'onMouseEnter', + value: function onMouseEnter(event, parentElement) { + if (!this.mouseDown || !this.wot.getSetting('hideBorderOnMouseDownOver')) { + return; } - this.refreshSelections(fastDraw); - - if (!this.isWorkingOnClone()) { - wtOverlays.topOverlay.resetFixedPosition(); - - if (wtOverlays.bottomOverlay.clone) { - wtOverlays.bottomOverlay.resetFixedPosition(); - } + event.preventDefault(); + (0, _event.stopImmediatePropagation)(event); - wtOverlays.leftOverlay.resetFixedPosition(); + var _this = this; + var bounds = parentElement.getBoundingClientRect(); + // Hide border to prevents selection jumping when fragmentSelection is enabled. + parentElement.style.display = 'none'; - if (wtOverlays.topLeftCornerOverlay) { - wtOverlays.topLeftCornerOverlay.resetFixedPosition(); + function isOutside(event) { + if (event.clientY < Math.floor(bounds.top)) { + return true; } - - if (wtOverlays.bottomLeftCornerOverlay && wtOverlays.bottomLeftCornerOverlay.clone) { - wtOverlays.bottomLeftCornerOverlay.resetFixedPosition(); + if (event.clientY > Math.ceil(bounds.top + bounds.height)) { + return true; } - } - if (syncScroll) { - wtOverlays.syncScrollWithMaster(); - } - this.wot.drawn = true; - - return this; - } - }, { - key: '_doDraw', - value: function _doDraw() { - var wtRenderer = new _tableRenderer2.default(this); - - wtRenderer.render(); - } - }, { - key: 'removeClassFromCells', - value: function removeClassFromCells(className) { - var nodes = this.TABLE.querySelectorAll('.' + className); - - for (var i = 0, len = nodes.length; i < len; i++) { - (0, _element.removeClass)(nodes[i], className); - } - } - }, { - key: 'refreshSelections', - value: function refreshSelections(fastDraw) { - if (!this.wot.selections) { - return; - } - var len = this.wot.selections.length; - - if (fastDraw) { - for (var i = 0; i < len; i++) { - // there was no rerender, so we need to remove classNames by ourselves - if (this.wot.selections[i].settings.className) { - this.removeClassFromCells(this.wot.selections[i].settings.className); - } - if (this.wot.selections[i].settings.highlightHeaderClassName) { - this.removeClassFromCells(this.wot.selections[i].settings.highlightHeaderClassName); - } - if (this.wot.selections[i].settings.highlightRowClassName) { - this.removeClassFromCells(this.wot.selections[i].settings.highlightRowClassName); - } - if (this.wot.selections[i].settings.highlightColumnClassName) { - this.removeClassFromCells(this.wot.selections[i].settings.highlightColumnClassName); - } + if (event.clientX < Math.floor(bounds.left)) { + return true; + } + if (event.clientX > Math.ceil(bounds.left + bounds.width)) { + return true; } } - for (var _i = 0; _i < len; _i++) { - this.wot.selections[_i].draw(this.wot, fastDraw); + + function handler(event) { + if (isOutside(event)) { + _this.eventManager.removeEventListener(document.body, 'mousemove', handler); + parentElement.style.display = 'block'; + } } + + this.eventManager.addEventListener(document.body, 'mousemove', handler); } /** - * Get cell element at coords. + * Create border elements * - * @param {CellCoords} coords - * @returns {HTMLElement|Number} HTMLElement on success or Number one of the exit codes on error: - * -1 row before viewport - * -2 row after viewport + * @param {Object} settings */ }, { - key: 'getCell', - value: function getCell(coords) { - if (this.isRowBeforeRenderedRows(coords.row)) { - // row before rendered rows - return -1; - } else if (this.isRowAfterRenderedRows(coords.row)) { - // row after rendered rows - return -2; + key: 'createBorders', + value: function createBorders(settings) { + this.main = document.createElement('div'); + + var borderDivs = ['top', 'left', 'bottom', 'right', 'corner']; + var style = this.main.style; + style.position = 'absolute'; + style.top = 0; + style.left = 0; + + for (var i = 0; i < 5; i++) { + var position = borderDivs[i]; + var div = document.createElement('div'); + div.className = 'wtBorder ' + (this.settings.className || ''); // + borderDivs[i]; + + if (this.settings[position] && this.settings[position].hide) { + div.className += ' hidden'; + } + style = div.style; + style.backgroundColor = this.settings[position] && this.settings[position].color ? this.settings[position].color : settings.border.color; + style.height = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px'; + style.width = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px'; + + this.main.appendChild(div); } + this.top = this.main.childNodes[0]; + this.left = this.main.childNodes[1]; + this.bottom = this.main.childNodes[2]; + this.right = this.main.childNodes[3]; - var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(coords.row)]; + this.topStyle = this.top.style; + this.leftStyle = this.left.style; + this.bottomStyle = this.bottom.style; + this.rightStyle = this.right.style; - if (TR) { - return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(coords.col)]; + this.corner = this.main.childNodes[4]; + this.corner.className += ' corner'; + this.cornerStyle = this.corner.style; + this.cornerStyle.width = this.cornerDefaultStyle.width; + this.cornerStyle.height = this.cornerDefaultStyle.height; + this.cornerStyle.border = [this.cornerDefaultStyle.borderWidth, this.cornerDefaultStyle.borderStyle, this.cornerDefaultStyle.borderColor].join(' '); + + if ((0, _browser.isMobileBrowser)()) { + this.createMultipleSelectorHandles(); + } + this.disappear(); + + if (!this.wot.wtTable.bordersHolder) { + this.wot.wtTable.bordersHolder = document.createElement('div'); + this.wot.wtTable.bordersHolder.className = 'htBorders'; + this.wot.wtTable.spreader.appendChild(this.wot.wtTable.bordersHolder); } + this.wot.wtTable.bordersHolder.insertBefore(this.main, this.wot.wtTable.bordersHolder.firstChild); } /** - * getColumnHeader - * - * @param {Number} col Column index - * @param {Number} [level=0] Header level (0 = most distant to the table) - * @returns {Object} HTMLElement on success or undefined on error + * Create multiple selector handler for mobile devices */ }, { - key: 'getColumnHeader', - value: function getColumnHeader(col) { - var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + key: 'createMultipleSelectorHandles', + value: function createMultipleSelectorHandles() { + this.selectionHandles = { + topLeft: document.createElement('DIV'), + topLeftHitArea: document.createElement('DIV'), + bottomRight: document.createElement('DIV'), + bottomRightHitArea: document.createElement('DIV') + }; + var width = 10; + var hitAreaWidth = 40; - var TR = this.THEAD.childNodes[level]; + this.selectionHandles.topLeft.className = 'topLeftSelectionHandle'; + this.selectionHandles.topLeftHitArea.className = 'topLeftSelectionHandle-HitArea'; + this.selectionHandles.bottomRight.className = 'bottomRightSelectionHandle'; + this.selectionHandles.bottomRightHitArea.className = 'bottomRightSelectionHandle-HitArea'; - if (TR) { - return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(col)]; + this.selectionHandles.styles = { + topLeft: this.selectionHandles.topLeft.style, + topLeftHitArea: this.selectionHandles.topLeftHitArea.style, + bottomRight: this.selectionHandles.bottomRight.style, + bottomRightHitArea: this.selectionHandles.bottomRightHitArea.style + }; + + var hitAreaStyle = { + position: 'absolute', + height: hitAreaWidth + 'px', + width: hitAreaWidth + 'px', + 'border-radius': parseInt(hitAreaWidth / 1.5, 10) + 'px' + }; + + for (var prop in hitAreaStyle) { + if ((0, _object.hasOwnProperty)(hitAreaStyle, prop)) { + this.selectionHandles.styles.bottomRightHitArea[prop] = hitAreaStyle[prop]; + this.selectionHandles.styles.topLeftHitArea[prop] = hitAreaStyle[prop]; + } } - } - /** - * getRowHeader - * - * @param {Number} row Row index - * @returns {HTMLElement} HTMLElement on success or Number one of the exit codes on error: `null table doesn't have row headers` - */ + var handleStyle = { + position: 'absolute', + height: width + 'px', + width: width + 'px', + 'border-radius': parseInt(width / 1.5, 10) + 'px', + background: '#F5F5FF', + border: '1px solid #4285c8' + }; + for (var _prop in handleStyle) { + if ((0, _object.hasOwnProperty)(handleStyle, _prop)) { + this.selectionHandles.styles.bottomRight[_prop] = handleStyle[_prop]; + this.selectionHandles.styles.topLeft[_prop] = handleStyle[_prop]; + } + } + this.main.appendChild(this.selectionHandles.topLeft); + this.main.appendChild(this.selectionHandles.bottomRight); + this.main.appendChild(this.selectionHandles.topLeftHitArea); + this.main.appendChild(this.selectionHandles.bottomRightHitArea); + } }, { - key: 'getRowHeader', - value: function getRowHeader(row) { - if (this.columnFilter.sourceColumnToVisibleRowHeadedColumn(0) === 0) { - return null; + key: 'isPartRange', + value: function isPartRange(row, col) { + if (this.wot.selections.area.cellRange) { + if (row != this.wot.selections.area.cellRange.to.row || col != this.wot.selections.area.cellRange.to.col) { + return true; + } } - var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)]; - if (TR) { - return TR.childNodes[0]; - } + return false; } + }, { + key: 'updateMultipleSelectionHandlesPosition', + value: function updateMultipleSelectionHandlesPosition(row, col, top, left, width, height) { + var handleWidth = parseInt(this.selectionHandles.styles.topLeft.width, 10); + var hitAreaWidth = parseInt(this.selectionHandles.styles.topLeftHitArea.width, 10); - /** - * Returns cell coords object for a given TD (or a child element of a TD element). - * - * @param {HTMLTableCellElement} TD A cell DOM element (or a child of one). - * @returns {CellCoords|null} The coordinates of the provided TD element (or the closest TD element) or null, if the provided element is not applicable. - */ + this.selectionHandles.styles.topLeft.top = parseInt(top - handleWidth, 10) + 'px'; + this.selectionHandles.styles.topLeft.left = parseInt(left - handleWidth, 10) + 'px'; - }, { - key: 'getCoords', - value: function getCoords(TD) { - if (TD.nodeName !== 'TD' && TD.nodeName !== 'TH') { - TD = (0, _element.closest)(TD, ['TD', 'TH']); - } + this.selectionHandles.styles.topLeftHitArea.top = parseInt(top - hitAreaWidth / 4 * 3, 10) + 'px'; + this.selectionHandles.styles.topLeftHitArea.left = parseInt(left - hitAreaWidth / 4 * 3, 10) + 'px'; - if (TD === null) { - return null; - } + this.selectionHandles.styles.bottomRight.top = parseInt(top + height, 10) + 'px'; + this.selectionHandles.styles.bottomRight.left = parseInt(left + width, 10) + 'px'; - var TR = TD.parentNode; - var CONTAINER = TR.parentNode; - var row = (0, _element.index)(TR); - var col = TD.cellIndex; + this.selectionHandles.styles.bottomRightHitArea.top = parseInt(top + height - hitAreaWidth / 4, 10) + 'px'; + this.selectionHandles.styles.bottomRightHitArea.left = parseInt(left + width - hitAreaWidth / 4, 10) + 'px'; - if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_TOP, TD)) { - if (CONTAINER.nodeName === 'THEAD') { - row -= CONTAINER.childNodes.length; + if (this.settings.border.multipleSelectionHandlesVisible && this.settings.border.multipleSelectionHandlesVisible()) { + this.selectionHandles.styles.topLeft.display = 'block'; + this.selectionHandles.styles.topLeftHitArea.display = 'block'; + + if (this.isPartRange(row, col)) { + this.selectionHandles.styles.bottomRight.display = 'none'; + this.selectionHandles.styles.bottomRightHitArea.display = 'none'; + } else { + this.selectionHandles.styles.bottomRight.display = 'block'; + this.selectionHandles.styles.bottomRightHitArea.display = 'block'; } - } else if (CONTAINER === this.THEAD) { - row = this.rowFilter.visibleColHeadedRowToSourceRow(row); } else { - row = this.rowFilter.renderedToSource(row); + this.selectionHandles.styles.topLeft.display = 'none'; + this.selectionHandles.styles.bottomRight.display = 'none'; + this.selectionHandles.styles.topLeftHitArea.display = 'none'; + this.selectionHandles.styles.bottomRightHitArea.display = 'none'; } - if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_LEFT, TD)) { - col = this.columnFilter.offsettedTH(col); + if (row == this.wot.wtSettings.getSetting('fixedRowsTop') || col == this.wot.wtSettings.getSetting('fixedColumnsLeft')) { + this.selectionHandles.styles.topLeft.zIndex = '9999'; + this.selectionHandles.styles.topLeftHitArea.zIndex = '9999'; } else { - col = this.columnFilter.visibleRowHeadedColumnToSourceColumn(col); + this.selectionHandles.styles.topLeft.zIndex = ''; + this.selectionHandles.styles.topLeftHitArea.zIndex = ''; } - - return new _coords2.default(row, col); - } - }, { - key: 'getTrForRow', - value: function getTrForRow(row) { - return this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)]; - } - }, { - key: 'getFirstRenderedRow', - value: function getFirstRenderedRow() { - return this.wot.wtViewport.rowsRenderCalculator.startRow; - } - }, { - key: 'getFirstVisibleRow', - value: function getFirstVisibleRow() { - return this.wot.wtViewport.rowsVisibleCalculator.startRow; - } - }, { - key: 'getFirstRenderedColumn', - value: function getFirstRenderedColumn() { - return this.wot.wtViewport.columnsRenderCalculator.startColumn; } /** - * @returns {Number} Returns -1 if no row is visible + * Show border around one or many cells + * + * @param {Array} corners */ }, { - key: 'getFirstVisibleColumn', - value: function getFirstVisibleColumn() { - return this.wot.wtViewport.columnsVisibleCalculator.startColumn; - } + key: 'appear', + value: function appear(corners) { + if (this.disabled) { + return; + } + var isMultiple, fromTD, toTD, fromOffset, toOffset, containerOffset, top, minTop, left, minLeft, height, width, fromRow, fromColumn, toRow, toColumn, trimmingContainer, cornerOverlappingContainer, ilen; - /** - * @returns {Number} Returns -1 if no row is visible - */ + ilen = this.wot.wtTable.getRenderedRowsCount(); - }, { - key: 'getLastRenderedRow', - value: function getLastRenderedRow() { - return this.wot.wtViewport.rowsRenderCalculator.endRow; - } - }, { - key: 'getLastVisibleRow', - value: function getLastVisibleRow() { - return this.wot.wtViewport.rowsVisibleCalculator.endRow; - } - }, { - key: 'getLastRenderedColumn', - value: function getLastRenderedColumn() { - return this.wot.wtViewport.columnsRenderCalculator.endColumn; - } + for (var i = 0; i < ilen; i++) { + var s = this.wot.wtTable.rowFilter.renderedToSource(i); - /** - * @returns {Number} Returns -1 if no column is visible - */ + if (s >= corners[0] && s <= corners[2]) { + fromRow = s; + break; + } + } - }, { - key: 'getLastVisibleColumn', - value: function getLastVisibleColumn() { - return this.wot.wtViewport.columnsVisibleCalculator.endColumn; - } - }, { - key: 'isRowBeforeRenderedRows', - value: function isRowBeforeRenderedRows(row) { - return this.rowFilter && this.rowFilter.sourceToRendered(row) < 0 && row >= 0; - } - }, { - key: 'isRowAfterViewport', - value: function isRowAfterViewport(row) { - return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastVisibleRow(); - } - }, { - key: 'isRowAfterRenderedRows', - value: function isRowAfterRenderedRows(row) { - return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastRenderedRow(); - } - }, { - key: 'isColumnBeforeViewport', - value: function isColumnBeforeViewport(column) { - return this.columnFilter && this.columnFilter.sourceToRendered(column) < 0 && column >= 0; - } - }, { - key: 'isColumnAfterViewport', - value: function isColumnAfterViewport(column) { - return this.columnFilter && this.columnFilter.sourceToRendered(column) > this.getLastVisibleColumn(); - } - }, { - key: 'isLastRowFullyVisible', - value: function isLastRowFullyVisible() { - return this.getLastVisibleRow() === this.getLastRenderedRow(); - } - }, { - key: 'isLastColumnFullyVisible', - value: function isLastColumnFullyVisible() { - return this.getLastVisibleColumn() === this.getLastRenderedColumn(); - } - }, { - key: 'getRenderedColumnsCount', - value: function getRenderedColumnsCount() { - var columnsCount = this.wot.wtViewport.columnsRenderCalculator.count; - var totalColumns = this.wot.getSetting('totalColumns'); + for (var _i = ilen - 1; _i >= 0; _i--) { + var _s = this.wot.wtTable.rowFilter.renderedToSource(_i); - if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) { - columnsCount = totalColumns; - } else if (this.wot.isOverlayName(_base2.default.CLONE_LEFT) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) { - return Math.min(this.wot.getSetting('fixedColumnsLeft'), totalColumns); + if (_s >= corners[0] && _s <= corners[2]) { + toRow = _s; + break; + } } - return columnsCount; - } - }, { - key: 'getRenderedRowsCount', - value: function getRenderedRowsCount() { - var rowsCount = this.wot.wtViewport.rowsRenderCalculator.count; - var totalRows = this.wot.getSetting('totalRows'); + ilen = this.wot.wtTable.getRenderedColumnsCount(); - if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) { - rowsCount = totalRows; - } else if (this.wot.isOverlayName(_base2.default.CLONE_TOP) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER)) { - rowsCount = Math.min(this.wot.getSetting('fixedRowsTop'), totalRows); - } else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) { - rowsCount = Math.min(this.wot.getSetting('fixedRowsBottom'), totalRows); - } + for (var _i2 = 0; _i2 < ilen; _i2++) { + var _s2 = this.wot.wtTable.columnFilter.renderedToSource(_i2); - return rowsCount; - } - }, { - key: 'getVisibleRowsCount', - value: function getVisibleRowsCount() { - return this.wot.wtViewport.rowsVisibleCalculator.count; - } - }, { - key: 'allRowsInViewport', - value: function allRowsInViewport() { - return this.wot.getSetting('totalRows') == this.getVisibleRowsCount(); - } + if (_s2 >= corners[1] && _s2 <= corners[3]) { + fromColumn = _s2; + break; + } + } - /** - * Checks if any of the row's cells content exceeds its initial height, and if so, returns the oversized height - * - * @param {Number} sourceRow - * @returns {Number} - */ + for (var _i3 = ilen - 1; _i3 >= 0; _i3--) { + var _s3 = this.wot.wtTable.columnFilter.renderedToSource(_i3); - }, { - key: 'getRowHeight', - value: function getRowHeight(sourceRow) { - var height = this.wot.wtSettings.settings.rowHeight(sourceRow); - var oversizedHeight = this.wot.wtViewport.oversizedRows[sourceRow]; + if (_s3 >= corners[1] && _s3 <= corners[3]) { + toColumn = _s3; + break; + } + } + if (fromRow === void 0 || fromColumn === void 0) { + this.disappear(); - if (oversizedHeight !== void 0) { - height = height === void 0 ? oversizedHeight : Math.max(height, oversizedHeight); + return; } + isMultiple = fromRow !== toRow || fromColumn !== toColumn; + fromTD = this.wot.wtTable.getCell(new _coords2.default(fromRow, fromColumn)); + toTD = isMultiple ? this.wot.wtTable.getCell(new _coords2.default(toRow, toColumn)) : fromTD; + fromOffset = (0, _element.offset)(fromTD); + toOffset = isMultiple ? (0, _element.offset)(toTD) : fromOffset; + containerOffset = (0, _element.offset)(this.wot.wtTable.TABLE); - return height; - } - }, { - key: 'getColumnHeaderHeight', - value: function getColumnHeaderHeight(level) { - var height = this.wot.wtSettings.settings.defaultRowHeight; - var oversizedHeight = this.wot.wtViewport.oversizedColumnHeaders[level]; + minTop = fromOffset.top; + height = toOffset.top + (0, _element.outerHeight)(toTD) - minTop; + minLeft = fromOffset.left; + width = toOffset.left + (0, _element.outerWidth)(toTD) - minLeft; - if (oversizedHeight !== void 0) { - height = height ? Math.max(height, oversizedHeight) : oversizedHeight; + top = minTop - containerOffset.top - 1; + left = minLeft - containerOffset.left - 1; + var style = (0, _element.getComputedStyle)(fromTD); + + if (parseInt(style.borderTopWidth, 10) > 0) { + top += 1; + height = height > 0 ? height - 1 : 0; + } + if (parseInt(style.borderLeftWidth, 10) > 0) { + left += 1; + width = width > 0 ? width - 1 : 0; } - return height; - } - }, { - key: 'getVisibleColumnsCount', - value: function getVisibleColumnsCount() { - return this.wot.wtViewport.columnsVisibleCalculator.count; - } - }, { - key: 'allColumnsInViewport', - value: function allColumnsInViewport() { - return this.wot.getSetting('totalColumns') == this.getVisibleColumnsCount(); - } - }, { - key: 'getColumnWidth', - value: function getColumnWidth(sourceColumn) { - var width = this.wot.wtSettings.settings.columnWidth; + this.topStyle.top = top + 'px'; + this.topStyle.left = left + 'px'; + this.topStyle.width = width + 'px'; + this.topStyle.display = 'block'; - if (typeof width === 'function') { - width = width(sourceColumn); - } else if ((typeof width === 'undefined' ? 'undefined' : _typeof(width)) === 'object') { - width = width[sourceColumn]; - } + this.leftStyle.top = top + 'px'; + this.leftStyle.left = left + 'px'; + this.leftStyle.height = height + 'px'; + this.leftStyle.display = 'block'; - return width || this.wot.wtSettings.settings.defaultColumnWidth; - } - }, { - key: 'getStretchedColumnWidth', - value: function getStretchedColumnWidth(sourceColumn) { - var columnWidth = this.getColumnWidth(sourceColumn); - var width = columnWidth == null ? this.instance.wtSettings.settings.defaultColumnWidth : columnWidth; - var calculator = this.wot.wtViewport.columnsRenderCalculator; + var delta = Math.floor(this.settings.border.width / 2); - if (calculator) { - var stretchedWidth = calculator.getStretchedColumnWidth(sourceColumn, width); + this.bottomStyle.top = top + height - delta + 'px'; + this.bottomStyle.left = left + 'px'; + this.bottomStyle.width = width + 'px'; + this.bottomStyle.display = 'block'; - if (stretchedWidth) { - width = stretchedWidth; + this.rightStyle.top = top + 'px'; + this.rightStyle.left = left + width - delta + 'px'; + this.rightStyle.height = height + 1 + 'px'; + this.rightStyle.display = 'block'; + + if ((0, _browser.isMobileBrowser)() || !this.hasSetting(this.settings.border.cornerVisible) || this.isPartRange(toRow, toColumn)) { + this.cornerStyle.display = 'none'; + } else { + this.cornerStyle.top = top + height - 4 + 'px'; + this.cornerStyle.left = left + width - 4 + 'px'; + this.cornerStyle.borderRightWidth = this.cornerDefaultStyle.borderWidth; + this.cornerStyle.width = this.cornerDefaultStyle.width; + + // Hide the fill handle, so the possible further adjustments won't force unneeded scrollbars. + this.cornerStyle.display = 'none'; + + trimmingContainer = (0, _element.getTrimmingContainer)(this.wot.wtTable.TABLE); + + if (toColumn === this.wot.getSetting('totalColumns') - 1) { + cornerOverlappingContainer = toTD.offsetLeft + (0, _element.outerWidth)(toTD) + parseInt(this.cornerDefaultStyle.width, 10) / 2 >= (0, _element.innerWidth)(trimmingContainer); + + if (cornerOverlappingContainer) { + this.cornerStyle.left = Math.floor(left + width - 3 - parseInt(this.cornerDefaultStyle.width, 10) / 2) + 'px'; + this.cornerStyle.borderRightWidth = 0; + } + } + + if (toRow === this.wot.getSetting('totalRows') - 1) { + cornerOverlappingContainer = toTD.offsetTop + (0, _element.outerHeight)(toTD) + parseInt(this.cornerDefaultStyle.height, 10) / 2 >= (0, _element.innerHeight)(trimmingContainer); + + if (cornerOverlappingContainer) { + this.cornerStyle.top = Math.floor(top + height - 3 - parseInt(this.cornerDefaultStyle.height, 10) / 2) + 'px'; + this.cornerStyle.borderBottomWidth = 0; + } } + + this.cornerStyle.display = 'block'; } - return width; + if ((0, _browser.isMobileBrowser)()) { + this.updateMultipleSelectionHandlesPosition(fromRow, fromColumn, top, left, width, height); + } } /** - * Modify row header widths provided by user in class contructor. - * - * @private + * Hide border */ }, { - key: '_modifyRowHeaderWidth', - value: function _modifyRowHeaderWidth(rowHeaderWidthFactory) { - var widths = (0, _function.isFunction)(rowHeaderWidthFactory) ? rowHeaderWidthFactory() : null; + key: 'disappear', + value: function disappear() { + this.topStyle.display = 'none'; + this.leftStyle.display = 'none'; + this.bottomStyle.display = 'none'; + this.rightStyle.display = 'none'; + this.cornerStyle.display = 'none'; - if (Array.isArray(widths)) { - widths = [].concat(_toConsumableArray(widths)); - widths[widths.length - 1] = this._correctRowHeaderWidth(widths[widths.length - 1]); - } else { - widths = this._correctRowHeaderWidth(widths); + if ((0, _browser.isMobileBrowser)()) { + this.selectionHandles.styles.topLeft.display = 'none'; + this.selectionHandles.styles.bottomRight.display = 'none'; } - - return widths; } /** - * Correct row header width if necessary. - * - * @private + * @param {Function} setting + * @returns {*} */ }, { - key: '_correctRowHeaderWidth', - value: function _correctRowHeaderWidth(width) { - if (typeof width !== 'number') { - width = this.wot.getSetting('defaultColumnWidth'); - } - if (this.correctHeaderWidth) { - width++; + key: 'hasSetting', + value: function hasSetting(setting) { + if (typeof setting === 'function') { + return setting(); } - return width; + return !!setting; } }]); - return Table; + return Border; }(); -exports.default = Table; +exports.default = Border; /***/ }), -/* 147 */ +/* 168 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -39451,1753 +38678,3131 @@ exports.default = Table; exports.__esModule = true; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _unicode = __webpack_require__(17); + +var _mixed = __webpack_require__(22); + +var _string = __webpack_require__(32); + +var _array = __webpack_require__(2); var _element = __webpack_require__(0); -var _base = __webpack_require__(28); +var _handsontableEditor = __webpack_require__(169); -var _base2 = _interopRequireDefault(_base); +var _handsontableEditor2 = _interopRequireDefault(_handsontableEditor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var performanceWarningAppeared = false; +var AutocompleteEditor = _handsontableEditor2.default.prototype.extend(); /** - * @class TableRenderer + * @private + * @editor AutocompleteEditor + * @class AutocompleteEditor + * @dependencies HandsontableEditor */ +AutocompleteEditor.prototype.init = function () { + _handsontableEditor2.default.prototype.init.apply(this, arguments); + this.query = null; + this.strippedChoices = []; + this.rawChoices = []; +}; -var TableRenderer = function () { - /** - * @param {WalkontableTable} wtTable - */ - function TableRenderer(wtTable) { - _classCallCheck(this, TableRenderer); - - this.wtTable = wtTable; - this.wot = wtTable.instance; - - // legacy support - this.instance = wtTable.instance; +AutocompleteEditor.prototype.getValue = function () { + var _this2 = this; - this.rowFilter = wtTable.rowFilter; - this.columnFilter = wtTable.columnFilter; + var selectedValue = this.rawChoices.find(function (value) { + var strippedValue = _this2.stripValueIfNeeded(value); - this.TABLE = wtTable.TABLE; - this.THEAD = wtTable.THEAD; - this.TBODY = wtTable.TBODY; - this.COLGROUP = wtTable.COLGROUP; + return strippedValue === _this2.TEXTAREA.value; + }); - this.rowHeaders = []; - this.rowHeaderCount = 0; - this.columnHeaders = []; - this.columnHeaderCount = 0; - this.fixedRowsTop = 0; - this.fixedRowsBottom = 0; + if ((0, _mixed.isDefined)(selectedValue)) { + return selectedValue; } - /** - * - */ + return this.TEXTAREA.value; +}; +AutocompleteEditor.prototype.createElements = function () { + _handsontableEditor2.default.prototype.createElements.apply(this, arguments); - _createClass(TableRenderer, [{ - key: 'render', - value: function render() { - if (!this.wtTable.isWorkingOnClone()) { - var skipRender = {}; - this.wot.getSetting('beforeDraw', true, skipRender); + (0, _element.addClass)(this.htContainer, 'autocompleteEditor'); + (0, _element.addClass)(this.htContainer, window.navigator.platform.indexOf('Mac') === -1 ? '' : 'htMacScroll'); +}; - if (skipRender.skipRender === true) { - return; - } - } +var skipOne = false; +function onBeforeKeyDown(event) { + skipOne = false; + var editor = this.getActiveEditor(); - this.rowHeaders = this.wot.getSetting('rowHeaders'); - this.rowHeaderCount = this.rowHeaders.length; - this.fixedRowsTop = this.wot.getSetting('fixedRowsTop'); - this.fixedRowsBottom = this.wot.getSetting('fixedRowsBottom'); - this.columnHeaders = this.wot.getSetting('columnHeaders'); - this.columnHeaderCount = this.columnHeaders.length; + if ((0, _unicode.isPrintableChar)(event.keyCode) || event.keyCode === _unicode.KEY_CODES.BACKSPACE || event.keyCode === _unicode.KEY_CODES.DELETE || event.keyCode === _unicode.KEY_CODES.INSERT) { + var timeOffset = 0; - var columnsToRender = this.wtTable.getRenderedColumnsCount(); - var rowsToRender = this.wtTable.getRenderedRowsCount(); - var totalColumns = this.wot.getSetting('totalColumns'); - var totalRows = this.wot.getSetting('totalRows'); - var workspaceWidth = void 0; - var adjusted = false; + // on ctl+c / cmd+c don't update suggestion list + if (event.keyCode === _unicode.KEY_CODES.C && (event.ctrlKey || event.metaKey)) { + return; + } + if (!editor.isOpened()) { + timeOffset += 10; + } - if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) { + if (editor.htEditor) { + editor.instance._registerTimeout(setTimeout(function () { + editor.queryChoices(editor.TEXTAREA.value); + skipOne = true; + }, timeOffset)); + } + } +} - // do NOT render headers on the bottom or bottom-left corner overlay - this.columnHeaders = []; - this.columnHeaderCount = 0; - } +AutocompleteEditor.prototype.prepare = function () { + this.instance.addHook('beforeKeyDown', onBeforeKeyDown); + _handsontableEditor2.default.prototype.prepare.apply(this, arguments); +}; - if (totalColumns >= 0) { - // prepare COL and TH elements for rendering - this.adjustAvailableNodes(); - adjusted = true; +AutocompleteEditor.prototype.open = function () { + // Ugly fix for handsontable which grab window object for autocomplete scroll listener instead table element. + this.TEXTAREA_PARENT.style.overflow = 'auto'; + _handsontableEditor2.default.prototype.open.apply(this, arguments); + this.TEXTAREA_PARENT.style.overflow = ''; - // adjust column widths according to user widths settings - this.renderColumnHeaders(); + var choicesListHot = this.htEditor.getInstance(); + var _this = this; + var trimDropdown = this.cellProperties.trimDropdown === void 0 ? true : this.cellProperties.trimDropdown; - // Render table rows - this.renderRows(totalRows, rowsToRender, columnsToRender); + this.TEXTAREA.style.visibility = 'visible'; + this.focus(); - if (!this.wtTable.isWorkingOnClone()) { - workspaceWidth = this.wot.wtViewport.getWorkspaceWidth(); - this.wot.wtViewport.containerWidth = null; - } + choicesListHot.updateSettings({ + colWidths: trimDropdown ? [(0, _element.outerWidth)(this.TEXTAREA) - 2] : void 0, + width: trimDropdown ? (0, _element.outerWidth)(this.TEXTAREA) + (0, _element.getScrollbarWidth)() + 2 : void 0, + afterRenderer: function afterRenderer(TD, row, col, prop, value, cellProperties) { + var _this$cellProperties = _this.cellProperties, + filteringCaseSensitive = _this$cellProperties.filteringCaseSensitive, + allowHtml = _this$cellProperties.allowHtml; - this.adjustColumnWidths(columnsToRender); - this.markOversizedColumnHeaders(); - this.adjustColumnHeaderHeights(); - } + var indexOfMatch = void 0; + var match = void 0; - if (!adjusted) { - this.adjustAvailableNodes(); - } - this.removeRedundantRows(rowsToRender); + value = (0, _mixed.stringify)(value); - if (!this.wtTable.isWorkingOnClone() || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) { - this.markOversizedRows(); + if (value && !allowHtml) { + indexOfMatch = filteringCaseSensitive === true ? value.indexOf(this.query) : value.toLowerCase().indexOf(_this.query.toLowerCase()); + + if (indexOfMatch !== -1) { + match = value.substr(indexOfMatch, _this.query.length); + value = value.replace(match, '' + match + ''); + } } - if (!this.wtTable.isWorkingOnClone()) { - this.wot.wtViewport.createVisibleCalculators(); - this.wot.wtOverlays.refresh(false); + TD.innerHTML = value; + }, - this.wot.wtOverlays.applyToDOM(); + autoColumnSize: true, + modifyColWidth: function modifyColWidth(width, col) { + // workaround for text overlapping the dropdown, not really accurate + var autoWidths = this.getPlugin('autoColumnSize').widths; - var hiderWidth = (0, _element.outerWidth)(this.wtTable.hider); - var tableWidth = (0, _element.outerWidth)(this.wtTable.TABLE); + if (autoWidths[col]) { + width = autoWidths[col]; + } - if (hiderWidth !== 0 && tableWidth !== hiderWidth) { - // Recalculate the column widths, if width changes made in the overlays removed the scrollbar, thus changing the viewport width. - this.adjustColumnWidths(columnsToRender); - } + return trimDropdown ? width : width + 15; + } + }); - if (workspaceWidth !== this.wot.wtViewport.getWorkspaceWidth()) { - // workspace width changed though to shown/hidden vertical scrollbar. Let's reapply stretching - this.wot.wtViewport.containerWidth = null; + // Add additional space for autocomplete holder + this.htEditor.view.wt.wtTable.holder.parentNode.style['padding-right'] = (0, _element.getScrollbarWidth)() + 2 + 'px'; - var firstRendered = this.wtTable.getFirstRenderedColumn(); - var lastRendered = this.wtTable.getLastRenderedColumn(); - var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth'); - var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth'); + if (skipOne) { + skipOne = false; + } - rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting); + _this.instance._registerTimeout(setTimeout(function () { + _this.queryChoices(_this.TEXTAREA.value); + }, 0)); +}; - if (rowHeaderWidthSetting != null) { - for (var i = 0; i < this.rowHeaderCount; i++) { - var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting; +AutocompleteEditor.prototype.close = function () { + _handsontableEditor2.default.prototype.close.apply(this, arguments); +}; +AutocompleteEditor.prototype.queryChoices = function (query) { + var _this3 = this; - width = width == null ? defaultColumnWidth : width; + this.query = query; + var source = this.cellProperties.source; - this.COLGROUP.childNodes[i].style.width = width + 'px'; - } - } + if (typeof source == 'function') { + source.call(this.cellProperties, query, function (choices) { + _this3.rawChoices = choices; + _this3.updateChoicesList(_this3.stripValuesIfNeeded(choices)); + }); + } else if (Array.isArray(source)) { + this.rawChoices = source; + this.updateChoicesList(this.stripValuesIfNeeded(source)); + } else { + this.updateChoicesList([]); + } +}; - for (var _i = firstRendered; _i < lastRendered; _i++) { - var _width = this.wtTable.getStretchedColumnWidth(_i); - var renderedIndex = this.columnFilter.sourceToRendered(_i); +AutocompleteEditor.prototype.updateChoicesList = function (choices) { + var pos = (0, _element.getCaretPosition)(this.TEXTAREA); + var endPos = (0, _element.getSelectionEndPosition)(this.TEXTAREA); + var sortByRelevanceSetting = this.cellProperties.sortByRelevance; + var filterSetting = this.cellProperties.filter; + var orderByRelevance = null; + var highlightIndex = null; - this.COLGROUP.childNodes[renderedIndex + this.rowHeaderCount].style.width = _width + 'px'; - } - } + if (sortByRelevanceSetting) { + orderByRelevance = AutocompleteEditor.sortByRelevance(this.stripValueIfNeeded(this.getValue()), choices, this.cellProperties.filteringCaseSensitive); + } + var orderByRelevanceLength = Array.isArray(orderByRelevance) ? orderByRelevance.length : 0; - this.wot.getSetting('onDraw', true); - } else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) { - this.wot.cloneSource.wtOverlays.adjustElementsSize(); - } + if (filterSetting === false) { + if (orderByRelevanceLength) { + highlightIndex = orderByRelevance[0]; } + } else { + var sorted = []; - /** - * @param {Number} renderedRowsCount - */ - - }, { - key: 'removeRedundantRows', - value: function removeRedundantRows(renderedRowsCount) { - while (this.wtTable.tbodyChildrenLength > renderedRowsCount) { - this.TBODY.removeChild(this.TBODY.lastChild); - this.wtTable.tbodyChildrenLength--; + for (var i = 0, choicesCount = choices.length; i < choicesCount; i++) { + if (sortByRelevanceSetting && orderByRelevanceLength <= i) { + break; + } + if (orderByRelevanceLength) { + sorted.push(choices[orderByRelevance[i]]); + } else { + sorted.push(choices[i]); } } - /** - * @param {Number} totalRows - * @param {Number} rowsToRender - * @param {Number} columnsToRender - */ + highlightIndex = 0; + choices = sorted; + } - }, { - key: 'renderRows', - value: function renderRows(totalRows, rowsToRender, columnsToRender) { - var lastTD = void 0, - TR = void 0; - var visibleRowIndex = 0; - var sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex); - var isWorkingOnClone = this.wtTable.isWorkingOnClone(); + this.strippedChoices = choices; + this.htEditor.loadData((0, _array.pivot)([choices])); - while (sourceRowIndex < totalRows && sourceRowIndex >= 0) { - if (!performanceWarningAppeared && visibleRowIndex > 1000) { - performanceWarningAppeared = true; - console.warn('Performance tip: Handsontable rendered more than 1000 visible rows. Consider limiting the number ' + 'of rendered rows by specifying the table height and/or turning off the "renderAllRows" option.'); - } - if (rowsToRender !== void 0 && visibleRowIndex === rowsToRender) { - // We have as much rows as needed for this clone - break; - } - TR = this.getOrCreateTrForRow(visibleRowIndex, TR); + this.updateDropdownHeight(); - // Render row headers - this.renderRowHeaders(sourceRowIndex, TR); - // Add and/or remove TDs to TR to match the desired number - this.adjustColumns(TR, columnsToRender + this.rowHeaderCount); + this.flipDropdownIfNeeded(); - lastTD = this.renderCells(sourceRowIndex, TR, columnsToRender); + if (this.cellProperties.strict === true) { + this.highlightBestMatchingChoice(highlightIndex); + } - if (!isWorkingOnClone || - // Necessary to refresh oversized row heights after editing cell in overlays - this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) { - // Reset the oversized row cache for this row - this.resetOversizedRow(sourceRowIndex); - } + this.instance.listen(); + this.TEXTAREA.focus(); + (0, _element.setCaretPosition)(this.TEXTAREA, pos, pos === endPos ? void 0 : endPos); +}; - if (TR.firstChild) { - // if I have 2 fixed columns with one-line content and the 3rd column has a multiline content, this is - // the way to make sure that the overlay will has same row height - var height = this.wot.wtTable.getRowHeight(sourceRowIndex); +AutocompleteEditor.prototype.flipDropdownIfNeeded = function () { + var textareaOffset = (0, _element.offset)(this.TEXTAREA); + var textareaHeight = (0, _element.outerHeight)(this.TEXTAREA); + var dropdownHeight = this.getDropdownHeight(); + var trimmingContainer = (0, _element.getTrimmingContainer)(this.instance.view.wt.wtTable.TABLE); + var trimmingContainerScrollTop = trimmingContainer.scrollTop; + var headersHeight = (0, _element.outerHeight)(this.instance.view.wt.wtTable.THEAD); + var containerOffset = { + row: 0, + col: 0 + }; - if (height) { - // Decrease height. 1 pixel will be "replaced" by 1px border top - height--; - TR.firstChild.style.height = height + 'px'; - } else { - TR.firstChild.style.height = ''; - } - } - visibleRowIndex++; - sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex); - } - } + if (trimmingContainer !== window) { + containerOffset = (0, _element.offset)(trimmingContainer); + } - /** - * Reset the oversized row cache for the provided index - * - * @param {Number} sourceRow Row index - */ + var spaceAbove = textareaOffset.top - containerOffset.top - headersHeight + trimmingContainerScrollTop; + var spaceBelow = trimmingContainer.scrollHeight - spaceAbove - headersHeight - textareaHeight; + var flipNeeded = dropdownHeight > spaceBelow && spaceAbove > spaceBelow; - }, { - key: 'resetOversizedRow', - value: function resetOversizedRow(sourceRow) { - if (this.wot.getSetting('externalRowCalculator')) { - return; - } - if (this.wot.wtViewport.oversizedRows && this.wot.wtViewport.oversizedRows[sourceRow]) { - this.wot.wtViewport.oversizedRows[sourceRow] = void 0; - } - } + if (flipNeeded) { + this.flipDropdown(dropdownHeight); + } else { + this.unflipDropdown(); + } - /** - * Check if any of the rendered rows is higher than expected, and if so, cache them - */ + this.limitDropdownIfNeeded(flipNeeded ? spaceAbove : spaceBelow, dropdownHeight); - }, { - key: 'markOversizedRows', - value: function markOversizedRows() { - if (this.wot.getSetting('externalRowCalculator')) { - return; - } - var rowCount = this.instance.wtTable.TBODY.childNodes.length; - var expectedTableHeight = rowCount * this.instance.wtSettings.settings.defaultRowHeight; - var actualTableHeight = (0, _element.innerHeight)(this.instance.wtTable.TBODY) - 1; - var previousRowHeight = void 0; - var rowInnerHeight = void 0; - var sourceRowIndex = void 0; - var currentTr = void 0; - var rowHeader = void 0; - var totalRows = this.instance.getSetting('totalRows'); + return flipNeeded; +}; - if (expectedTableHeight === actualTableHeight && !this.instance.getSetting('fixedRowsBottom')) { - // If the actual table height equals rowCount * default single row height, no row is oversized -> no need to iterate over them - return; - } +AutocompleteEditor.prototype.limitDropdownIfNeeded = function (spaceAvailable, dropdownHeight) { + if (dropdownHeight > spaceAvailable) { + var tempHeight = 0; + var i = 0; + var lastRowHeight = 0; + var height = null; - while (rowCount) { - rowCount--; - sourceRowIndex = this.instance.wtTable.rowFilter.renderedToSource(rowCount); - previousRowHeight = this.instance.wtTable.getRowHeight(sourceRowIndex); - currentTr = this.instance.wtTable.getTrForRow(sourceRowIndex); - rowHeader = currentTr.querySelector('th'); + do { + lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view.wt.wtSettings.settings.defaultRowHeight; + tempHeight += lastRowHeight; + i++; + } while (tempHeight < spaceAvailable); - if (rowHeader) { - rowInnerHeight = (0, _element.innerHeight)(rowHeader); - } else { - rowInnerHeight = (0, _element.innerHeight)(currentTr) - 1; - } + height = tempHeight - lastRowHeight; - if (!previousRowHeight && this.instance.wtSettings.settings.defaultRowHeight < rowInnerHeight || previousRowHeight < rowInnerHeight) { - this.instance.wtViewport.oversizedRows[sourceRowIndex] = ++rowInnerHeight; - } - } + if (this.htEditor.flipped) { + this.htEditor.rootElement.style.top = parseInt(this.htEditor.rootElement.style.top, 10) + dropdownHeight - height + 'px'; } - /** - * Check if any of the rendered columns is higher than expected, and if so, cache them. - */ + this.setDropdownHeight(tempHeight - lastRowHeight); + } +}; - }, { - key: 'markOversizedColumnHeaders', - value: function markOversizedColumnHeaders() { - var overlayName = this.wot.getOverlayName(); +AutocompleteEditor.prototype.flipDropdown = function (dropdownHeight) { + var dropdownStyle = this.htEditor.rootElement.style; - if (!this.columnHeaderCount || this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] || this.wtTable.isWorkingOnClone()) { - return; - } - var columnCount = this.wtTable.getRenderedColumnsCount(); + dropdownStyle.position = 'absolute'; + dropdownStyle.top = -dropdownHeight + 'px'; - for (var i = 0; i < this.columnHeaderCount; i++) { - for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) { - this.markIfOversizedColumnHeader(renderedColumnIndex); - } - } - this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] = true; - } + this.htEditor.flipped = true; +}; - /** - * - */ +AutocompleteEditor.prototype.unflipDropdown = function () { + var dropdownStyle = this.htEditor.rootElement.style; - }, { - key: 'adjustColumnHeaderHeights', - value: function adjustColumnHeaderHeights() { - var columnHeaders = this.wot.getSetting('columnHeaders'); - var children = this.wot.wtTable.THEAD.childNodes; - var oversizedColumnHeaders = this.wot.wtViewport.oversizedColumnHeaders; + if (dropdownStyle.position === 'absolute') { + dropdownStyle.position = ''; + dropdownStyle.top = ''; + } - for (var i = 0, len = columnHeaders.length; i < len; i++) { - if (oversizedColumnHeaders[i]) { - if (!children[i] || children[i].childNodes.length === 0) { - return; - } - children[i].childNodes[0].style.height = oversizedColumnHeaders[i] + 'px'; - } - } - } + this.htEditor.flipped = void 0; +}; - /** - * Check if column header for the specified column is higher than expected, and if so, cache it - * - * @param {Number} col Index of column - */ +AutocompleteEditor.prototype.updateDropdownHeight = function () { + var currentDropdownWidth = this.htEditor.getColWidth(0) + (0, _element.getScrollbarWidth)() + 2; + var trimDropdown = this.cellProperties.trimDropdown; - }, { - key: 'markIfOversizedColumnHeader', - value: function markIfOversizedColumnHeader(col) { - var sourceColIndex = this.wot.wtTable.columnFilter.renderedToSource(col); - var level = this.columnHeaderCount; - var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight; - var previousColHeaderHeight = void 0; - var currentHeader = void 0; - var currentHeaderHeight = void 0; - var columnHeaderHeightSetting = this.wot.getSetting('columnHeaderHeight') || []; + this.htEditor.updateSettings({ + height: this.getDropdownHeight(), + width: trimDropdown ? void 0 : currentDropdownWidth + }); - while (level) { - level--; + this.htEditor.view.wt.wtTable.alignOverlaysWithTrimmingContainer(); +}; - previousColHeaderHeight = this.wot.wtTable.getColumnHeaderHeight(level); - currentHeader = this.wot.wtTable.getColumnHeader(sourceColIndex, level); +AutocompleteEditor.prototype.setDropdownHeight = function (height) { + this.htEditor.updateSettings({ + height: height + }); +}; - if (!currentHeader) { - /* eslint-disable no-continue */ - continue; - } - currentHeaderHeight = (0, _element.innerHeight)(currentHeader); +AutocompleteEditor.prototype.finishEditing = function (restoreOriginalValue) { + if (!restoreOriginalValue) { + this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); + } + _handsontableEditor2.default.prototype.finishEditing.apply(this, arguments); +}; - if (!previousColHeaderHeight && defaultRowHeight < currentHeaderHeight || previousColHeaderHeight < currentHeaderHeight) { - this.wot.wtViewport.oversizedColumnHeaders[level] = currentHeaderHeight; - } +AutocompleteEditor.prototype.highlightBestMatchingChoice = function (index) { + if (typeof index === 'number') { + this.htEditor.selectCell(index, 0); + } else { + this.htEditor.deselectCell(); + } +}; - if (Array.isArray(columnHeaderHeightSetting)) { - if (columnHeaderHeightSetting[level] != null) { - this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level]; - } - } else if (!isNaN(columnHeaderHeightSetting)) { - this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting; - } +/** + * Filters and sorts by relevance + * @param value + * @param choices + * @param caseSensitive + * @returns {Array} array of indexes in original choices array + */ +AutocompleteEditor.sortByRelevance = function (value, choices, caseSensitive) { + var choicesRelevance = []; + var currentItem = void 0; + var valueLength = value.length; + var valueIndex = void 0; + var charsLeft = void 0; + var result = []; + var i = void 0; + var choicesCount = choices.length; - if (this.wot.wtViewport.oversizedColumnHeaders[level] < (columnHeaderHeightSetting[level] || columnHeaderHeightSetting)) { - this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level] || columnHeaderHeightSetting; - } - } + if (valueLength === 0) { + for (i = 0; i < choicesCount; i++) { + result.push(i); } + return result; + } - /** - * @param {Number} sourceRowIndex - * @param {HTMLTableRowElement} TR - * @param {Number} columnsToRender - * @returns {HTMLTableCellElement} - */ - - }, { - key: 'renderCells', - value: function renderCells(sourceRowIndex, TR, columnsToRender) { - var TD = void 0; - var sourceColIndex = void 0; + for (i = 0; i < choicesCount; i++) { + currentItem = (0, _string.stripTags)((0, _mixed.stringify)(choices[i])); - for (var visibleColIndex = 0; visibleColIndex < columnsToRender; visibleColIndex++) { - sourceColIndex = this.columnFilter.renderedToSource(visibleColIndex); + if (caseSensitive) { + valueIndex = currentItem.indexOf(value); + } else { + valueIndex = currentItem.toLowerCase().indexOf(value.toLowerCase()); + } - if (visibleColIndex === 0) { - TD = TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(sourceColIndex)]; - } else { - TD = TD.nextSibling; // http://jsperf.com/nextsibling-vs-indexed-childnodes - } - // If the number of headers has been reduced, we need to replace excess TH with TD - if (TD.nodeName == 'TH') { - TD = replaceThWithTd(TD, TR); - } - if (!(0, _element.hasClass)(TD, 'hide')) { - TD.className = ''; - } - TD.removeAttribute('style'); - this.wot.wtSettings.settings.cellRenderer(sourceRowIndex, sourceColIndex, TD); - } + if (valueIndex !== -1) { + charsLeft = currentItem.length - valueIndex - valueLength; - return TD; + choicesRelevance.push({ + baseIndex: i, + index: valueIndex, + charsLeft: charsLeft, + value: currentItem + }); } + } - /** - * @param {Number} columnsToRender Number of columns to render. - */ + choicesRelevance.sort(function (a, b) { - }, { - key: 'adjustColumnWidths', - value: function adjustColumnWidths(columnsToRender) { - var scrollbarCompensation = 0; - var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot; - var mainHolder = sourceInstance.wtTable.holder; - var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth'); - var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth'); + if (b.index === -1) { + return -1; + } + if (a.index === -1) { + return 1; + } - if (mainHolder.offsetHeight < mainHolder.scrollHeight) { - scrollbarCompensation = (0, _element.getScrollbarWidth)(); + if (a.index < b.index) { + return -1; + } else if (b.index < a.index) { + return 1; + } else if (a.index === b.index) { + if (a.charsLeft < b.charsLeft) { + return -1; + } else if (a.charsLeft > b.charsLeft) { + return 1; } - this.wot.wtViewport.columnsRenderCalculator.refreshStretching(this.wot.wtViewport.getViewportWidth() - scrollbarCompensation); + } - rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting); + return 0; + }); - if (rowHeaderWidthSetting != null) { - for (var i = 0; i < this.rowHeaderCount; i++) { - var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting; + for (i = 0, choicesCount = choicesRelevance.length; i < choicesCount; i++) { + result.push(choicesRelevance[i].baseIndex); + } - width = width == null ? defaultColumnWidth : width; + return result; +}; - this.COLGROUP.childNodes[i].style.width = width + 'px'; - } - } +AutocompleteEditor.prototype.getDropdownHeight = function () { + var firstRowHeight = this.htEditor.getInstance().getRowHeight(0) || 23; + var visibleRows = this.cellProperties.visibleRows; - for (var renderedColIndex = 0; renderedColIndex < columnsToRender; renderedColIndex++) { - var _width2 = this.wtTable.getStretchedColumnWidth(this.columnFilter.renderedToSource(renderedColIndex)); + return this.strippedChoices.length >= visibleRows ? visibleRows * firstRowHeight : this.strippedChoices.length * firstRowHeight + 8; +}; - this.COLGROUP.childNodes[renderedColIndex + this.rowHeaderCount].style.width = _width2 + 'px'; - } - } +AutocompleteEditor.prototype.stripValueIfNeeded = function (value) { + return this.stripValuesIfNeeded([value])[0]; +}; - /** - * @param {HTMLTableCellElement} TR - */ +AutocompleteEditor.prototype.stripValuesIfNeeded = function (values) { + var allowHtml = this.cellProperties.allowHtml; - }, { - key: 'appendToTbody', - value: function appendToTbody(TR) { - this.TBODY.appendChild(TR); - this.wtTable.tbodyChildrenLength++; - } - /** - * @param {Number} rowIndex - * @param {HTMLTableRowElement} currentTr - * @returns {HTMLTableCellElement} - */ + var stringifiedValues = (0, _array.arrayMap)(values, function (value) { + return (0, _mixed.stringify)(value); + }); + var strippedValues = (0, _array.arrayMap)(stringifiedValues, function (value) { + return allowHtml ? value : (0, _string.stripTags)(value); + }); - }, { - key: 'getOrCreateTrForRow', - value: function getOrCreateTrForRow(rowIndex, currentTr) { - var TR = void 0; + return strippedValues; +}; - if (rowIndex >= this.wtTable.tbodyChildrenLength) { - TR = this.createRow(); - this.appendToTbody(TR); - } else if (rowIndex === 0) { - TR = this.TBODY.firstChild; - } else { - // http://jsperf.com/nextsibling-vs-indexed-childnodes - TR = currentTr.nextSibling; - } - if (TR.className) { - TR.removeAttribute('class'); - } +AutocompleteEditor.prototype.allowKeyEventPropagation = function (keyCode) { + var selected = { row: this.htEditor.getSelectedRange() ? this.htEditor.getSelectedRange().from.row : -1 }; + var allowed = false; - return TR; - } + if (keyCode === _unicode.KEY_CODES.ARROW_DOWN && selected.row > 0 && selected.row < this.htEditor.countRows() - 1) { + allowed = true; + } + if (keyCode === _unicode.KEY_CODES.ARROW_UP && selected.row > -1) { + allowed = true; + } - /** - * @returns {HTMLTableCellElement} - */ + return allowed; +}; - }, { - key: 'createRow', - value: function createRow() { - var TR = document.createElement('TR'); +AutocompleteEditor.prototype.discardEditor = function (result) { + _handsontableEditor2.default.prototype.discardEditor.apply(this, arguments); - for (var visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) { - TR.appendChild(document.createElement('TH')); - } + this.instance.view.render(); +}; - return TR; - } +exports.default = AutocompleteEditor; - /** - * @param {Number} row - * @param {Number} col - * @param {HTMLTableCellElement} TH - */ +/***/ }), +/* 169 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'renderRowHeader', - value: function renderRowHeader(row, col, TH) { - TH.className = ''; - TH.removeAttribute('style'); - this.rowHeaders[col](row, TH, col); - } +"use strict"; - /** - * @param {Number} row - * @param {HTMLTableCellElement} TR - */ - }, { - key: 'renderRowHeaders', - value: function renderRowHeaders(row, TR) { - for (var TH = TR.firstChild, visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) { - // If the number of row headers increased we need to create TH or replace an existing TD node with TH - if (!TH) { - TH = document.createElement('TH'); - TR.appendChild(TH); - } else if (TH.nodeName == 'TD') { - TH = replaceTdWithTh(TH, TR); - } - this.renderRowHeader(row, visibleColIndex, TH); - // http://jsperf.com/nextsibling-vs-indexed-childnodes - TH = TH.nextSibling; - } - } +exports.__esModule = true; - /** - * Adjust the number of COL and TH elements to match the number of columns and headers that need to be rendered - */ +var _unicode = __webpack_require__(17); - }, { - key: 'adjustAvailableNodes', - value: function adjustAvailableNodes() { - this.adjustColGroups(); - this.adjustThead(); - } +var _object = __webpack_require__(1); - /** - * Renders the column headers - */ +var _element = __webpack_require__(0); - }, { - key: 'renderColumnHeaders', - value: function renderColumnHeaders() { - if (!this.columnHeaderCount) { - return; - } - var columnCount = this.wtTable.getRenderedColumnsCount(); +var _event = __webpack_require__(8); - for (var i = 0; i < this.columnHeaderCount; i++) { - var TR = this.getTrForColumnHeaders(i); +var _textEditor = __webpack_require__(50); - for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) { - var sourceCol = this.columnFilter.renderedToSource(renderedColumnIndex); +var _textEditor2 = _interopRequireDefault(_textEditor); - this.renderColumnHeader(i, sourceCol, TR.childNodes[renderedColumnIndex + this.rowHeaderCount]); - } - } - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - /** - * Adjusts the number of COL elements to match the number of columns that need to be rendered - */ +var HandsontableEditor = _textEditor2.default.prototype.extend(); - }, { - key: 'adjustColGroups', - value: function adjustColGroups() { - var columnCount = this.wtTable.getRenderedColumnsCount(); +/** + * @private + * @editor HandsontableEditor + * @class HandsontableEditor + * @dependencies TextEditor + */ +HandsontableEditor.prototype.createElements = function () { + _textEditor2.default.prototype.createElements.apply(this, arguments); - while (this.wtTable.colgroupChildrenLength < columnCount + this.rowHeaderCount) { - this.COLGROUP.appendChild(document.createElement('COL')); - this.wtTable.colgroupChildrenLength++; - } - while (this.wtTable.colgroupChildrenLength > columnCount + this.rowHeaderCount) { - this.COLGROUP.removeChild(this.COLGROUP.lastChild); - this.wtTable.colgroupChildrenLength--; - } - if (this.rowHeaderCount) { - (0, _element.addClass)(this.COLGROUP.childNodes[0], 'rowHeader'); + var DIV = document.createElement('DIV'); + DIV.className = 'handsontableEditor'; + this.TEXTAREA_PARENT.appendChild(DIV); + + this.htContainer = DIV; + this.assignHooks(); +}; + +HandsontableEditor.prototype.prepare = function (td, row, col, prop, value, cellProperties) { + _textEditor2.default.prototype.prepare.apply(this, arguments); + + var parent = this; + var options = { + startRows: 0, + startCols: 0, + minRows: 0, + minCols: 0, + className: 'listbox', + copyPaste: false, + autoColumnSize: false, + autoRowSize: false, + readOnly: true, + fillHandle: false, + afterOnCellMouseDown: function afterOnCellMouseDown(_, coords) { + var value = this.getSourceData(coords.row, coords.col); + + // if the value is undefined then it means we don't want to set the value + if (value !== void 0) { + parent.setValue(value); } + parent.instance.destroyEditor(); } + }; - /** - * Adjusts the number of TH elements in THEAD to match the number of headers and columns that need to be rendered - */ - - }, { - key: 'adjustThead', - value: function adjustThead() { - var columnCount = this.wtTable.getRenderedColumnsCount(); - var TR = this.THEAD.firstChild; + if (this.cellProperties.handsontable) { + (0, _object.extend)(options, cellProperties.handsontable); + } + this.htOptions = options; +}; - if (this.columnHeaders.length) { - for (var i = 0, len = this.columnHeaders.length; i < len; i++) { - TR = this.THEAD.childNodes[i]; +var onBeforeKeyDown = function onBeforeKeyDown(event) { + if ((0, _event.isImmediatePropagationStopped)(event)) { + return; + } + var editor = this.getActiveEditor(); - if (!TR) { - TR = document.createElement('TR'); - this.THEAD.appendChild(TR); - } - this.theadChildrenLength = TR.childNodes.length; + var innerHOT = editor.htEditor.getInstance(); - while (this.theadChildrenLength < columnCount + this.rowHeaderCount) { - TR.appendChild(document.createElement('TH')); - this.theadChildrenLength++; - } - while (this.theadChildrenLength > columnCount + this.rowHeaderCount) { - TR.removeChild(TR.lastChild); - this.theadChildrenLength--; - } - } - var theadChildrenLength = this.THEAD.childNodes.length; + var rowToSelect; + var selectedRow; - if (theadChildrenLength > this.columnHeaders.length) { - for (var _i2 = this.columnHeaders.length; _i2 < theadChildrenLength; _i2++) { - this.THEAD.removeChild(this.THEAD.lastChild); - } - } - } else if (TR) { - (0, _element.empty)(TR); + if (event.keyCode == _unicode.KEY_CODES.ARROW_DOWN) { + if (!innerHOT.getSelected() && !innerHOT.flipped) { + rowToSelect = 0; + } else if (innerHOT.getSelected()) { + if (innerHOT.flipped) { + rowToSelect = innerHOT.getSelected()[0] + 1; + } else if (!innerHOT.flipped) { + selectedRow = innerHOT.getSelected()[0]; + var lastRow = innerHOT.countRows() - 1; + rowToSelect = Math.min(lastRow, selectedRow + 1); + } + } + } else if (event.keyCode == _unicode.KEY_CODES.ARROW_UP) { + if (!innerHOT.getSelected() && innerHOT.flipped) { + rowToSelect = innerHOT.countRows() - 1; + } else if (innerHOT.getSelected()) { + if (innerHOT.flipped) { + selectedRow = innerHOT.getSelected()[0]; + rowToSelect = Math.max(0, selectedRow - 1); + } else { + selectedRow = innerHOT.getSelected()[0]; + rowToSelect = selectedRow - 1; } } + } - /** - * @param {Number} index - * @returns {HTMLTableCellElement} - */ + if (rowToSelect !== void 0) { + if (rowToSelect < 0 || innerHOT.flipped && rowToSelect > innerHOT.countRows() - 1) { + innerHOT.deselectCell(); + } else { + innerHOT.selectCell(rowToSelect, 0); + } + if (innerHOT.getData().length) { + event.preventDefault(); + (0, _event.stopImmediatePropagation)(event); - }, { - key: 'getTrForColumnHeaders', - value: function getTrForColumnHeaders(index) { - return this.THEAD.childNodes[index]; + editor.instance.listen(); + editor.TEXTAREA.focus(); } + } +}; - /** - * @param {Number} row - * @param {Number} col - * @param {HTMLTableCellElement} TH - * @returns {*} - */ +HandsontableEditor.prototype.open = function () { + this.instance.addHook('beforeKeyDown', onBeforeKeyDown); + + _textEditor2.default.prototype.open.apply(this, arguments); - }, { - key: 'renderColumnHeader', - value: function renderColumnHeader(row, col, TH) { - TH.className = ''; - TH.removeAttribute('style'); + if (this.htEditor) { + this.htEditor.destroy(); + } + // Construct and initialise a new Handsontable + this.htEditor = new this.instance.constructor(this.htContainer, this.htOptions); + this.htEditor.init(); - return this.columnHeaders[row](col, TH, row); - } + if (this.cellProperties.strict) { + this.htEditor.selectCell(0, 0); + this.TEXTAREA.style.visibility = 'hidden'; + } else { + this.htEditor.deselectCell(); + this.TEXTAREA.style.visibility = 'visible'; + } - /** - * Add and/or remove the TDs to match the desired number - * - * @param {HTMLTableCellElement} TR Table row in question - * @param {Number} desiredCount The desired number of TDs in the TR - */ + (0, _element.setCaretPosition)(this.TEXTAREA, 0, this.TEXTAREA.value.length); +}; - }, { - key: 'adjustColumns', - value: function adjustColumns(TR, desiredCount) { - var count = TR.childNodes.length; +HandsontableEditor.prototype.close = function () { + this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); + this.instance.listen(); - while (count < desiredCount) { - var TD = document.createElement('TD'); + _textEditor2.default.prototype.close.apply(this, arguments); +}; - TR.appendChild(TD); - count++; - } - while (count > desiredCount) { - TR.removeChild(TR.lastChild); - count--; - } - } +HandsontableEditor.prototype.focus = function () { + this.instance.listen(); + _textEditor2.default.prototype.focus.apply(this, arguments); +}; - /** - * @param {Number} columnsToRender - */ +HandsontableEditor.prototype.beginEditing = function (initialValue) { + var onBeginEditing = this.instance.getSettings().onBeginEditing; - }, { - key: 'removeRedundantColumns', - value: function removeRedundantColumns(columnsToRender) { - while (this.wtTable.tbodyChildrenLength > columnsToRender) { - this.TBODY.removeChild(this.TBODY.lastChild); - this.wtTable.tbodyChildrenLength--; - } - } - }]); + if (onBeginEditing && onBeginEditing() === false) { + return; + } + _textEditor2.default.prototype.beginEditing.apply(this, arguments); +}; - return TableRenderer; -}(); +HandsontableEditor.prototype.finishEditing = function (isCancelled, ctrlDown) { + if (this.htEditor && this.htEditor.isListening()) { + // if focus is still in the HOT editor -function replaceTdWithTh(TD, TR) { - var TH = document.createElement('TH'); + this.instance.listen(); // return the focus to the parent HOT instance + } - TR.insertBefore(TH, TD); - TR.removeChild(TD); + if (this.htEditor && this.htEditor.getSelected()) { + var value = this.htEditor.getInstance().getValue(); - return TH; -} + if (value !== void 0) { + // if the value is undefined then it means we don't want to set the value + this.setValue(value); + } + } -function replaceThWithTd(TH, TR) { - var TD = document.createElement('TD'); + return _textEditor2.default.prototype.finishEditing.apply(this, arguments); +}; - TR.insertBefore(TD, TH); - TR.removeChild(TH); +HandsontableEditor.prototype.assignHooks = function () { + var _this = this; - return TD; -} + this.instance.addHook('afterDestroy', function () { + if (_this.htEditor) { + _this.htEditor.destroy(); + } + }); +}; -exports.default = TableRenderer; +exports.default = HandsontableEditor; /***/ }), -/* 148 */ +/* 170 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; +exports.getNormalizedDate = getNormalizedDate; +/* eslint-disable import/prefer-default-export */ -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _element = __webpack_require__(0); - -var _object = __webpack_require__(1); - -var _eventManager = __webpack_require__(4); - -var _eventManager2 = _interopRequireDefault(_eventManager); +/** + * Get normalized Date object for the ISO formatted date strings. + * Natively, the date object parsed from a ISO 8601 string will be offsetted by the timezone difference, which may result in returning a wrong date. + * See: Github issue #3338. + * + * @param {String} dateString String representing the date. + * @returns {Date} The proper Date object. + */ +function getNormalizedDate(dateString) { + var nativeDate = new Date(dateString); -var _viewportColumns = __webpack_require__(137); + // NaN if dateString is not in ISO format + if (!isNaN(new Date(dateString + "T00:00").getDate())) { -var _viewportColumns2 = _interopRequireDefault(_viewportColumns); + // Compensate timezone offset + return new Date(nativeDate.getTime() + nativeDate.getTimezoneOffset() * 60000); + } -var _viewportRows = __webpack_require__(138); + return nativeDate; +} -var _viewportRows2 = _interopRequireDefault(_viewportRows); +/***/ }), +/* 171 */ +/***/ (function(module, exports, __webpack_require__) { -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +"use strict"; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * @class Viewport + * SheetClip - Spreadsheet Clipboard Parser + * version 0.2 + * + * This tiny library transforms JavaScript arrays to strings that are pasteable by LibreOffice, OpenOffice, + * Google Docs and Microsoft Excel. + * + * Copyright 2012, Marcin Warpechowski + * Licensed under the MIT license. + * http://github.com/warpech/sheetclip/ */ -var Viewport = function () { - /** - * @param wotInstance - */ - function Viewport(wotInstance) { - var _this = this; - - _classCallCheck(this, Viewport); - - this.wot = wotInstance; - // legacy support - this.instance = this.wot; - - this.oversizedRows = []; - this.oversizedColumnHeaders = []; - this.hasOversizedColumnHeadersMarked = {}; - this.clientHeight = 0; - this.containerWidth = NaN; - this.rowHeaderWidth = NaN; - this.rowsVisibleCalculator = null; - this.columnsVisibleCalculator = null; +/*jslint white: true*/ +(function (global) { + "use strict"; - this.eventManager = new _eventManager2.default(this.wot); - this.eventManager.addEventListener(window, 'resize', function () { - _this.clientHeight = _this.getWorkspaceHeight(); - }); + function countQuotes(str) { + return str.split('"').length - 1; } - /** - * @returns {number} - */ - + var SheetClip = { + /** + * Decode spreadsheet string into array + * + * @param {String} str + * @returns {Array} + */ + parse: function parse(str) { + var r, + rLen, + rows, + arr = [], + a = 0, + c, + cLen, + multiline, + last; - _createClass(Viewport, [{ - key: 'getWorkspaceHeight', - value: function getWorkspaceHeight() { - var trimmingContainer = this.instance.wtOverlays.topOverlay.trimmingContainer; - var elemHeight = void 0; - var height = 0; + rows = str.split('\n'); - if (trimmingContainer === window) { - height = document.documentElement.clientHeight; - } else { - elemHeight = (0, _element.outerHeight)(trimmingContainer); - // returns height without DIV scrollbar - height = elemHeight > 0 && trimmingContainer.clientHeight > 0 ? trimmingContainer.clientHeight : Infinity; + if (rows.length > 1 && rows[rows.length - 1] === '') { + rows.pop(); } + for (r = 0, rLen = rows.length; r < rLen; r += 1) { + rows[r] = rows[r].split('\t'); - return height; - } - }, { - key: 'getWorkspaceWidth', - value: function getWorkspaceWidth() { - var width = void 0; - var totalColumns = this.wot.getSetting('totalColumns'); - var trimmingContainer = this.instance.wtOverlays.leftOverlay.trimmingContainer; - var overflow = void 0; - var stretchSetting = this.wot.getSetting('stretchH'); - var docOffsetWidth = document.documentElement.offsetWidth; - var preventOverflow = this.wot.getSetting('preventOverflow'); + for (c = 0, cLen = rows[r].length; c < cLen; c += 1) { + if (!arr[a]) { + arr[a] = []; + } + if (multiline && c === 0) { + last = arr[a].length - 1; + arr[a][last] = arr[a][last] + '\n' + rows[r][0]; - if (preventOverflow) { - return (0, _element.outerWidth)(this.instance.wtTable.wtRootElement); + if (multiline && countQuotes(rows[r][0]) & 1) { + //& 1 is a bitwise way of performing mod 2 + multiline = false; + arr[a][last] = arr[a][last].substring(0, arr[a][last].length - 1).replace(/""/g, '"'); + } + } else { + if (c === cLen - 1 && rows[r][c].indexOf('"') === 0 && countQuotes(rows[r][c]) & 1) { + arr[a].push(rows[r][c].substring(1).replace(/""/g, '"')); + multiline = true; + } else { + arr[a].push(rows[r][c].replace(/""/g, '"')); + multiline = false; + } + } + } + if (!multiline) { + a += 1; + } } - if (this.wot.getSetting('freezeOverlays')) { - width = Math.min(docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth); - } else { - width = Math.min(this.getContainerFillWidth(), docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth); - } + return arr; + }, - if (trimmingContainer === window && totalColumns > 0 && this.sumColumnWidths(0, totalColumns - 1) > width) { - // in case sum of column widths is higher than available stylesheet width, let's assume using the whole window - // otherwise continue below, which will allow stretching - // this is used in `scroll_window.html` - // TODO test me - return document.documentElement.clientWidth; - } + /** + * Encode array into valid spreadsheet string + * + * @param arr + * @returns {String} + */ + stringify: function stringify(arr) { + var r, + rLen, + c, + cLen, + str = '', + val; - if (trimmingContainer !== window) { - overflow = (0, _element.getStyle)(this.instance.wtOverlays.leftOverlay.trimmingContainer, 'overflow'); + for (r = 0, rLen = arr.length; r < rLen; r += 1) { + cLen = arr[r].length; - if (overflow == 'scroll' || overflow == 'hidden' || overflow == 'auto') { - // this is used in `scroll.html` - // TODO test me - return Math.max(width, trimmingContainer.clientWidth); + for (c = 0; c < cLen; c += 1) { + if (c > 0) { + str += '\t'; + } + val = arr[r][c]; + + if (typeof val === 'string') { + if (val.indexOf('\n') > -1) { + str += '"' + val.replace(/"/g, '""') + '"'; + } else { + str += val; + } + } else if (val === null || val === void 0) { + // void 0 resolves to undefined + str += ''; + } else { + str += val; + } } - } - if (stretchSetting === 'none' || !stretchSetting) { - // if no stretching is used, return the maximum used workspace width - return Math.max(width, (0, _element.outerWidth)(this.instance.wtTable.TABLE)); + if (r !== rLen - 1) { + str += '\n'; + } } - // if stretching is used, return the actual container width, so the columns can fit inside it - return width; + return str; } + }; - /** - * Checks if viewport has vertical scroll - * - * @returns {Boolean} - */ + if (true) { + exports.parse = SheetClip.parse; + exports.stringify = SheetClip.stringify; + } else { + global.SheetClip = SheetClip; + } +})(window); - }, { - key: 'hasVerticalScroll', - value: function hasVerticalScroll() { - return this.getWorkspaceActualHeight() > this.getWorkspaceHeight(); - } +/***/ }), +/* 172 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Checks if viewport has horizontal scroll - * - * @returns {Boolean} - */ +"use strict"; - }, { - key: 'hasHorizontalScroll', - value: function hasHorizontalScroll() { - return this.getWorkspaceActualWidth() > this.getWorkspaceWidth(); - } - /** - * @param from - * @param length - * @returns {Number} - */ +exports.__esModule = true; +exports.RecordTranslator = undefined; - }, { - key: 'sumColumnWidths', - value: function sumColumnWidths(from, length) { - var sum = 0; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - while (from < length) { - sum += this.wot.wtTable.getColumnWidth(from); - from++; - } +exports.registerIdentity = registerIdentity; +exports.getTranslator = getTranslator; - return sum; - } +var _core = __webpack_require__(82); - /** - * @returns {Number} - */ +var _core2 = _interopRequireDefault(_core); - }, { - key: 'getContainerFillWidth', - value: function getContainerFillWidth() { - if (this.containerWidth) { - return this.containerWidth; - } - var mainContainer = this.instance.wtTable.holder; - var fillWidth = void 0; - var dummyElement = void 0; +var _object = __webpack_require__(1); - dummyElement = document.createElement('div'); - dummyElement.style.width = '100%'; - dummyElement.style.height = '1px'; - mainContainer.appendChild(dummyElement); - fillWidth = dummyElement.offsetWidth; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - this.containerWidth = fillWidth; - mainContainer.removeChild(dummyElement); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - return fillWidth; - } +/** + * @class RecordTranslator + * @util + */ +var RecordTranslator = function () { + function RecordTranslator(hot) { + _classCallCheck(this, RecordTranslator); - /** - * @returns {Number} - */ + this.hot = hot; + } - }, { - key: 'getWorkspaceOffset', - value: function getWorkspaceOffset() { - return (0, _element.offset)(this.wot.wtTable.TABLE); - } + /** + * Translate physical row index into visual. + * + * @param {Number} row Physical row index. + * @returns {Number} Returns visual row index. + */ - /** - * @returns {Number} - */ - }, { - key: 'getWorkspaceActualHeight', - value: function getWorkspaceActualHeight() { - return (0, _element.outerHeight)(this.wot.wtTable.TABLE); + _createClass(RecordTranslator, [{ + key: 'toVisualRow', + value: function toVisualRow(row) { + return this.hot.runHooks('unmodifyRow', row); } /** - * @returns {Number} + * Translate physical column index into visual. + * + * @param {Number} column Physical column index. + * @returns {Number} Returns visual column index. */ }, { - key: 'getWorkspaceActualWidth', - value: function getWorkspaceActualWidth() { - return (0, _element.outerWidth)(this.wot.wtTable.TABLE) || (0, _element.outerWidth)(this.wot.wtTable.TBODY) || (0, _element.outerWidth)(this.wot.wtTable.THEAD); // IE8 reports 0 as
offsetWidth; + key: 'toVisualColumn', + value: function toVisualColumn(column) { + return this.hot.runHooks('unmodifyCol', column); } /** - * @returns {Number} + * Translate physical coordinates into visual. Can be passed as separate 2 arguments (row, column) or as an object in first + * argument with `row` and `column` keys. + * + * @param {Number|Object} row Physical coordinates or row index. + * @param {Number} [column] Physical column index. + * @returns {Object|Array} Returns an object with visual records or an array if coordinates passed as separate arguments. */ }, { - key: 'getColumnHeaderHeight', - value: function getColumnHeaderHeight() { - if (isNaN(this.columnHeaderHeight)) { - this.columnHeaderHeight = (0, _element.outerHeight)(this.wot.wtTable.THEAD); + key: 'toVisual', + value: function toVisual(row, column) { + var result = void 0; + + if ((0, _object.isObject)(row)) { + result = { + row: this.toVisualRow(row.row), + column: this.toVisualColumn(row.column) + }; + } else { + result = [this.toVisualRow(row), this.toVisualColumn(column)]; } - return this.columnHeaderHeight; + return result; } /** - * @returns {Number} + * Translate visual row index into physical. + * + * @param {Number} row Visual row index. + * @returns {Number} Returns physical row index. */ }, { - key: 'getViewportHeight', - value: function getViewportHeight() { - var containerHeight = this.getWorkspaceHeight(); - var columnHeaderHeight = void 0; - - if (containerHeight === Infinity) { - return containerHeight; - } - columnHeaderHeight = this.getColumnHeaderHeight(); + key: 'toPhysicalRow', + value: function toPhysicalRow(row) { + return this.hot.runHooks('modifyRow', row); + } - if (columnHeaderHeight > 0) { - containerHeight -= columnHeaderHeight; - } + /** + * Translate visual column index into physical. + * + * @param {Number} column Visual column index. + * @returns {Number} Returns physical column index. + */ - return containerHeight; + }, { + key: 'toPhysicalColumn', + value: function toPhysicalColumn(column) { + return this.hot.runHooks('modifyCol', column); } /** - * @returns {Number} + * Translate visual coordinates into physical. Can be passed as separate 2 arguments (row, column) or as an object in first + * argument with `row` and `column` keys. + * + * @param {Number|Object} row Visual coordinates or row index. + * @param {Number} [column] Visual column index. + * @returns {Object|Array} Returns an object with physical records or an array if coordinates passed as separate arguments. */ }, { - key: 'getRowHeaderWidth', - value: function getRowHeaderWidth() { - var rowHeadersHeightSetting = this.instance.getSetting('rowHeaderWidth'); - var rowHeaders = this.instance.getSetting('rowHeaders'); - - if (rowHeadersHeightSetting) { - this.rowHeaderWidth = 0; + key: 'toPhysical', + value: function toPhysical(row, column) { + var result = void 0; - for (var i = 0, len = rowHeaders.length; i < len; i++) { - this.rowHeaderWidth += rowHeadersHeightSetting[i] || rowHeadersHeightSetting; - } + if ((0, _object.isObject)(row)) { + result = { + row: this.toPhysicalRow(row.row), + column: this.toPhysicalColumn(row.column) + }; + } else { + result = [this.toPhysicalRow(row), this.toPhysicalColumn(column)]; } - if (this.wot.cloneSource) { - return this.wot.cloneSource.wtViewport.getRowHeaderWidth(); - } + return result; + } + }]); - if (isNaN(this.rowHeaderWidth)) { + return RecordTranslator; +}(); - if (rowHeaders.length) { - var TH = this.instance.wtTable.TABLE.querySelector('TH'); - this.rowHeaderWidth = 0; +exports.RecordTranslator = RecordTranslator; - for (var _i = 0, _len = rowHeaders.length; _i < _len; _i++) { - if (TH) { - this.rowHeaderWidth += (0, _element.outerWidth)(TH); - TH = TH.nextSibling; - } else { - // yes this is a cheat but it worked like that before, just taking assumption from CSS instead of measuring. - // TODO: proper fix - this.rowHeaderWidth += 50; - } - } - } else { - this.rowHeaderWidth = 0; - } - } - this.rowHeaderWidth = this.instance.getSetting('onModifyRowHeaderWidth', this.rowHeaderWidth) || this.rowHeaderWidth; +var identities = new WeakMap(); +var translatorSingletons = new WeakMap(); - return this.rowHeaderWidth; +function registerIdentity(identity, hot) { + identities.set(identity, hot); +} + +function getTranslator(identity) { + var singleton = void 0; + + if (!(identity instanceof _core2.default)) { + if (!identities.has(identity)) { + throw Error('Record translator was not registered for this object identity'); } + identity = identities.get(identity); + } + if (translatorSingletons.has(identity)) { + singleton = translatorSingletons.get(identity); + } else { + singleton = new RecordTranslator(identity); + translatorSingletons.set(identity, singleton); + } - /** - * @returns {Number} - */ + return singleton; +} - }, { - key: 'getViewportWidth', - value: function getViewportWidth() { - var containerWidth = this.getWorkspaceWidth(); - var rowHeaderWidth = void 0; +/***/ }), +/* 173 */ +/***/ (function(module, exports, __webpack_require__) { - if (containerWidth === Infinity) { - return containerWidth; - } - rowHeaderWidth = this.getRowHeaderWidth(); +"use strict"; - if (rowHeaderWidth > 0) { - return containerWidth - rowHeaderWidth; - } - return containerWidth; - } +exports.__esModule = true; +exports.registerAsRootInstance = registerAsRootInstance; +exports.hasValidParameter = hasValidParameter; +exports.isRootInstance = isRootInstance; +var holder = exports.holder = new WeakMap(); - /** - * Creates: - * - rowsRenderCalculator (before draw, to qualify rows for rendering) - * - rowsVisibleCalculator (after draw, to measure which rows are actually visible) - * - * @returns {ViewportRowsCalculator} - */ +var rootInstanceSymbol = exports.rootInstanceSymbol = Symbol('rootInstance'); - }, { - key: 'createRowsCalculator', - value: function createRowsCalculator() { - var _this2 = this; +/** + * Register an object as a root instance. + * + * @param {Object} object An object to associate with root instance flag. + */ +function registerAsRootInstance(object) { + holder.set(object, true); +} - var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; +/** + * Check if the source of the root indication call is valid. + * + * @param {Symbol} rootSymbol A symbol as a source of truth. + * @return {Boolean} + */ +function hasValidParameter(rootSymbol) { + return rootSymbol === rootInstanceSymbol; +} - var height = void 0; - var pos = void 0; - var fixedRowsTop = void 0; - var scrollbarHeight = void 0; - var fixedRowsBottom = void 0; - var fixedRowsHeight = void 0; - var totalRows = void 0; +/** + * Check if passed an object was flagged as a root instance. + * + * @param {Object} object An object to check. + * @return {Boolean} + */ +function isRootInstance(object) { + return holder.has(object); +} - this.rowHeaderWidth = NaN; +/***/ }), +/* 174 */ +/***/ (function(module, exports, __webpack_require__) { - if (this.wot.wtSettings.settings.renderAllRows) { - height = Infinity; - } else { - height = this.getViewportHeight(); - } - pos = this.wot.wtOverlays.topOverlay.getScrollPosition() - this.wot.wtOverlays.topOverlay.getTableParentOffset(); +"use strict"; - if (pos < 0) { - pos = 0; - } - fixedRowsTop = this.wot.getSetting('fixedRowsTop'); - fixedRowsBottom = this.wot.getSetting('fixedRowsBottom'); - totalRows = this.wot.getSetting('totalRows'); - if (fixedRowsTop) { - fixedRowsHeight = this.wot.wtOverlays.topOverlay.sumCellSizes(0, fixedRowsTop); - pos += fixedRowsHeight; - height -= fixedRowsHeight; - } +exports.__esModule = true; - if (fixedRowsBottom && this.wot.wtOverlays.bottomOverlay.clone) { - fixedRowsHeight = this.wot.wtOverlays.bottomOverlay.sumCellSizes(totalRows - fixedRowsBottom, totalRows); +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - height -= fixedRowsHeight; - } +var _mixed = __webpack_require__(22); - if (this.wot.wtTable.holder.clientHeight === this.wot.wtTable.holder.offsetHeight) { - scrollbarHeight = 0; - } else { - scrollbarHeight = (0, _element.getScrollbarWidth)(); - } +var _object = __webpack_require__(1); - return new _viewportRows2.default(height, pos, this.wot.getSetting('totalRows'), function (sourceRow) { - return _this2.wot.wtTable.getRowHeight(sourceRow); - }, visible ? null : this.wot.wtSettings.settings.viewportRowCalculatorOverride, visible, scrollbarHeight); - } +/** + * @alias Options + * @constructor + * @description - /** - * Creates: - * - columnsRenderCalculator (before draw, to qualify columns for rendering) - * - columnsVisibleCalculator (after draw, to measure which columns are actually visible) - * - * @returns {ViewportRowsCalculator} - */ + * ## Constructor options + * + * Constructor options are applied using an object literal passed as a second argument to the Handsontable constructor. + * + * ```js + * var hot = new Handsontable(document.getElementById('example1'), { + * data: myArray, + * width: 400, + * height: 300 + * }); + * ``` + * + * --- + * ## Cascading configuration + * + * Handsontable 0.9 and newer is using *Cascading Configuration*, which is a fast way to provide configuration options + * for the entire table, including its columns and particular cells. + * + * Consider the following example: + * ```js + * var hot = new Handsontable(document.getElementById('example'), { + * readOnly: true, + * columns: [ + * {readOnly: false}, + * {}, + * {} + * ], + * cells: function (row, col, prop) { + * var cellProperties = {}; + * + * if (row === 0 && col === 0) { + * cellProperties.readOnly = true; + * } + * + * return cellProperties; + * } + * }); + * ``` + * + * The above notation will result in all TDs being *read only*, except for first column TDs which will be *editable*, except for the TD in top left corner which will still be *read only*. + * + * ### The Cascading Configuration model + * + * ##### 1. Constructor + * + * Configuration options that are provided using first-level `handsontable(container, {option: "value"})` and `updateSettings` method. + * + * ##### 2. Columns + * + * Configuration options that are provided using second-level object `handsontable(container, {columns: {option: "value"}]})` + * + * ##### 3. Cells + * + * Configuration options that are provided using third-level function `handsontable(container, {cells: function: (row, col, prop){ }})` + * + * --- + * ## Architecture performance + * + * The Cascading Configuration model is based on prototypical inheritance. It is much faster and memory efficient compared + * to the previous model that used jQuery extend. See: [http://jsperf.com/extending-settings](http://jsperf.com/extending-settings). + * + * --- + * __Important notice:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`. + */ +function DefaultSettings() {}; - }, { - key: 'createColumnsCalculator', - value: function createColumnsCalculator() { - var _this3 = this; +DefaultSettings.prototype = { + /** + * License key for commercial version of Handsontable. + * + * @pro + * @type {String} + * @default 'trial' + */ + licenseKey: 'trial', - var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + /** + * @description + * Initial data source that will be bound to the data grid __by reference__ (editing data grid alters the data source). + * Can be declared as an Array of Arrays, Array of Objects or a Function. + * + * See [Understanding binding as reference](http://docs.handsontable.com/tutorial-data-binding.html#page-reference). + * + * @type {Array|Function} + * @default undefined + */ + data: void 0, - var width = this.getViewportWidth(); - var pos = void 0; - var fixedColumnsLeft = void 0; + /** + * @description + * Defines the structure of a new row when data source is an array of objects. + * + * See [data-schema](http://docs.handsontable.com/tutorial-data-sources.html#page-data-schema) for examples. + * + * @type {Object} + * @default undefined + */ + dataSchema: void 0, - this.columnHeaderHeight = NaN; + /** + * Width of the grid. Can be a value or a function that returns a value. + * + * @type {Number|Function} + * @default undefined + */ + width: void 0, - pos = this.wot.wtOverlays.leftOverlay.getScrollPosition() - this.wot.wtOverlays.leftOverlay.getTableParentOffset(); + /** + * Height of the grid. Can be a number or a function that returns a number. + * + * @type {Number|Function} + * @default undefined + */ + height: void 0, - if (pos < 0) { - pos = 0; - } - fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft'); + /** + * @description + * Initial number of rows. + * + * __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided + * + * @type {Number} + * @default 5 + */ + startRows: 5, - if (fixedColumnsLeft) { - var fixedColumnsWidth = this.wot.wtOverlays.leftOverlay.sumCellSizes(0, fixedColumnsLeft); - pos += fixedColumnsWidth; - width -= fixedColumnsWidth; - } - if (this.wot.wtTable.holder.clientWidth !== this.wot.wtTable.holder.offsetWidth) { - width -= (0, _element.getScrollbarWidth)(); - } + /** + * @description + * Initial number of columns. + * + * __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided + * + * @type {Number} + * @default 5 + */ + startCols: 5, - return new _viewportColumns2.default(width, pos, this.wot.getSetting('totalColumns'), function (sourceCol) { - return _this3.wot.wtTable.getColumnWidth(sourceCol); - }, visible ? null : this.wot.wtSettings.settings.viewportColumnCalculatorOverride, visible, this.wot.getSetting('stretchH'), function (stretchedWidth, column) { - return _this3.wot.getSetting('onBeforeStretchingColumnWidth', stretchedWidth, column); - }); - } + /** + * Setting `true` or `false` will enable or disable the default row headers (1, 2, 3). + * You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers. + * If a function is set the index of the row is passed as a parameter. + * + * @type {Boolean|Array|Function} + * @default null + * @example + * ```js + * ... + * // as boolean + * rowHeaders: true, + * ... + * + * ... + * // as array + * rowHeaders: [1, 2, 3], + * ... + * + * ... + * // as function + * rowHeaders: function(index) { + * return index + ': AB'; + * }, + * ... + * ``` + */ + rowHeaders: void 0, - /** - * Creates rowsRenderCalculator and columnsRenderCalculator (before draw, to determine what rows and - * cols should be rendered) - * - * @param fastDraw {Boolean} If `true`, will try to avoid full redraw and only update the border positions. - * If `false` or `undefined`, will perform a full redraw - * @returns fastDraw {Boolean} The fastDraw value, possibly modified - */ + /** + * Setting `true` or `false` will enable or disable the default column headers (A, B, C). + * You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers. + * If a function is set, then the index of the column is passed as a parameter. + * + * @type {Boolean|Array|Function} + * @default null + * @example + * ```js + * ... + * // as boolean + * colHeaders: true, + * ... + * + * ... + * // as array + * colHeaders: ['A', 'B', 'C'], + * ... + * + * ... + * // as function + * colHeaders: function(index) { + * return index + ': AB'; + * }, + * ... + * ``` + */ + colHeaders: null, - }, { - key: 'createRenderCalculators', - value: function createRenderCalculators() { - var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + /** + * Defines column widths in pixels. Accepts number, string (that will be converted to a number), + * array of numbers (if you want to define column width separately for each column) or a + * function (if you want to set column width dynamically on each render). + * + * @type {Array|Function|Number|String} + * @default undefined + * @example + * ```js + * ... + * // as numeric, for each column. + * colWidths: 100, + * ... + * + * * ... + * // as string, for each column. + * colWidths: '100px', + * ... + * + * ... + * // as array, based on visual indexes. The rest of the columns have a default width. + * colWidths: [100, 120, 90], + * ... + * + * ... + * // as function, based on visual indexes. + * colWidths: function(index) { + * return index * 10; + * }, + * ... + * ``` + */ + colWidths: void 0, + + /** + * Defines row heights in pixels. Accepts numbers, strings (that will be converted into a number), + * array of numbers (if you want to define row height separately for each row) or a + * function (if you want to set row height dynamically on each render). + * If the ManualRowResize or AutoRowSize plugins are enabled, this is also the minimum height that can be set + * via either of those two plugins. + * Height should be equal or greater than 23px. Table is rendered incorrectly if height is less than 23px. + * + * @type {Array|Function|Number|String} + * @default undefined + * @example + * ```js + * ... + * // as numeric, for each row. + * rowHeights: 100, + * ... + * + * * ... + * // as string, for each row. + * rowHeights: '100px', + * ... + * + * ... + * // as array, based on visual indexes. The rest of the rows have a default height. + * rowHeights: [100, 120, 90], + * ... + * + * ... + * // as function, based on visual indexes. + * rowHeights: function(index) { + * return index * 10; + * }, + * ... + * ``` + */ + rowHeights: void 0, + + /** + * @description + * Defines the cell properties and data binding for certain columns. + * + * __Notice:__ Using this option sets a fixed number of columns (options `startCols`, `minCols`, `maxCols` will be ignored). + * + * See [documentation -> datasources.html](http://docs.handsontable.com/tutorial-data-sources.html#page-nested) for examples. + * + * @type {Array|Function} + * @default undefined + * @example + * ```js + * ... + * // as an array of objects. Order of the objects in array is representation of physical indexes. + * columns: [ + * { + * // column options for the first column + * type: 'numeric', + * format: '0,0.00 $' + * }, + * { + * // column options for the second column + * type: 'text', + * readOnly: true + * } + * ], + * ... + * + * // or as function, based on physical indexes + * ... + * columns: function(index) { + * return { + * type: index > 0 ? 'numeric' : 'text', + * readOnly: index < 1 + * } + * } + * ... + * ``` + */ + columns: void 0, - if (fastDraw) { - var proposedRowsVisibleCalculator = this.createRowsCalculator(true); - var proposedColumnsVisibleCalculator = this.createColumnsCalculator(true); + /** + * @description + * Defines the cell properties for given `row`, `col`, `prop` coordinates. + * Any constructor or column option may be overwritten for a particular cell (row/column combination) + * using the `cells` property in the Handsontable constructor. + * + * __Note:__ Parameters `row` and `col` always represent __physical indexes__. Example below show how to execute + * operations based on the __visual__ representation of Handsontable. + * + * Possible values of `prop`: + * - property name for column's data source object, when dataset is an [array of objects](/tutorial-data-sources.html#page-object) + * - the same number as `col`, when dataset is an [array of arrays](/tutorial-data-sources.html#page-array) + * + * @type {Function} + * @default undefined + * @example + * ```js + * ... + * cells: function (row, col, prop) { + * var cellProperties = {}; + * var visualRowIndex = this.instance.toVisualRow(row); + * var visualColIndex = this.instance.toVisualColumn(col); + * + * if (visualRowIndex === 0 && visualColIndex === 0) { + * cellProperties.readOnly = true; + * } + * + * return cellProperties; + * }, + * ... + * ``` + */ + cells: void 0, - if (!(this.areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) && this.areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator))) { - fastDraw = false; - } - } + /** + * Any constructor or column option may be overwritten for a particular cell (row/column combination), using `cell` + * array passed to the Handsontable constructor. + * + * @type {Array} + * @default [] + * @example + * ```js + * ... + * cell: [ + * {row: 0, col: 0, readOnly: true} + * ], + * ... + * ``` + */ + cell: [], - if (!fastDraw) { - this.rowsRenderCalculator = this.createRowsCalculator(); - this.columnsRenderCalculator = this.createColumnsCalculator(); - } - // delete temporarily to make sure that renderers always use rowsRenderCalculator, not rowsVisibleCalculator - this.rowsVisibleCalculator = null; - this.columnsVisibleCalculator = null; + /** + * @description + * If `true`, enables the {@link Comments} plugin, which enables an option to apply cell comments through the context menu + * (configurable with context menu keys `commentsAddEdit`, `commentsRemove`). + * + * To initialize Handsontable with predefined comments, provide cell coordinates and comment text values in a form of an array. + * + * See [Comments](http://docs.handsontable.com/demo-comments_.html) demo for examples. + * + * @since 0.11.0 + * @type {Boolean|Array} + * @default false + * @example + * ```js + * ... + * comments: [{row: 1, col: 1, comment: {value: "Test comment"}}], + * ... + * ``` + */ + comments: false, - return fastDraw; - } + /** + * @description + * If `true`, enables the Custom Borders plugin, which enables an option to apply custom borders through the context menu (configurable with context menu key `borders`). + * + * To initialize Handsontable with predefined custom borders, provide cell coordinates and border styles in a form of an array. + * + * See [Custom Borders](http://docs.handsontable.com/demo-custom-borders.html) demo for examples. + * + * @since 0.11.0 + * @type {Boolean|Array} + * @default false + * @example + * ```js + * ... + * customBorders: [ + * {range: { + * from: {row: 1, col: 1}, + * to: {row: 3, col: 4}}, + * left: {}, + * right: {}, + * top: {}, + * bottom: {} + * } + * ], + * ... + * + * // or + * ... + * customBorders: [ + * {row: 2, col: 2, left: {width: 2, color: 'red'}, + * right: {width: 1, color: 'green'}, top: '', bottom: ''} + * ], + * ... + * ``` + */ + customBorders: false, - /** - * Creates rowsVisibleCalculator and columnsVisibleCalculator (after draw, to determine what are - * the actually visible rows and columns) - */ + /** + * Minimum number of rows. At least that number of rows will be created during initialization. + * + * @type {Number} + * @default 0 + */ + minRows: 0, - }, { - key: 'createVisibleCalculators', - value: function createVisibleCalculators() { - this.rowsVisibleCalculator = this.createRowsCalculator(true); - this.columnsVisibleCalculator = this.createColumnsCalculator(true); - } + /** + * Minimum number of columns. At least that number of columns will be created during initialization. + * + * @type {Number} + * @default 0 + */ + minCols: 0, - /** - * Returns information whether proposedRowsVisibleCalculator viewport - * is contained inside rows rendered in previous draw (cached in rowsRenderCalculator) - * - * @param {Object} proposedRowsVisibleCalculator - * @returns {Boolean} Returns `true` if all proposed visible rows are already rendered (meaning: redraw is not needed). - * Returns `false` if at least one proposed visible row is not already rendered (meaning: redraw is needed) - */ + /** + * Maximum number of rows. If set to a value lower than the initial row count, the data will be trimmed to the provided value as the number of rows. + * + * @type {Number} + * @default Infinity + */ + maxRows: Infinity, - }, { - key: 'areAllProposedVisibleRowsAlreadyRendered', - value: function areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) { - if (this.rowsVisibleCalculator) { - if (proposedRowsVisibleCalculator.startRow < this.rowsRenderCalculator.startRow || proposedRowsVisibleCalculator.startRow === this.rowsRenderCalculator.startRow && proposedRowsVisibleCalculator.startRow > 0) { - return false; - } else if (proposedRowsVisibleCalculator.endRow > this.rowsRenderCalculator.endRow || proposedRowsVisibleCalculator.endRow === this.rowsRenderCalculator.endRow && proposedRowsVisibleCalculator.endRow < this.wot.getSetting('totalRows') - 1) { - return false; - } - return true; - } + /** + * Maximum number of cols. If set to a value lower than the initial col count, the data will be trimmed to the provided value as the number of cols. + * + * @type {Number} + * @default Infinity + */ + maxCols: Infinity, - return false; - } + /** + * When set to 1 (or more), Handsontable will add a new row at the end of grid if there are no more empty rows. + * (unless the number of rows exceeds the one set in the `maxRows` property) + * + * @type {Number} + * @default 0 + */ + minSpareRows: 0, - /** - * Returns information whether proposedColumnsVisibleCalculator viewport - * is contained inside column rendered in previous draw (cached in columnsRenderCalculator) - * - * @param {Object} proposedColumnsVisibleCalculator - * @returns {Boolean} Returns `true` if all proposed visible columns are already rendered (meaning: redraw is not needed). - * Returns `false` if at least one proposed visible column is not already rendered (meaning: redraw is needed) - */ + /** + * When set to 1 (or more), Handsontable will add a new column at the end of grid if there are no more empty columns. + * (unless the number of rows exceeds the one set in the `maxCols` property) + * + * @type {Number} + * @default 0 + */ + minSpareCols: 0, - }, { - key: 'areAllProposedVisibleColumnsAlreadyRendered', - value: function areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator) { - if (this.columnsVisibleCalculator) { - if (proposedColumnsVisibleCalculator.startColumn < this.columnsRenderCalculator.startColumn || proposedColumnsVisibleCalculator.startColumn === this.columnsRenderCalculator.startColumn && proposedColumnsVisibleCalculator.startColumn > 0) { - return false; - } else if (proposedColumnsVisibleCalculator.endColumn > this.columnsRenderCalculator.endColumn || proposedColumnsVisibleCalculator.endColumn === this.columnsRenderCalculator.endColumn && proposedColumnsVisibleCalculator.endColumn < this.wot.getSetting('totalColumns') - 1) { - return false; - } - return true; - } + /** + * If set to `false`, there won't be an option to insert new rows in the Context Menu. + * + * @type {Boolean} + * @default true + */ + allowInsertRow: true, - return false; - } + /** + * If set to `false`, there won't be an option to insert new columns in the Context Menu. + * + * @type {Boolean} + * @default true + */ + allowInsertColumn: true, - /** - * Resets values in keys of the hasOversizedColumnHeadersMarked object after updateSettings. - */ + /** + * If set to `false`, there won't be an option to remove rows in the Context Menu. + * + * @type {Boolean} + * @default true + */ + allowRemoveRow: true, - }, { - key: 'resetHasOversizedColumnHeadersMarked', - value: function resetHasOversizedColumnHeadersMarked() { - (0, _object.objectEach)(this.hasOversizedColumnHeadersMarked, function (value, key, object) { - object[key] = void 0; - }); - } - }]); + /** + * If set to `false`, there won't be an option to remove columns in the Context Menu. + * + * @type {Boolean} + * @default true + */ + allowRemoveColumn: true, - return Viewport; -}(); + /** + * If true, selection of multiple cells using keyboard or mouse is allowed. + * + * @type {Boolean} + * @default true + */ + multiSelect: true, -exports.default = Viewport; + /** + * Enables the fill handle (drag-down and copy-down) functionality, which shows a small rectangle in bottom + * right corner of the selected area, that let's you expand values to the adjacent cells. + * + * Possible values: `true` (to enable in all directions), `'vertical'` or `'horizontal'` (to enable in one direction), + * `false` (to disable completely). Setting to `true` enables the fillHandle plugin. + * + * Since 0.23.0 you can pass object to plugin which allows you to add more options for this functionality. If `autoInsertRow` + * option is `true`, fill-handler will create new rows till it reaches the last row. It is enabled by default. + * + * @example + * ```js + * ... + * fillHandle: true // enable plugin in all directions and with autoInsertRow as true + * ... + * // or + * ... + * fillHandle: 'vertical' // enable plugin in vertical direction and with autoInsertRow as true + * ... + * // or + * ... + * fillHandle: { // enable plugin in both directions and with autoInsertRow as false + * autoInsertRow: false, + * } + * // or + * ... + * fillHandle: { // enable plugin in vertical direction and with autoInsertRow as false + * autoInsertRow: false, + * direction: 'vertical' // 'vertical' or 'horizontal' + * } + * ``` + * + * @type {Boolean|String|Object} + * @default true + */ + fillHandle: true, -/***/ }), -/* 149 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Allows to specify the number of fixed (or *frozen*) rows at the top of the table. + * + * @type {Number} + * @default 0 + * @example + * ```js + * fixedRowsTop: 3 // This would freeze the top 3 rows of the table. + * ``` + */ + fixedRowsTop: 0, -"use strict"; + /** + * Allows to specify the number of fixed (or *frozen*) rows at the bottom of the table. + * + * @pro + * @type {Number} + * @default 0 + * @example + * ```js + * fixedRowsBottom: 3 // This would freeze the top 3 rows of the table. + * ``` + */ + fixedRowsBottom: 0, + /** + * Allows to specify the number of fixed (or *frozen*) columns on the left of the table. + * + * @type {Number} + * @default 0 + * @example + * ```js + * fixedColumnsLeft: 3 // This would freeze the top 3 rows of the table. + * ``` + */ + fixedColumnsLeft: 0, -exports.__esModule = true; + /** + * If `true`, mouse click outside the grid will deselect the current selection. + * Can be a function that takes the click event target and returns a boolean. + * + * @type {Boolean|Function} + * @default true + */ + outsideClickDeselects: true, -var _unicode = __webpack_require__(16); + /** + * If `true`, ENTER begins editing mode (like in Google Docs). If `false`, ENTER moves to next + * row (like Excel) and adds a new row if necessary. TAB adds new column if necessary. + * + * @type {Boolean} + * @default true + */ + enterBeginsEditing: true, -var _mixed = __webpack_require__(20); + /** + * Defines the cursor movement after ENTER was pressed (SHIFT + ENTER uses a negative vector). + * Can be an object or a function that returns an object. The event argument passed to the function + * is a DOM Event object received after the ENTER key has been pressed. This event object can be used to check + * whether user pressed ENTER or SHIFT + ENTER. + * + * @type {Object|Function} + * @default {row: 1, col: 0} + */ + enterMoves: { row: 1, col: 0 }, -var _string = __webpack_require__(27); + /** + * Defines the cursor movement after TAB is pressed (SHIFT + TAB uses a negative vector). + * Can be an object or a function that returns an object. The event argument passed to the function + * is a DOM Event object received after the TAB key has been pressed. This event object can be used to check + * whether user pressed TAB or SHIFT + TAB. + * + * @type {Object} + * @default {row: 0, col: 1} + */ + tabMoves: { row: 0, col: 1 }, -var _array = __webpack_require__(2); + /** + * If `true`, pressing TAB or right arrow in the last column will move to first column in next row. + * + * @type {Boolean} + * @default false + */ + autoWrapRow: false, -var _element = __webpack_require__(0); + /** + * If `true`, pressing ENTER or down arrow in the last row will move to the first row in the next column. + * + * @type {Boolean} + * @default false + */ + autoWrapCol: false, -var _handsontableEditor = __webpack_require__(150); + /** + * @description + * Turns on saving the state of column sorting, column positions and column sizes in local storage. + * + * You can save any sort of data in local storage to preserve table state between page reloads. + * In order to enable data storage mechanism, `persistentState` option must be set to `true` (you can set it + * either during Handsontable initialization or using the `updateSettings` method). When `persistentState` is enabled it exposes 3 hooks: + * + * __persistentStateSave__ (key: String, value: Mixed) + * + * * Saves value under given key in browser local storage. + * + * __persistentStateLoad__ (key: String, valuePlaceholder: Object) + * + * * Loads `value`, saved under given key, form browser local storage. The loaded `value` will be saved in `valuePlaceholder.value` + * (this is due to specific behaviour of `Hooks.run()` method). If no value have been saved under key `valuePlaceholder.value` + * will be `undefined`. + * + * __persistentStateReset__ (key: String) + * + * * Clears the value saved under `key`. If no `key` is given, all values associated with table will be cleared. + * + * __Note:__ The main reason behind using `persistentState` hooks rather than regular LocalStorage API is that it + * ensures separation of data stored by multiple Handsontable instances. In other words, if you have two (or more) + * instances of Handsontable on one page, data saved by one instance won't be accessible by the second instance. + * Those two instances can store data under the same key and no data would be overwritten. + * + * __Important:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`. + * + * @type {Boolean} + * @default false + */ + persistentState: void 0, -var _handsontableEditor2 = _interopRequireDefault(_handsontableEditor); + /** + * Class name for all visible rows in the current selection. + * + * @type {String} + * @default undefined + * @example + * ```js + * currentRowClassName: 'currentRow' // This will add a 'currentRow' class name to appropriate table cells. + * ``` + */ + currentRowClassName: void 0, -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** + * Class name for all visible columns in the current selection. + * + * @type {String} + * @default undefined + * @example + * ```js + * currentColClassName: 'currentColumn' // This will add a 'currentColumn' class name to appropriate table cells. + * ``` + */ + currentColClassName: void 0, -var AutocompleteEditor = _handsontableEditor2.default.prototype.extend(); + /** + * Class name for all visible headers in current selection. + * + * @type {String} + * @since 0.27.0 + * @default 'ht__highlight' + * @example + * ```js + * currentHeaderClassName: 'ht__highlight' // This will add a 'ht__highlight' class name to appropriate table headers. + * ``` + */ + currentHeaderClassName: 'ht__highlight', + /** + * Class name for the Handsontable container element. + * + * @type {String|Array} + * @default undefined + */ + className: void 0, -/** - * @private - * @editor AutocompleteEditor - * @class AutocompleteEditor - * @dependencies HandsontableEditor - */ -AutocompleteEditor.prototype.init = function () { - _handsontableEditor2.default.prototype.init.apply(this, arguments); - this.query = null; - this.strippedChoices = []; - this.rawChoices = []; -}; + /** + * Class name for all tables inside container element. + * + * @since 0.17.0 + * @type {String|Array} + * @default undefined + */ + tableClassName: void 0, -AutocompleteEditor.prototype.getValue = function () { - var _this2 = this; + /** + * @description + * Defines how the columns react, when the declared table width is different than the calculated sum of all column widths. + * [See more](http://docs.handsontable.com/demo-stretching.html) mode. Possible values: + * * `'none'` Disable stretching + * * `'last'` Stretch only the last column + * * `'all'` Stretch all the columns evenly + * + * @type {String} + * @default 'none' + */ + stretchH: 'none', - var selectedValue = this.rawChoices.find(function (value) { - var strippedValue = _this2.stripValueIfNeeded(value); + /** + * Lets you overwrite the default `isEmptyRow` method, which checks if row at the provided index is empty. + * + * @type {Function} + * @param {Number} row Visual row index. + * @returns {Boolean} + */ + isEmptyRow: function isEmptyRow(row) { + var col, colLen, value, meta; - return strippedValue === _this2.TEXTAREA.value; - }); + for (col = 0, colLen = this.countCols(); col < colLen; col++) { + value = this.getDataAtCell(row, col); - if ((0, _mixed.isDefined)(selectedValue)) { - return selectedValue; - } + if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) { + if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') { + meta = this.getCellMeta(row, col); - return this.TEXTAREA.value; -}; + return (0, _object.isObjectEquals)(this.getSchema()[meta.prop], value); + } + return false; + } + } -AutocompleteEditor.prototype.createElements = function () { - _handsontableEditor2.default.prototype.createElements.apply(this, arguments); + return true; + }, - (0, _element.addClass)(this.htContainer, 'autocompleteEditor'); - (0, _element.addClass)(this.htContainer, window.navigator.platform.indexOf('Mac') === -1 ? '' : 'htMacScroll'); -}; -var skipOne = false; -function onBeforeKeyDown(event) { - skipOne = false; - var editor = this.getActiveEditor(); + /** + * Lets you overwrite the default `isEmptyCol` method, which checks if column at the provided index is empty. + * + * @type {Function} + * @param {Number} col Visual column index + * @returns {Boolean} + */ + isEmptyCol: function isEmptyCol(col) { + var row, rowLen, value; - if ((0, _unicode.isPrintableChar)(event.keyCode) || event.keyCode === _unicode.KEY_CODES.BACKSPACE || event.keyCode === _unicode.KEY_CODES.DELETE || event.keyCode === _unicode.KEY_CODES.INSERT) { - var timeOffset = 0; + for (row = 0, rowLen = this.countRows(); row < rowLen; row++) { + value = this.getDataAtCell(row, col); - // on ctl+c / cmd+c don't update suggestion list - if (event.keyCode === _unicode.KEY_CODES.C && (event.ctrlKey || event.metaKey)) { - return; - } - if (!editor.isOpened()) { - timeOffset += 10; + if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) { + return false; + } } - if (editor.htEditor) { - editor.instance._registerTimeout(setTimeout(function () { - editor.queryChoices(editor.TEXTAREA.value); - skipOne = true; - }, timeOffset)); - } - } -} + return true; + }, -AutocompleteEditor.prototype.prepare = function () { - this.instance.addHook('beforeKeyDown', onBeforeKeyDown); - _handsontableEditor2.default.prototype.prepare.apply(this, arguments); -}; -AutocompleteEditor.prototype.open = function () { - // Ugly fix for handsontable which grab window object for autocomplete scroll listener instead table element. - this.TEXTAREA_PARENT.style.overflow = 'auto'; - _handsontableEditor2.default.prototype.open.apply(this, arguments); - this.TEXTAREA_PARENT.style.overflow = ''; + /** + * When set to `true`, the table is re-rendered when it is detected that it was made visible in DOM. + * + * @type {Boolean} + * @default true + */ + observeDOMVisibility: true, - var choicesListHot = this.htEditor.getInstance(); - var _this = this; - var trimDropdown = this.cellProperties.trimDropdown === void 0 ? true : this.cellProperties.trimDropdown; + /** + * If set to `true`, Handsontable will accept values that were marked as invalid by the cell `validator`. + * It will result with *invalid* cells being treated as *valid* (will save the *invalid* value into the Handsontable data source). + * If set to `false`, Handsontable will *not* accept the invalid values and won't allow the user to close the editor. + * This option will be particularly useful when used with the Autocomplete's `strict` mode. + * + * @type {Boolean} + * @default true + * @since 0.9.5 + */ + allowInvalid: true, - this.TEXTAREA.style.visibility = 'visible'; - this.focus(); + /** + * If set to `true`, Handsontable will accept values that are empty (`null`, `undefined` or `''`). + * If set to `false`, Handsontable will *not* accept the empty values and mark cell as invalid. + * + * @example + * ```js + * ... + * allowEmpty: true // allow empty values for all cells (whole table) + * ... + * // or + * ... + * columns: [ + * // allow empty values only for 'date' column + * {data: 'date', dateFormat: 'DD/MM/YYYY', allowEmpty: true} + * ] + * ... + * ``` + * + * @type {Boolean} + * @default true + * @since 0.23.0 + */ + allowEmpty: true, - choicesListHot.updateSettings({ - colWidths: trimDropdown ? [(0, _element.outerWidth)(this.TEXTAREA) - 2] : void 0, - width: trimDropdown ? (0, _element.outerWidth)(this.TEXTAREA) + (0, _element.getScrollbarWidth)() + 2 : void 0, - afterRenderer: function afterRenderer(TD, row, col, prop, value, cellProperties) { - var _this$cellProperties = _this.cellProperties, - filteringCaseSensitive = _this$cellProperties.filteringCaseSensitive, - allowHtml = _this$cellProperties.allowHtml; + /** + * CSS class name for cells that did not pass validation. + * + * @type {String} + * @default 'htInvalid' + */ + invalidCellClassName: 'htInvalid', - var indexOfMatch = void 0; - var match = void 0; + /** + * When set to an non-empty string, displayed as the cell content for empty cells. If a value of a different type is provided, + * it will be stringified and applied as a string. + * + * @type {Mixed} + * @default false + */ + placeholder: false, - value = (0, _mixed.stringify)(value); + /** + * CSS class name for cells that have a placeholder in use. + * + * @type {String} + * @default 'htPlaceholder' + */ + placeholderCellClassName: 'htPlaceholder', - if (value && !allowHtml) { - indexOfMatch = filteringCaseSensitive === true ? value.indexOf(this.query) : value.toLowerCase().indexOf(_this.query.toLowerCase()); + /** + * CSS class name for read-only cells. + * + * @type {String} + * @default 'htDimmed' + */ + readOnlyCellClassName: 'htDimmed', - if (indexOfMatch !== -1) { - match = value.substr(indexOfMatch, _this.query.length); - value = value.replace(match, '' + match + ''); - } - } - TD.innerHTML = value; - }, + /** + * @description + * If a string is provided, it may be one of the following predefined values: + * * `autocomplete`, + * * `checkbox`, + * * `html`, + * * `numeric`, + * * `password`. + * * `text`. + * + * Or you can [register](http://docs.handsontable.com/demo-custom-renderers.html) the custom renderer under specified name and use + * its name as an alias in your configuration. + * + * If a function is provided, it will receive the following arguments: + * ```js + * function(instance, TD, row, col, prop, value, cellProperties) {} + * ``` + * + * You can read more about custom renderes [in the documentation](http://docs.handsontable.com/demo-custom-renderers.html). + * + * @example + * ```js + * ... + * Handsontable.renderers.registerRenderer('my.renderer', function(instance, TD, row, col, prop, value, cellProperties) { + * TD.innerHTML = value; + * }); + * ... + * columns: [ + * { + * editor: 'select', + * renderer: 'autocomplete' // as string + * }, + * { + * renderer: 'my.renderer' // custom renderer as an alias + * }, + * { + * // renderer as custom function + * renderer: function(hotInstance, TD, row, col, prop, value, cellProperties) { + * TD.style.color = 'blue'; + * TD.innerHTML = value; + * } + * } + * ] + * ... + * ``` + * + * @type {String|Function} + * @default undefined + */ + renderer: void 0, - autoColumnSize: true, - modifyColWidth: function modifyColWidth(width, col) { - // workaround for text overlapping the dropdown, not really accurate - var autoWidths = this.getPlugin('autoColumnSize').widths; + /** + * CSS class name added to the commented cells. + * + * @type {String} + * @default 'htCommentCell' + */ + commentedCellClassName: 'htCommentCell', - if (autoWidths[col]) { - width = autoWidths[col]; - } + /** + * If set to `true`, it enables the browser's native selection of a fragment of the text within a single cell, between adjacent cells or in a whole table. + * If set to `'cell'`, it enables the possibility of selecting a fragment of the text within a single cell's body. + * + * @type {Boolean|String} + * @default false + */ + fragmentSelection: false, - return trimDropdown ? width : width + 15; - } - }); + /** + * @description + * Make cell [read only](http://docs.handsontable.com/demo-read-only.html). + * + * @type {Boolean} + * @default false + */ + readOnly: false, - // Add additional space for autocomplete holder - this.htEditor.view.wt.wtTable.holder.parentNode.style['padding-right'] = (0, _element.getScrollbarWidth)() + 2 + 'px'; + /** + * @description + * When added to a `column` property, it skips the column on paste and pastes the data on the next column to the right. + * + * @type {Boolean} + * @default false + */ + skipColumnOnPaste: false, - if (skipOne) { - skipOne = false; - } + /** + * @description + * Setting to true enables the search plugin (see [demo](http://docs.handsontable.com/demo-search-for-values.html)). + * + * @type {Boolean} + * @default false + */ + search: false, - _this.instance._registerTimeout(setTimeout(function () { - _this.queryChoices(_this.TEXTAREA.value); - }, 0)); -}; + /** + * @description + * Shortcut to define the combination of the cell renderer, editor and validator for the column, cell or whole table. + * + * Possible values: + * * [autocomplete](http://docs.handsontable.com/demo-autocomplete.html) + * * [checkbox](http://docs.handsontable.com/demo-checkbox.html) + * * [date](http://docs.handsontable.com/demo-date.html) + * * [dropdown](http://docs.handsontable.com/demo-dropdown.html) + * * [handsontable](http://docs.handsontable.com/demo-handsontable.html) + * * [numeric](http://docs.handsontable.com/demo-numeric.html) + * * [password](http://docs.handsontable.com/demo-password.html) + * * text + * * [time](http://docs.handsontable.com/demo-time.html) + * + * Or you can register the custom cell type under specified name and use + * its name as an alias in your configuration. + * + * @example + * ```js + * ... + * Handsontable.cellTypes.registerCellType('my.type', { + * editor: MyEditorClass, + * renderer: function(hot, td, row, col, prop, value, cellProperties) { + * td.innerHTML = value; + * }, + * validator: function(value, callback) { + * callback(value === 'foo' ? true : false); + * } + * }); + * ... + * columns: [ + * { + * type: 'text' + * }, + * { + * type: 'my.type' // an alias to custom type + * }, + * { + * type: 'checkbox' + * } + * ] + * ... + * ``` + * + * @type {String} + * @default 'text' + */ + type: 'text', -AutocompleteEditor.prototype.close = function () { - _handsontableEditor2.default.prototype.close.apply(this, arguments); -}; -AutocompleteEditor.prototype.queryChoices = function (query) { - var _this3 = this; + /** + * @description + * Make cell copyable (pressing CTRL + C on your keyboard moves its value to system clipboard). + * + * __Note:__ this setting is `false` by default for cells with type `password`. + * + * @type {Boolean} + * @default true + * @since 0.10.2 + */ + copyable: true, - this.query = query; - var source = this.cellProperties.source; + /** + * Defines the editor for the table/column/cell. + * + * If a string is provided, it may be one of the following predefined values: + * * [autocomplete](http://docs.handsontable.com/demo-autocomplete.html) + * * [checkbox](http://docs.handsontable.com/demo-checkbox.html) + * * [date](http://docs.handsontable.com/demo-date.html) + * * [dropdown](http://docs.handsontable.com/demo-dropdown.html) + * * [handsontable](http://docs.handsontable.com/demo-handsontable.html) + * * [mobile](http://docs.handsontable.com/demo-mobiles-and-tablets.html) + * * [password](http://docs.handsontable.com/demo-password.html) + * * [select](http://docs.handsontable.com/demo-select.html) + * * text + * + * Or you can [register](http://docs.handsontable.com/tutorial-cell-editor.html#registering-an-editor) the custom editor under specified name and use + * its name as an alias in your configuration. + * + * To disable cell editing completely set `editor` property to `false`. + * + * @example + * ```js + * ... + * columns: [ + * { + * editor: 'select' + * }, + * { + * editor: false + * } + * ] + * ... + * ``` + * + * @type {String|Function|Boolean} + * @default 'text' + */ + editor: void 0, - if (typeof source == 'function') { - source.call(this.cellProperties, query, function (choices) { - _this3.rawChoices = choices; - _this3.updateChoicesList(_this3.stripValuesIfNeeded(choices)); - }); - } else if (Array.isArray(source)) { - this.rawChoices = source; - this.updateChoicesList(this.stripValuesIfNeeded(source)); - } else { - this.updateChoicesList([]); - } -}; + /** + * @description + * Autocomplete definitions. See [autocomplete demo](http://docs.handsontable.com/demo-autocomplete.html) for examples and definitions. + * + * @type {Array} + * @default undefined + */ + autoComplete: void 0, -AutocompleteEditor.prototype.updateChoicesList = function (choices) { - var pos = (0, _element.getCaretPosition)(this.TEXTAREA); - var endPos = (0, _element.getSelectionEndPosition)(this.TEXTAREA); - var sortByRelevanceSetting = this.cellProperties.sortByRelevance; - var filterSetting = this.cellProperties.filter; - var orderByRelevance = null; - var highlightIndex = null; + /** + * Control number of choices for the autocomplete (or dropdown) typed cells. After exceeding it, a scrollbar for the dropdown list of choices will appear. + * + * @since 0.18.0 + * @type {Number} + * @default 10 + */ + visibleRows: 10, - if (sortByRelevanceSetting) { - orderByRelevance = AutocompleteEditor.sortByRelevance(this.stripValueIfNeeded(this.getValue()), choices, this.cellProperties.filteringCaseSensitive); - } - var orderByRelevanceLength = Array.isArray(orderByRelevance) ? orderByRelevance.length : 0; + /** + * Makes autocomplete or dropdown width the same as the edited cell width. If `false` then editor will be scaled + * according to its content. + * + * @since 0.17.0 + * @type {Boolean} + * @default true + */ + trimDropdown: true, - if (filterSetting === false) { - if (orderByRelevanceLength) { - highlightIndex = orderByRelevance[0]; - } - } else { - var sorted = []; + /** + * Setting to true enables the debug mode, currently used to test the correctness of the row and column + * header fixed positioning on a layer above the master table. + * + * @type {Boolean} + * @default false + */ + debug: false, - for (var i = 0, choicesCount = choices.length; i < choicesCount; i++) { - if (sortByRelevanceSetting && orderByRelevanceLength <= i) { - break; - } - if (orderByRelevanceLength) { - sorted.push(choices[orderByRelevance[i]]); - } else { - sorted.push(choices[i]); - } - } + /** + * When set to `true`, the text of the cell content is wrapped if it does not fit in the fixed column width. + * + * @type {Boolean} + * @default true + * @since 0.11.0 + */ + wordWrap: true, - highlightIndex = 0; - choices = sorted; - } + /** + * CSS class name added to cells with cell meta `wordWrap: false`. + * + * @type {String} + * @default 'htNoWrap' + * @since 0.11.0 + */ + noWordWrapClassName: 'htNoWrap', + + /** + * @description + * Defines if the right-click context menu should be enabled. Context menu allows to create new row or + * column at any place in the grid among [other features](http://docs.handsontable.com/demo-context-menu.html). + * Possible values: + * * `true` (to enable default options), + * * `false` (to disable completely) + * * an array of [predefined options](https://docs.handsontable.com/demo-context-menu.html#page-specific), + * * an object [with defined structure](http://docs.handsontable.com/demo-context-menu.html#page-custom) + * + * See [the context menu demo](http://docs.handsontable.com/demo-context-menu.html) for examples. + * + * @example + * ```js + * ... + * // as a boolean + * contextMenu: true + * ... + * // as an array + * contextMenu: ['row_above', 'row_below', '--------', 'undo', 'redo'] + * ... + * ``` + * ... + * // as an object (`name` attribute is required in the custom keys) + * contextMenu: { + * items: { + * "option1": { + * name: "option1" + * }, + * "option2": { + * name: "option2", + * submenu: { + * items: [ + * { + * key: "option2:suboption1", + * name: "option2:suboption1", + * callback: function(key, options) { + * ... + * } + * }, + * ... + * ] + * } + * } + * } + * } + * ... + * ``` + * @type {Boolean|Array|Object} + * @default undefined + */ + contextMenu: void 0, - this.strippedChoices = choices; - this.htEditor.loadData((0, _array.pivot)([choices])); + /** + * @description + * Disable or enable the copy/paste functionality. + * + * @example + * ```js + * ... + * copyPaste: false, + * ... + * ``` + * + * @type {Boolean} + * @default true + */ + copyPaste: true, - this.updateDropdownHeight(); + /** + * If `true`, undo/redo functionality is enabled. + * + * @type {Boolean} + * @default undefined + */ + undo: void 0, - this.flipDropdownIfNeeded(); + /** + * @description + * Turns on [Column sorting](http://docs.handsontable.com/demo-sorting-data.html). + * Can be either a boolean (true/false) or an object with a declared sorting options. See the below example: + * + * @example + * ```js + * ... + * // as boolean + * columnSorting: true + * ... + * // as a object with initial order (sort ascending column at index 2) + * columnSorting: { + * column: 2, + * sortOrder: true, // true = ascending, false = descending, undefined = original order + * sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table + * } + * ... + * ``` + * + * @type {Boolean|Object} + * @default undefined + */ + columnSorting: void 0, - if (this.cellProperties.strict === true) { - this.highlightBestMatchingChoice(highlightIndex); - } + /** + * @description + * Turns on [Manual column move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial + * column order, if set to an array of column indexes. + * + * @example + * ```js + * ... + * // as boolean + * manualColumnMove: true + * ... + * // as a array with initial order (move column index at 0 to 1 and move column index at 1 to 4) + * manualColumnMove: [1, 4] + * ... + * ``` + * + * @type {Boolean|Array} + * @default undefined + */ + manualColumnMove: void 0, - this.instance.listen(); - this.TEXTAREA.focus(); - (0, _element.setCaretPosition)(this.TEXTAREA, pos, pos === endPos ? void 0 : endPos); -}; + /** + * @description + * Turns on [Manual column resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial + * column resized widths, if set to an array of numbers. + * + * @example + * ```js + * ... + * // as boolean + * manualColumnResize: true + * ... + * // as a array with initial widths (column at 0 index has 40px and column at 1 index has 50px) + * manualColumnResize: [40, 50] + * ... + * ``` + * + * @type {Boolean|Array} + * @default undefined + */ + manualColumnResize: void 0, -AutocompleteEditor.prototype.flipDropdownIfNeeded = function () { - var textareaOffset = (0, _element.offset)(this.TEXTAREA); - var textareaHeight = (0, _element.outerHeight)(this.TEXTAREA); - var dropdownHeight = this.getDropdownHeight(); - var trimmingContainer = (0, _element.getTrimmingContainer)(this.instance.view.wt.wtTable.TABLE); - var trimmingContainerScrollTop = trimmingContainer.scrollTop; - var headersHeight = (0, _element.outerHeight)(this.instance.view.wt.wtTable.THEAD); - var containerOffset = { - row: 0, - col: 0 - }; + /** + * @description + * Turns on [Manual row move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial + * row order, if set to an array of row indexes. + * + * @example + * ```js + * ... + * // as boolean + * manualRowMove: true + * ... + * // as a array with initial order (move row index at 0 to 1 and move row index at 1 to 4) + * manualRowMove: [1, 4] + * ... + * ``` + * + * @type {Boolean|Array} + * @default undefined + * @since 0.11.0 + */ + manualRowMove: void 0, - if (trimmingContainer !== window) { - containerOffset = (0, _element.offset)(trimmingContainer); - } + /** + * @description + * Turns on [Manual row resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial + * row resized heights, if set to an array of numbers. + * + * @example + * ```js + * ... + * // as boolean + * manualRowResize: true + * ... + * // as a array with initial heights (row at 0 index has 40px and row at 1 index has 50px) + * manualRowResize: [40, 50] + * ... + * ``` + * + * @type {Boolean|Array} + * @default undefined + * @since 0.11.0 + */ + manualRowResize: void 0, - var spaceAbove = textareaOffset.top - containerOffset.top - headersHeight + trimmingContainerScrollTop; - var spaceBelow = trimmingContainer.scrollHeight - spaceAbove - headersHeight - textareaHeight; - var flipNeeded = dropdownHeight > spaceBelow && spaceAbove > spaceBelow; + /** + * @description + * If set to `true`, it enables a possibility to merge cells. If set to an array of objects, it merges the cells provided in the objects (see the example below). + * [More information on the demo page.](http://docs.handsontable.com/demo-merge-cells.html) + * + * @example + * ```js + * // enables the mergeCells plugin: + * margeCells: true + * ... + * // declares a list of merged sections: + * mergeCells: [ + * {row: 1, col: 1, rowspan: 3, colspan: 3}, // rowspan and colspan properties declare the width and height of a merged section in cells + * {row: 3, col: 4, rowspan: 2, colspan: 2}, + * {row: 5, col: 6, rowspan: 3, colspan: 3} + * ] + * ``` + * @type {Boolean|Array} + * @default false + */ + mergeCells: false, - if (flipNeeded) { - this.flipDropdown(dropdownHeight); - } else { - this.unflipDropdown(); - } + /** + * Number of rows to be rendered outside of the visible part of the table. + * By default, it's set to `'auto'`, which makes Handsontable to attempt to calculate the best offset performance-wise. + * + * You may test out different values to find the best one that works for your specific implementation. + * + * @type {Number|String} + * @default 'auto' + */ + viewportRowRenderingOffset: 'auto', - this.limitDropdownIfNeeded(flipNeeded ? spaceAbove : spaceBelow, dropdownHeight); + /** + * Number of columns to be rendered outside of the visible part of the table. + * By default, it's set to `'auto'`, which makes Handsontable try calculating the best offset performance-wise. + * + * You may experiment with the value to find the one that works best for your specific implementation. + * + * @type {Number|String} + * @default 'auto' + */ + viewportColumnRenderingOffset: 'auto', - return flipNeeded; -}; + /** + * A function, regular expression or a string, which will be used in the process of cell validation. + * If a function is used, be sure to execute the callback argument with either `true` (`callback(true)`) if the validation passed + * or with `false` (`callback(false)`), if the validation failed. + * Note, that `this` in the function points to the `cellProperties` object. + * + * If a string is provided, it may be one of the following predefined values: + * * `autocomplete`, + * * `date`, + * * `numeric`, + * * `time`. + * + * Or you can [register](http://docs.handsontable.com/demo-data-validation.html) the validator function under specified name and use + * its name as an alias in your configuration. + * + * See more [in the demo](http://docs.handsontable.com/demo-data-validation.html). + * + * @example + * ```js + * // as a function + * columns: [ + * { + * validator: function(value, callback) { // validation rules } + * } + * ] + * ... + * // as a regexp + * columns: [ + * { + * validator: /^[0-9]$/ // regular expression + * } + * ] + * // as a string + * columns: [ + * { + * validator: 'numeric' + * } + * ] + * ``` + * @type {Function|RegExp|String} + * @default undefined + * @since 0.9.5 + */ + validator: void 0, -AutocompleteEditor.prototype.limitDropdownIfNeeded = function (spaceAvailable, dropdownHeight) { - if (dropdownHeight > spaceAvailable) { - var tempHeight = 0; - var i = 0; - var lastRowHeight = 0; - var height = null; + /** + * @description + * Disable visual cells selection. + * + * Possible values: + * * `true` - Disables any type of visual selection (current and area selection), + * * `false` - Enables any type of visual selection. This is default value. + * * `current` - Disables the selection of a currently selected cell, the area selection is still present. + * * `area` - Disables the area selection, the currently selected cell selection is still present. + * + * @type {Boolean|String|Array} + * @default false + * @since 0.13.2 + * @example + * ```js + * ... + * // as boolean + * disableVisualSelection: true, + * ... + * + * ... + * // as string ('current' or 'area') + * disableVisualSelection: 'current', + * ... + * + * ... + * // as array + * disableVisualSelection: ['current', 'area'], + * ... + * ``` + */ + disableVisualSelection: false, - do { - lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view.wt.wtSettings.settings.defaultRowHeight; - tempHeight += lastRowHeight; - i++; - } while (tempHeight < spaceAvailable); + /** + * @description + * Set whether to display the current sorting order indicator (a triangle icon in the column header, specifying the sorting order). + * + * @type {Boolean} + * @default false + * @since 0.15.0-beta3 + */ + sortIndicator: void 0, - height = tempHeight - lastRowHeight; + /** + * Disable or enable ManualColumnFreeze plugin. + * + * @type {Boolean} + * @default false + */ + manualColumnFreeze: void 0, - if (this.htEditor.flipped) { - this.htEditor.rootElement.style.top = parseInt(this.htEditor.rootElement.style.top, 10) + dropdownHeight - height + 'px'; - } + /** + * @description + * Defines whether Handsontable should trim the whitespace at the beginning and the end of the cell contents. + * + * @type {Boolean} + * @default true + */ + trimWhitespace: true, - this.setDropdownHeight(tempHeight - lastRowHeight); - } -}; + settings: void 0, -AutocompleteEditor.prototype.flipDropdown = function (dropdownHeight) { - var dropdownStyle = this.htEditor.rootElement.style; + /** + * @description + * Defines data source for Autocomplete or Dropdown cell types. + * + * @example + * ```js + * ... + * // source as a array + * columns: [{ + * type: 'autocomplete', + * source: ['A', 'B', 'C', 'D'] + * }] + * ... + * // source as a function + * columns: [{ + * type: 'autocomplete', + * source: function(query, callback) { + * fetch('http://example.com/query?q=' + query, function(response) { + * callback(response.items); + * }) + * } + * }] + * ... + * ``` + * + * @type {Array|Function} + * @default undefined + */ + source: void 0, - dropdownStyle.position = 'absolute'; - dropdownStyle.top = -dropdownHeight + 'px'; + /** + * @description + * Defines the column header name. + * + * @example + * ```js + * ... + * columns: [{ + * title: 'First name', + * type: 'text', + * }, + * { + * title: 'Last name', + * type: 'text', + * }] + * ... + * ``` + * + * @type {String} + * @default undefined + */ + title: void 0, - this.htEditor.flipped = true; -}; + /** + * Data template for `'checkbox'` type when checkbox is checked. + * + * @example + * ```js + * checkedTemplate: 'good' + * + * // if a checkbox-typed cell is checked, then getDataAtCell(x,y), where x and y are the coordinates of the cell + * // will return 'good'. + * ``` + * @type {Boolean|String} + * @default true + */ + checkedTemplate: void 0, -AutocompleteEditor.prototype.unflipDropdown = function () { - var dropdownStyle = this.htEditor.rootElement.style; + /** + * Data template for `'checkbox'` type when checkbox is unchecked. + * + * @example + * ```js + * uncheckedTemplate: 'bad' + * + * // if a checkbox-typed cell is not checked, then getDataAtCell(x,y), where x and y are the coordinates of the cell + * // will return 'bad'. + * ``` + * @type {Boolean|String} + * @default false + */ + uncheckedTemplate: void 0, - if (dropdownStyle.position === 'absolute') { - dropdownStyle.position = ''; - dropdownStyle.top = ''; - } + /** + * @description + * Object which describes if renderer should create checkbox element with label element as a parent. Option desired for + * [checkbox](http://docs.handsontable.com/demo-checkbox.html)-typed cells. + * + * By default the [checkbox](http://docs.handsontable.com/demo-checkbox.html) renderer renders the checkbox without a label. + * + * Possible object properties: + * * `property` - Defines the property name of the data object, which will to be used as a label. + * (eg. `label: {property: 'name.last'}`). This option works only if data was passed as an array of objects. + * * `position` - String which describes where to place the label text (before or after checkbox element). + * Valid values are `'before'` and '`after`' (defaults to `'after'`). + * * `value` - String or a Function which will be used as label text. + * + * @example + * ```js + * ... + * columns: [{ + * type: 'checkbox', + * label: {position: 'after', value: 'My label: '} + * }] + * ... + * ``` + * + * @since 0.19.0 + * @type {Object} + * @default undefined + */ + label: void 0, - this.htEditor.flipped = void 0; -}; + /** + * Display format. See [numbrojs](http://numbrojs.com). This option is desired for + * [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells. + * + * Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting. + * + * @example + * ```js + * ... + * columns: [{ + * type: 'numeric', + * format: '0,00' + * }] + * ... + * ``` + * + * @type {String} + * @default '0' + */ + format: void 0, -AutocompleteEditor.prototype.updateDropdownHeight = function () { - var currentDropdownWidth = this.htEditor.getColWidth(0) + (0, _element.getScrollbarWidth)() + 2; - var trimDropdown = this.cellProperties.trimDropdown; + /** + * Language display format. See [numbrojs](http://numbrojs.com/languages.html#supported-languages). This option is desired for + * [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells. + * + * Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting. + * + * @example + * ```js + * ... + * columns: [{ + * type: 'numeric', + * language: 'en-US' + * }] + * ... + * ``` + * + * @type {String} + * @default 'en-US' + */ + language: void 0, - this.htEditor.updateSettings({ - height: this.getDropdownHeight(), - width: trimDropdown ? void 0 : currentDropdownWidth - }); + /** + * @description + * Data source for [select](http://docs.handsontable.com/demo-select.html)-typed cells. + * + * @example + * ```js + * ... + * columns: [{ + * editor: 'select', + * selectOptions: ['A', 'B', 'C'], + * }] + * ... + * ``` + * + * @type {Array} + */ + selectOptions: void 0, - this.htEditor.view.wt.wtTable.alignOverlaysWithTrimmingContainer(); -}; + /** + * Enables or disables the autoColumnSize plugin. Default value is `undefined`, which has the same effect as `true`. + * Disabling this plugin can increase performance, as no size-related calculations would be done. + * + * Column width calculations are divided into sync and async part. Each of this parts has their own advantages and + * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't + * block the browser UI. + * + * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value. + * `syncLimit` option is available since 0.16.0. + * + * You can also use the `useHeaders` option to take the column headers with into calculation. + * + * @example + * ```js + * ... + * // as a number (300 columns in sync, rest async) + * autoColumnSize: {syncLimit: 300}, + * ... + * + * ... + * // as a string (percent) + * autoColumnSize: {syncLimit: '40%'}, + * ... + * + * ... + * // use headers width while calculation the column width + * autoColumnSize: {useHeaders: true}, + * ... + * + * ``` + * + * @type {Object|Boolean} + * @default {syncLimit: 50} + */ + autoColumnSize: void 0, -AutocompleteEditor.prototype.setDropdownHeight = function (height) { - this.htEditor.updateSettings({ - height: height - }); -}; + /** + * Enables or disables autoRowSize plugin. Default value is `undefined`, which has the same effect as `false` (disabled). + * Enabling this plugin can decrease performance, as size-related calculations would be performed. + * + * Row height calculations are divided into sync and async stages. Each of these stages has their own advantages and + * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't + * block the browser UI. + * + * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value. + * `syncLimit` options is available since 0.16.0. + * + * @example + * ```js + * ... + * // as number (300 columns in sync, rest async) + * autoRowSize: {syncLimit: 300}, + * ... + * + * ... + * // as string (percent) + * autoRowSize: {syncLimit: '40%'}, + * ... + * ``` + * @type {Object|Boolean} + * @default {syncLimit: 1000} + */ + autoRowSize: void 0, -AutocompleteEditor.prototype.finishEditing = function (restoreOriginalValue) { - if (!restoreOriginalValue) { - this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); - } - _handsontableEditor2.default.prototype.finishEditing.apply(this, arguments); -}; + /** + * Date validation format. + * + * Option desired for `'date'` - typed cells. + * + * @example + * ```js + * ... + * columns: [{ + * type: 'date', + * dateFormat: 'MM/DD/YYYY' + * }] + * ... + * ``` + * + * @type {String} + * @default 'DD/MM/YYYY' + */ + dateFormat: void 0, -AutocompleteEditor.prototype.highlightBestMatchingChoice = function (index) { - if (typeof index === 'number') { - this.htEditor.selectCell(index, 0); - } else { - this.htEditor.deselectCell(); - } -}; + /** + * If `true` then dates will be automatically formatted to match the desired format. + * + * Option desired for `'date'`-typed typed cells. + * + * @example + * ```js + * ... + * columns: [{ + * type: 'date', + * dateFormat: 'YYYY-MM-DD', + * correctFormat: true + * }] + * ... + * ``` + * + * @type {Boolean} + * @default false + */ + correctFormat: false, -/** - * Filters and sorts by relevance - * @param value - * @param choices - * @param caseSensitive - * @returns {Array} array of indexes in original choices array - */ -AutocompleteEditor.sortByRelevance = function (value, choices, caseSensitive) { - var choicesRelevance = []; - var currentItem = void 0; - var valueLength = value.length; - var valueIndex = void 0; - var charsLeft = void 0; - var result = []; - var i = void 0; - var choicesCount = choices.length; + /** + * Definition of default value which will fill the empty cells. + * + * Option desired for `'date'`-typed cells. + * + * @example + * ```js + * ... + * columns: [{ + * type: 'date', + * defaultData: '2015-02-02' + * }] + * ... + * ``` + * + * @type {String} + */ + defaultDate: void 0, - if (valueLength === 0) { - for (i = 0; i < choicesCount; i++) { - result.push(i); - } - return result; - } + /** + * If set to `true`, the value entered into the cell must match (case-sensitive) the autocomplete source. Otherwise, cell won't pass the validation. + * When filtering the autocomplete source list, the editor will be working in case-insensitive mode. + * + * Option desired for `autocomplete`-typed cells. + * + * @example + * ```js + * ... + * columns: [{ + * type: 'autocomplete', + * source: ['A', 'B', 'C'], + * strict: true + * }] + * ... + * ``` + * + * @type {Boolean} + */ + strict: void 0, - for (i = 0; i < choicesCount; i++) { - currentItem = (0, _string.stripTags)((0, _mixed.stringify)(choices[i])); + /** + * @description + * If typed `true`, data defined in `source` of the autocomplete or dropdown cell will be treated as HTML. + * + * __Warning:__ Enabling this option can cause serious XSS vulnerabilities. + * + * Option desired for `'autocomplete'`-typed cells. + * @example + * ```js + * ... + * columns: [{ + * type: 'autocomplete', + * allowHtml: true, + * source: ['foo', 'bar'] + * }] + * ... + * ``` + * @type {Boolean} + * @default false + */ + allowHtml: false, - if (caseSensitive) { - valueIndex = currentItem.indexOf(value); - } else { - valueIndex = currentItem.toLowerCase().indexOf(value.toLowerCase()); - } + /** + * If typed `true` then virtual rendering mechanism for handsontable will be disabled. + * + * @type {Boolean} + */ + renderAllRows: void 0, - if (valueIndex !== -1) { - charsLeft = currentItem.length - valueIndex - valueLength; + /** + * Prevents table to overlap outside the parent element. If `'horizontal'` option is chosen then table will appear horizontal + * scrollbar in case where parent's width is narrower then table's width. + * + * Possible values: + * * `false` - Disables functionality (Default option). + * * `horizontal` - Prevents horizontal overflow table. + * * `vertical` - Prevents vertical overflow table (Not implemented yet). + * + * @since 0.20.3 + * @example + * ```js + * ... + * preventOverflow: 'horizontal' + * ... + * ``` + * + * @type {String|Boolean} + */ + preventOverflow: false, - choicesRelevance.push({ - baseIndex: i, - index: valueIndex, - charsLeft: charsLeft, - value: currentItem - }); - } - } + /** + * @description + * Plugin allowing binding the table rows with their headers. + * If the plugin is enabled, the table row headers will "stick" to the rows, when they are hidden/moved. Basically, if at the initialization + * row 0 has a header titled "A", it will have it no matter what you do with the table. + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean|String} + * @example + * + * ```js + * ... + * var hot = new Handsontable(document.getElementById('example'), { + * date: getData(), + * bindRowsWithHeaders: true + * }); + * ... + * ``` + * + */ + bindRowsWithHeaders: void 0, - choicesRelevance.sort(function (a, b) { + /** + * @description + * The CollapsibleColumns plugin allows collapsing of columns, covered by a header with the `colspan` property defined. + * + * Clicking the "collapse/expand" button collapses (or expands) all "child" headers except the first one. + * + * Setting the `collapsibleColumns` property to `true` will display a "collapse/expand" button in every header with a defined + * `colspan` property. + * + * To limit this functionality to a smaller group of headers, define the `collapsibleColumns` property as an array of objects, as in + * the example below. + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean|Array} + * @example + * ```js + * ... + * collapsibleColumns: [ + * {row: -4, col: 1, collapsible: true}, + * {row: -3, col: 5, collapsible: true} + * ] + * ... + * // or + * ... + * collapsibleColumns: true + * ... + * ``` + */ + collapsibleColumns: void 0, - if (b.index === -1) { - return -1; - } - if (a.index === -1) { - return 1; - } + /** + * @description + * Allows making pre-defined calculations on the cell values and display the results within Handsontable. + * See the demo for more information. + * + * @pro + * @since 1.0.0-beta1 + * @type {Object} + */ + columnSummary: void 0, - if (a.index < b.index) { - return -1; - } else if (b.index < a.index) { - return 1; - } else if (a.index === b.index) { - if (a.charsLeft < b.charsLeft) { - return -1; - } else if (a.charsLeft > b.charsLeft) { - return 1; - } - } + /** + * This plugin allows adding a configurable dropdown menu to the table's column headers. + * The dropdown menu acts like the Context Menu, but is triggered by clicking the button in the header. + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean|Object|Array} + */ + dropdownMenu: void 0, - return 0; - }); + /** + * The filters plugin. + * It allows filtering the table data either by the built-in component or with the API. + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean} + */ + filters: void 0, - for (i = 0, choicesCount = choicesRelevance.length; i < choicesCount; i++) { - result.push(choicesRelevance[i].baseIndex); - } + /** + * It allows Handsontable to process formula expressions defined in the provided data. + * + * @pro + * @since 1.7.0 + * @type {Boolean} + */ + formulas: void 0, - return result; -}; + /** + * @description + * GanttChart plugin enables a possibility to create a Gantt chart using a Handsontable instance. + * In this case, the whole table becomes read-only. + * + * @pro + * @since 1.0.0-beta1 + * @type {Object} + */ + ganttChart: void 0, -AutocompleteEditor.prototype.getDropdownHeight = function () { - var firstRowHeight = this.htEditor.getInstance().getRowHeight(0) || 23; - var visibleRows = this.cellProperties.visibleRows; + /** + * @description + * Allows adding a tooltip to the table headers. + * + * Available options: + * * the `rows` property defines if tooltips should be added to row headers, + * * the `columns` property defines if tooltips should be added to column headers, + * * the `onlyTrimmed` property defines if tooltips should be added only to headers, which content is trimmed by the header itself (the content being wider then the header). + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean|Object} + */ + headerTooltips: void 0, - return this.strippedChoices.length >= visibleRows ? visibleRows * firstRowHeight : this.strippedChoices.length * firstRowHeight + 8; -}; + /** + * Plugin allowing hiding of certain columns. + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean|Object} + */ + hiddenColumns: void 0, -AutocompleteEditor.prototype.stripValueIfNeeded = function (value) { - return this.stripValuesIfNeeded([value])[0]; -}; + /** + * @description + * Plugin allowing hiding of certain rows. + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean|Object} + */ + hiddenRows: void 0, -AutocompleteEditor.prototype.stripValuesIfNeeded = function (values) { - var allowHtml = this.cellProperties.allowHtml; + /** + * @description + * Allows creating a nested header structure, using the HTML's colspan attribute. + * + * @pro + * @since 1.0.0-beta1 + * @type {Array} + */ + nestedHeaders: void 0, + /** + * @description + * Plugin allowing hiding of certain rows. + * + * @pro + * @since 1.0.0-beta1 + * @type {Boolean|Array} + */ + trimRows: void 0, - var stringifiedValues = (0, _array.arrayMap)(values, function (value) { - return (0, _mixed.stringify)(value); - }); - var strippedValues = (0, _array.arrayMap)(stringifiedValues, function (value) { - return allowHtml ? value : (0, _string.stripTags)(value); - }); + /** + * @description + * Allows setting a custom width of the row headers. You can provide a number or an array of widths, if many row header levels are defined. + * + * @since 0.22.0 + * @type {Number|Array} + */ + rowHeaderWidth: void 0, - return strippedValues; -}; + /** + * @description + * Allows setting a custom height of the column headers. You can provide a number or an array of heights, if many column header levels are defined. + * + * @since 0.22.0 + * @type {Number|Array} + */ + columnHeaderHeight: void 0, -AutocompleteEditor.prototype.allowKeyEventPropagation = function (keyCode) { - var selected = { row: this.htEditor.getSelectedRange() ? this.htEditor.getSelectedRange().from.row : -1 }; - var allowed = false; + /** + * @description + * Enabling this plugin switches table into one-way data binding where changes are applied into data source (from outside table) + * will be automatically reflected in the table. + * + * For every data change [afterChangesObserved](Hooks.html#event:afterChangesObserved) hook will be fired. + * + * @type {Boolean} + * @default false + */ + observeChanges: void 0, - if (keyCode === _unicode.KEY_CODES.ARROW_DOWN && selected.row > 0 && selected.row < this.htEditor.countRows() - 1) { - allowed = true; - } - if (keyCode === _unicode.KEY_CODES.ARROW_UP && selected.row > -1) { - allowed = true; - } + /** + * @description + * When passed to the `column` property, allows specifying a custom sorting function for the desired column. + * + * @since 0.24.0 + * @type {Function} + * @example + * ```js + * columns: [ + * { + * sortFunction: function(sortOrder) { + * return function(a, b) { + * // sorting function body. + * // + * // Function parameters: + * // sortOrder: If true, the order is ascending, if false - descending. undefined = original order + * // a, b: Two compared elements. These are 2-element arrays, with the first element being the row index, the second - cell value. + * } + * } + * } + * ] + * ``` + */ + sortFunction: void 0, - return allowed; -}; + /** + * If defined as 'true', the Autocomplete's suggestion list would be sorted by relevance (the closer to the left the match is, the higher the suggestion). + * + * Option desired for cells of the `'autocomplete'` type. + * + * @type {Boolean} + * @default true + */ + sortByRelevance: true, -AutocompleteEditor.prototype.discardEditor = function (result) { - _handsontableEditor2.default.prototype.discardEditor.apply(this, arguments); + /** + * If defined as 'true', when the user types into the input area the Autocomplete's suggestion list is updated to only + * include those choices starting with what has been typed; if defined as 'false' all suggestions remain shown, with + * those matching what has been typed marked in bold. + * + * @type {Boolean} + * @default true + */ + filter: true, - this.instance.view.render(); + /** + * If defined as 'true', filtering in the Autocomplete Editor will be case-sensitive. + * + * @type {Boolean} + * @default: false + */ + filteringCaseSensitive: false }; -exports.default = AutocompleteEditor; +exports.default = DefaultSettings; /***/ }), -/* 150 */ +/* 175 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41205,201 +41810,233 @@ exports.default = AutocompleteEditor; exports.__esModule = true; -var _unicode = __webpack_require__(16); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _object = __webpack_require__(1); -var _element = __webpack_require__(0); - -var _event = __webpack_require__(7); - -var _textEditor = __webpack_require__(43); +var _number = __webpack_require__(6); -var _textEditor2 = _interopRequireDefault(_textEditor); +var _mixed = __webpack_require__(22); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } -var HandsontableEditor = _textEditor2.default.prototype.extend(); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * @private - * @editor HandsontableEditor - * @class HandsontableEditor - * @dependencies TextEditor + * @class SamplesGenerator + * @util */ -HandsontableEditor.prototype.createElements = function () { - _textEditor2.default.prototype.createElements.apply(this, arguments); +var SamplesGenerator = function () { + _createClass(SamplesGenerator, null, [{ + key: 'SAMPLE_COUNT', - var DIV = document.createElement('DIV'); - DIV.className = 'handsontableEditor'; - this.TEXTAREA_PARENT.appendChild(DIV); + /** + * Number of samples to take of each value length. + * + * @type {Number} + */ + get: function get() { + return 3; + } + }]); - this.htContainer = DIV; - this.assignHooks(); -}; + function SamplesGenerator(dataFactory) { + _classCallCheck(this, SamplesGenerator); -HandsontableEditor.prototype.prepare = function (td, row, col, prop, value, cellProperties) { - _textEditor2.default.prototype.prepare.apply(this, arguments); + /** + * Samples prepared for calculations. + * + * @type {Map} + * @default {null} + */ + this.samples = null; + /** + * Function which give the data to collect samples. + * + * @type {Function} + */ + this.dataFactory = dataFactory; + /** + * Custom number of samples to take of each value length. + * + * @type {Number} + * @default {null} + */ + this.customSampleCount = null; + /** + * `true` if duplicate samples collection should be allowed, `false` otherwise. + * + * @type {Boolean} + * @default {false} + */ + this.allowDuplicates = false; + } - var parent = this; - var options = { - startRows: 0, - startCols: 0, - minRows: 0, - minCols: 0, - className: 'listbox', - copyPaste: false, - autoColumnSize: false, - autoRowSize: false, - readOnly: true, - fillHandle: false, - afterOnCellMouseDown: function afterOnCellMouseDown(_, coords) { - var value = this.getSourceData(coords.row, coords.col); + /** + * Get the sample count for this instance. + * + * @returns {Number} + */ - // if the value is undefined then it means we don't want to set the value - if (value !== void 0) { - parent.setValue(value); + + _createClass(SamplesGenerator, [{ + key: 'getSampleCount', + value: function getSampleCount() { + if (this.customSampleCount) { + return this.customSampleCount; } - parent.instance.destroyEditor(); + return SamplesGenerator.SAMPLE_COUNT; } - }; - - if (this.cellProperties.handsontable) { - (0, _object.extend)(options, cellProperties.handsontable); - } - this.htOptions = options; -}; + }, { + key: 'setSampleCount', -var onBeforeKeyDown = function onBeforeKeyDown(event) { - if ((0, _event.isImmediatePropagationStopped)(event)) { - return; - } - var editor = this.getActiveEditor(); - var innerHOT = editor.htEditor.getInstance(); + /** + * Set the sample count. + * + * @param {Number} sampleCount Number of samples to be collected. + */ + value: function setSampleCount(sampleCount) { + this.customSampleCount = sampleCount; + } - var rowToSelect; - var selectedRow; + /** + * Set if the generator should accept duplicate values. + * + * @param {Boolean} allowDuplicates `true` to allow duplicate values. + */ - if (event.keyCode == _unicode.KEY_CODES.ARROW_DOWN) { - if (!innerHOT.getSelected() && !innerHOT.flipped) { - rowToSelect = 0; - } else if (innerHOT.getSelected()) { - if (innerHOT.flipped) { - rowToSelect = innerHOT.getSelected()[0] + 1; - } else if (!innerHOT.flipped) { - selectedRow = innerHOT.getSelected()[0]; - var lastRow = innerHOT.countRows() - 1; - rowToSelect = Math.min(lastRow, selectedRow + 1); - } - } - } else if (event.keyCode == _unicode.KEY_CODES.ARROW_UP) { - if (!innerHOT.getSelected() && innerHOT.flipped) { - rowToSelect = innerHOT.countRows() - 1; - } else if (innerHOT.getSelected()) { - if (innerHOT.flipped) { - selectedRow = innerHOT.getSelected()[0]; - rowToSelect = Math.max(0, selectedRow - 1); - } else { - selectedRow = innerHOT.getSelected()[0]; - rowToSelect = selectedRow - 1; - } + }, { + key: 'setAllowDuplicates', + value: function setAllowDuplicates(allowDuplicates) { + this.allowDuplicates = allowDuplicates; } - } - if (rowToSelect !== void 0) { - if (rowToSelect < 0 || innerHOT.flipped && rowToSelect > innerHOT.countRows() - 1) { - innerHOT.deselectCell(); - } else { - innerHOT.selectCell(rowToSelect, 0); + /** + * Generate samples for row. You can control which area should be sampled by passing `rowRange` object and `colRange` object. + * + * @param {Object|Number} rowRange + * @param {Object} colRange + * @returns {Object} + */ + + }, { + key: 'generateRowSamples', + value: function generateRowSamples(rowRange, colRange) { + return this.generateSamples('row', colRange, rowRange); } - if (innerHOT.getData().length) { - event.preventDefault(); - (0, _event.stopImmediatePropagation)(event); - editor.instance.listen(); - editor.TEXTAREA.focus(); + /** + * Generate samples for column. You can control which area should be sampled by passing `colRange` object and `rowRange` object. + * + * @param {Object} colRange Column index. + * @param {Object} rowRange Column index. + * @returns {Object} + */ + + }, { + key: 'generateColumnSamples', + value: function generateColumnSamples(colRange, rowRange) { + return this.generateSamples('col', rowRange, colRange); } - } -}; -HandsontableEditor.prototype.open = function () { - this.instance.addHook('beforeKeyDown', onBeforeKeyDown); + /** + * Generate collection of samples. + * + * @param {String} type Type to generate. Can be `col` or `row`. + * @param {Object} range + * @param {Object|Number} specifierRange + * @returns {Map} + */ - _textEditor2.default.prototype.open.apply(this, arguments); + }, { + key: 'generateSamples', + value: function generateSamples(type, range, specifierRange) { + var _this = this; - if (this.htEditor) { - this.htEditor.destroy(); - } - // Construct and initialise a new Handsontable - this.htEditor = new this.instance.constructor(this.htContainer, this.htOptions); - this.htEditor.init(); + var samples = new Map(); - if (this.cellProperties.strict) { - this.htEditor.selectCell(0, 0); - this.TEXTAREA.style.visibility = 'hidden'; - } else { - this.htEditor.deselectCell(); - this.TEXTAREA.style.visibility = 'visible'; - } + if (typeof specifierRange === 'number') { + specifierRange = { from: specifierRange, to: specifierRange }; + } + (0, _number.rangeEach)(specifierRange.from, specifierRange.to, function (index) { + var sample = _this.generateSample(type, range, index); - (0, _element.setCaretPosition)(this.TEXTAREA, 0, this.TEXTAREA.value.length); -}; + samples.set(index, sample); + }); -HandsontableEditor.prototype.close = function () { - this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); - this.instance.listen(); + return samples; + } - _textEditor2.default.prototype.close.apply(this, arguments); -}; + /** + * Generate sample for specified type (`row` or `col`). + * + * @param {String} type Samples type `row` or `col`. + * @param {Object} range + * @param {Number} specifierValue + * @returns {Map} + */ -HandsontableEditor.prototype.focus = function () { - this.instance.listen(); - _textEditor2.default.prototype.focus.apply(this, arguments); -}; + }, { + key: 'generateSample', + value: function generateSample(type, range, specifierValue) { + var _this2 = this; -HandsontableEditor.prototype.beginEditing = function (initialValue) { - var onBeginEditing = this.instance.getSettings().onBeginEditing; + var samples = new Map(); + var sampledValues = []; + var length = void 0; - if (onBeginEditing && onBeginEditing() === false) { - return; - } - _textEditor2.default.prototype.beginEditing.apply(this, arguments); -}; + (0, _number.rangeEach)(range.from, range.to, function (index) { + var value = void 0; -HandsontableEditor.prototype.finishEditing = function (isCancelled, ctrlDown) { - if (this.htEditor && this.htEditor.isListening()) { - // if focus is still in the HOT editor + if (type === 'row') { + value = _this2.dataFactory(specifierValue, index); + } else if (type === 'col') { + value = _this2.dataFactory(index, specifierValue); + } else { + throw new Error('Unsupported sample type'); + } - this.instance.listen(); // return the focus to the parent HOT instance - } + if ((0, _object.isObject)(value)) { + length = Object.keys(value).length; + } else if (Array.isArray(value)) { + length = value.length; + } else { + length = (0, _mixed.stringify)(value).length; + } - if (this.htEditor && this.htEditor.getSelected()) { - var value = this.htEditor.getInstance().getValue(); + if (!samples.has(length)) { + samples.set(length, { + needed: _this2.getSampleCount(), + strings: [] + }); + } + var sample = samples.get(length); - if (value !== void 0) { - // if the value is undefined then it means we don't want to set the value - this.setValue(value); - } - } + if (sample.needed) { + var duplicate = sampledValues.indexOf(value) > -1; - return _textEditor2.default.prototype.finishEditing.apply(this, arguments); -}; + if (!duplicate || _this2.allowDuplicates) { + var computedKey = type === 'row' ? 'col' : 'row'; -HandsontableEditor.prototype.assignHooks = function () { - var _this = this; + sample.strings.push(_defineProperty({ value: value }, computedKey, index)); + sampledValues.push(value); + sample.needed--; + } + } + }); - this.instance.addHook('afterDestroy', function () { - if (_this.htEditor) { - _this.htEditor.destroy(); + return samples; } - }); -}; + }]); -exports.default = HandsontableEditor; + return SamplesGenerator; +}(); + +exports.default = SamplesGenerator; /***/ }), -/* 151 */ +/* 176 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41582,7 +42219,7 @@ var arrayMapper = { exports.default = arrayMapper; /***/ }), -/* 152 */ +/* 177 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41802,7 +42439,7 @@ var BaseUI = function () { exports.default = BaseUI; /***/ }), -/* 153 */ +/* 178 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41924,1965 +42561,1573 @@ var BaseUI = function () { }, { key: 'setPosition', value: function setPosition(top, left) { - if (top) { + if (top !== void 0) { this._element.style.top = top + UNIT; } - if (left) { - this._element.style.left = left + UNIT; - } - } - - /** - * Getter for the element position. - * - * @returns {Object} Object contains left and top position of the element. - */ - - }, { - key: 'getPosition', - value: function getPosition() { - return { - top: this._element.style.top ? parseInt(this._element.style.top, 10) : 0, - left: this._element.style.left ? parseInt(this._element.style.left, 10) : 0 - }; - } - - /** - * Setter for the element size. - * - * @param {Number} width New width of the element. - * @param {Number} height New height of the element. - */ - - }, { - key: 'setSize', - value: function setSize(width, height) { - if (width) { - this._element.style.width = width + UNIT; - } - if (height) { - this._element.style.height = height + UNIT; - } - } - - /** - * Getter for the element position. - * - * @returns {Object} Object contains height and width of the element. - */ - - }, { - key: 'getSize', - value: function getSize() { - return { - width: this._element.style.width ? parseInt(this._element.style.width, 10) : 0, - height: this._element.style.height ? parseInt(this._element.style.height, 10) : 0 - }; - } - - /** - * Setter for the element offset. Offset means marginTop and marginLeft of the element. - * - * @param {Number} top New margin top of the element. - * @param {Number} left New margin left of the element. - */ - - }, { - key: 'setOffset', - value: function setOffset(top, left) { - if (top) { - this._element.style.marginTop = top + UNIT; - } - if (left) { - this._element.style.marginLeft = left + UNIT; - } - } - - /** - * Getter for the element offset. - * - * @returns {Object} Object contains top and left offset of the element. - */ - - }, { - key: 'getOffset', - value: function getOffset() { - return { - top: this._element.style.marginTop ? parseInt(this._element.style.marginTop, 10) : 0, - left: this._element.style.marginLeft ? parseInt(this._element.style.marginLeft, 10) : 0 - }; - } - }]); - - return BaseUI; -}(); - -exports.default = BaseUI; - -/***/ }), -/* 154 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.RecordTranslator = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -exports.registerIdentity = registerIdentity; -exports.getTranslator = getTranslator; - -var _core = __webpack_require__(63); - -var _core2 = _interopRequireDefault(_core); - -var _object = __webpack_require__(1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * @class RecordTranslator - * @util - */ -var RecordTranslator = function () { - function RecordTranslator(hot) { - _classCallCheck(this, RecordTranslator); - - this.hot = hot; - } - - /** - * Translate physical row index into visual. - * - * @param {Number} row Physical row index. - * @returns {Number} Returns visual row index. - */ - - - _createClass(RecordTranslator, [{ - key: 'toVisualRow', - value: function toVisualRow(row) { - return this.hot.runHooks('unmodifyRow', row); + if (left !== void 0) { + this._element.style.left = left + UNIT; + } } /** - * Translate physical column index into visual. + * Getter for the element position. * - * @param {Number} column Physical column index. - * @returns {Number} Returns visual column index. + * @returns {Object} Object contains left and top position of the element. */ }, { - key: 'toVisualColumn', - value: function toVisualColumn(column) { - return this.hot.runHooks('unmodifyCol', column); + key: 'getPosition', + value: function getPosition() { + return { + top: this._element.style.top ? parseInt(this._element.style.top, 10) : 0, + left: this._element.style.left ? parseInt(this._element.style.left, 10) : 0 + }; } /** - * Translate physical coordinates into visual. Can be passed as separate 2 arguments (row, column) or as an object in first - * argument with `row` and `column` keys. + * Setter for the element size. * - * @param {Number|Object} row Physical coordinates or row index. - * @param {Number} [column] Physical column index. - * @returns {Object|Array} Returns an object with visual records or an array if coordinates passed as separate arguments. + * @param {Number} width New width of the element. + * @param {Number} height New height of the element. */ }, { - key: 'toVisual', - value: function toVisual(row, column) { - var result = void 0; - - if ((0, _object.isObject)(row)) { - result = { - row: this.toVisualRow(row.row), - column: this.toVisualColumn(row.column) - }; - } else { - result = [this.toVisualRow(row), this.toVisualColumn(column)]; + key: 'setSize', + value: function setSize(width, height) { + if (width) { + this._element.style.width = width + UNIT; + } + if (height) { + this._element.style.height = height + UNIT; } - - return result; } /** - * Translate visual row index into physical. + * Getter for the element position. * - * @param {Number} row Visual row index. - * @returns {Number} Returns physical row index. + * @returns {Object} Object contains height and width of the element. */ }, { - key: 'toPhysicalRow', - value: function toPhysicalRow(row) { - return this.hot.runHooks('modifyRow', row); + key: 'getSize', + value: function getSize() { + return { + width: this._element.style.width ? parseInt(this._element.style.width, 10) : 0, + height: this._element.style.height ? parseInt(this._element.style.height, 10) : 0 + }; } /** - * Translate visual column index into physical. + * Setter for the element offset. Offset means marginTop and marginLeft of the element. * - * @param {Number} column Visual column index. - * @returns {Number} Returns physical column index. + * @param {Number} top New margin top of the element. + * @param {Number} left New margin left of the element. */ }, { - key: 'toPhysicalColumn', - value: function toPhysicalColumn(column) { - return this.hot.runHooks('modifyCol', column); + key: 'setOffset', + value: function setOffset(top, left) { + if (top) { + this._element.style.marginTop = top + UNIT; + } + if (left) { + this._element.style.marginLeft = left + UNIT; + } } /** - * Translate visual coordinates into physical. Can be passed as separate 2 arguments (row, column) or as an object in first - * argument with `row` and `column` keys. + * Getter for the element offset. * - * @param {Number|Object} row Visual coordinates or row index. - * @param {Number} [column] Visual column index. - * @returns {Object|Array} Returns an object with physical records or an array if coordinates passed as separate arguments. + * @returns {Object} Object contains top and left offset of the element. */ }, { - key: 'toPhysical', - value: function toPhysical(row, column) { - var result = void 0; - - if ((0, _object.isObject)(row)) { - result = { - row: this.toPhysicalRow(row.row), - column: this.toPhysicalColumn(row.column) - }; - } else { - result = [this.toPhysicalRow(row), this.toPhysicalColumn(column)]; - } - - return result; + key: 'getOffset', + value: function getOffset() { + return { + top: this._element.style.marginTop ? parseInt(this._element.style.marginTop, 10) : 0, + left: this._element.style.marginLeft ? parseInt(this._element.style.marginLeft, 10) : 0 + }; } }]); - return RecordTranslator; + return BaseUI; }(); -exports.RecordTranslator = RecordTranslator; - - -var identities = new WeakMap(); -var translatorSingletons = new WeakMap(); - -function registerIdentity(identity, hot) { - identities.set(identity, hot); -} - -function getTranslator(identity) { - var singleton = void 0; - - if (!(identity instanceof _core2.default)) { - if (!identities.has(identity)) { - throw Error('Record translator was not registered for this object identity'); - } - identity = identities.get(identity); - } - if (translatorSingletons.has(identity)) { - singleton = translatorSingletons.get(identity); - } else { - singleton = new RecordTranslator(identity); - translatorSingletons.set(identity, singleton); - } - - return singleton; -} +exports.default = BaseUI; /***/ }), -/* 155 */ +/* 179 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.__esModule = true; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _object = __webpack_require__(1); - -var _number = __webpack_require__(6); - -var _mixed = __webpack_require__(20); - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; -/** - * @class SamplesGenerator - * @util +/*! + * https://github.com/Starcounter-Jack/JSON-Patch + * json-patch-duplex.js version: 0.5.7 + * (c) 2013 Joachim Wester + * MIT license */ -var SamplesGenerator = function () { - _createClass(SamplesGenerator, null, [{ - key: 'SAMPLE_COUNT', - - /** - * Number of samples to take of each value length. - * - * @type {Number} +var __extends = undefined && undefined.__extends || function (d, b) { + for (var p in b) { + if (b.hasOwnProperty(p)) d[p] = b[p]; + }function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var OriginalError = Error; +var jsonpatch; +(function (jsonpatch) { + var _objectKeys = function _objectKeys(obj) { + if (_isArray(obj)) { + var keys = new Array(obj.length); + for (var k = 0; k < keys.length; k++) { + keys[k] = "" + k; + } + return keys; + } + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + keys.push(i); + } + } + return keys; + }; + function _equals(a, b) { + switch (typeof a === 'undefined' ? 'undefined' : _typeof(a)) { + case 'undefined': //backward compatibility, but really I think we should return false + case 'boolean': + case 'string': + case 'number': + return a === b; + case 'object': + if (a === null) return b === null; + if (_isArray(a)) { + if (!_isArray(b) || a.length !== b.length) return false; + for (var i = 0, l = a.length; i < l; i++) { + if (!_equals(a[i], b[i])) return false; + }return true; + } + var bKeys = _objectKeys(b); + var bLength = bKeys.length; + if (_objectKeys(a).length !== bLength) return false; + for (var i = 0; i < bLength; i++) { + if (!_equals(a[i], b[i])) return false; + }return true; + default: + return false; + } + } + /* We use a Javascript hash to store each + function. Each hash entry (property) uses + the operation identifiers specified in rfc6902. + In this way, we can map each patch operation + to its dedicated function in efficient way. */ - get: function get() { - return 3; + /* The operations applicable to an object */ + var objOps = { + add: function add(obj, key) { + obj[key] = this.value; + return true; + }, + remove: function remove(obj, key) { + delete obj[key]; + return true; + }, + replace: function replace(obj, key) { + obj[key] = this.value; + return true; + }, + move: function move(obj, key, tree) { + var temp = { op: "_get", path: this.from }; + apply(tree, [temp]); + apply(tree, [{ op: "remove", path: this.from }]); + apply(tree, [{ op: "add", path: this.path, value: temp.value }]); + return true; + }, + copy: function copy(obj, key, tree) { + var temp = { op: "_get", path: this.from }; + apply(tree, [temp]); + apply(tree, [{ op: "add", path: this.path, value: temp.value }]); + return true; + }, + test: function test(obj, key) { + return _equals(obj[key], this.value); + }, + _get: function _get(obj, key) { + this.value = obj[key]; + } + }; + /* The operations applicable to an array. Many are the same as for the object */ + var arrOps = { + add: function add(arr, i) { + arr.splice(i, 0, this.value); + return true; + }, + remove: function remove(arr, i) { + arr.splice(i, 1); + return true; + }, + replace: function replace(arr, i) { + arr[i] = this.value; + return true; + }, + move: objOps.move, + copy: objOps.copy, + test: objOps.test, + _get: objOps._get + }; + /* The operations applicable to object root. Many are the same as for the object */ + var rootOps = { + add: function add(obj) { + rootOps.remove.call(this, obj); + for (var key in this.value) { + if (this.value.hasOwnProperty(key)) { + obj[key] = this.value[key]; + } + } + return true; + }, + remove: function remove(obj) { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + objOps.remove.call(this, obj, key); + } + } + return true; + }, + replace: function replace(obj) { + apply(obj, [{ op: "remove", path: this.path }]); + apply(obj, [{ op: "add", path: this.path, value: this.value }]); + return true; + }, + move: objOps.move, + copy: objOps.copy, + test: function test(obj) { + return JSON.stringify(obj) === JSON.stringify(this.value); + }, + _get: function _get(obj) { + this.value = obj; + } + }; + var observeOps = { + add: function add(patches, path) { + var patch = { + op: "add", + path: path + escapePathComponent(this.name), + value: this.object[this.name] }; + patches.push(patch); + }, + 'delete': function _delete(patches, path) { + var patch = { + op: "remove", + path: path + escapePathComponent(this.name) + }; + patches.push(patch); + }, + update: function update(patches, path) { + var patch = { + op: "replace", + path: path + escapePathComponent(this.name), + value: this.object[this.name] + }; + patches.push(patch); + } + }; + function escapePathComponent(str) { + if (str.indexOf('/') === -1 && str.indexOf('~') === -1) return str; + return str.replace(/~/g, '~0').replace(/\//g, '~1'); + } + function _getPathRecursive(root, obj) { + var found; + for (var key in root) { + if (root.hasOwnProperty(key)) { + if (root[key] === obj) { + return escapePathComponent(key) + '/'; + } else if (_typeof(root[key]) === 'object') { + found = _getPathRecursive(root[key], obj); + if (found != '') { + return escapePathComponent(key) + '/' + found; + } + } + } + } + return ''; + } + function getPath(root, obj) { + if (root === obj) { + return '/'; + } + var path = _getPathRecursive(root, obj); + if (path === '') { + throw new OriginalError("Object not found in root"); + } + return '/' + path; + } + var beforeDict = []; + var Mirror = function () { + function Mirror(obj) { + this.observers = []; + this.obj = obj; + } + return Mirror; + }(); + var ObserverInfo = function () { + function ObserverInfo(callback, observer) { + this.callback = callback; + this.observer = observer; + } + return ObserverInfo; + }(); + function getMirror(obj) { + for (var i = 0, ilen = beforeDict.length; i < ilen; i++) { + if (beforeDict[i].obj === obj) { + return beforeDict[i]; + } + } + } + function getObserverFromMirror(mirror, callback) { + for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) { + if (mirror.observers[j].callback === callback) { + return mirror.observers[j].observer; + } + } + } + function removeObserverFromMirror(mirror, observer) { + for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) { + if (mirror.observers[j].observer === observer) { + mirror.observers.splice(j, 1); + return; + } + } + } + function unobserve(root, observer) { + observer.unobserve(); + } + jsonpatch.unobserve = unobserve; + function deepClone(obj) { + if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === "object") { + return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5 + } else { + return obj; //no need to clone primitives + } + } + function observe(obj, callback) { + var patches = []; + var root = obj; + var observer; + var mirror = getMirror(obj); + if (!mirror) { + mirror = new Mirror(obj); + beforeDict.push(mirror); + } else { + observer = getObserverFromMirror(mirror, callback); + } + if (observer) { + return observer; + } + observer = {}; + mirror.value = deepClone(obj); + if (callback) { + observer.callback = callback; + observer.next = null; + var intervals = this.intervals || [100, 1000, 10000, 60000]; + if (intervals.push === void 0) { + throw new OriginalError("jsonpatch.intervals must be an array"); + } + var currentInterval = 0; + var dirtyCheck = function dirtyCheck() { + generate(observer); + }; + var fastCheck = function fastCheck() { + clearTimeout(observer.next); + observer.next = setTimeout(function () { + dirtyCheck(); + currentInterval = 0; + observer.next = setTimeout(slowCheck, intervals[currentInterval++]); + }, 0); + }; + var slowCheck = function slowCheck() { + dirtyCheck(); + if (currentInterval == intervals.length) currentInterval = intervals.length - 1; + observer.next = setTimeout(slowCheck, intervals[currentInterval++]); + }; + if (typeof window !== 'undefined') { + if (window.addEventListener) { + window.addEventListener('mousedown', fastCheck); + window.addEventListener('mouseup', fastCheck); + window.addEventListener('keydown', fastCheck); + } else { + document.documentElement.attachEvent('onmousedown', fastCheck); + document.documentElement.attachEvent('onmouseup', fastCheck); + document.documentElement.attachEvent('onkeydown', fastCheck); + } + } + observer.next = setTimeout(slowCheck, intervals[currentInterval++]); + } + observer.patches = patches; + observer.object = obj; + observer.unobserve = function () { + generate(observer); + clearTimeout(observer.next); + removeObserverFromMirror(mirror, observer); + if (typeof window !== 'undefined') { + if (window.removeEventListener) { + window.removeEventListener('mousedown', fastCheck); + window.removeEventListener('mouseup', fastCheck); + window.removeEventListener('keydown', fastCheck); + } else { + document.documentElement.detachEvent('onmousedown', fastCheck); + document.documentElement.detachEvent('onmouseup', fastCheck); + document.documentElement.detachEvent('onkeydown', fastCheck); + } + } + }; + mirror.observers.push(new ObserverInfo(callback, observer)); + return observer; + } + jsonpatch.observe = observe; + function generate(observer) { + var mirror; + for (var i = 0, ilen = beforeDict.length; i < ilen; i++) { + if (beforeDict[i].obj === observer.object) { + mirror = beforeDict[i]; + break; + } + } + _generate(mirror.value, observer.object, observer.patches, ""); + if (observer.patches.length) { + apply(mirror.value, observer.patches); + } + var temp = observer.patches; + if (temp.length > 0) { + observer.patches = []; + if (observer.callback) { + observer.callback(temp); + } + } + return temp; + } + jsonpatch.generate = generate; + // Dirty check if obj is different from mirror, generate patches and update mirror + function _generate(mirror, obj, patches, path) { + var newKeys = _objectKeys(obj); + var oldKeys = _objectKeys(mirror); + var changed = false; + var deleted = false; + //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)" + for (var t = oldKeys.length - 1; t >= 0; t--) { + var key = oldKeys[t]; + var oldVal = mirror[key]; + if (obj.hasOwnProperty(key)) { + var newVal = obj[key]; + if ((typeof oldVal === 'undefined' ? 'undefined' : _typeof(oldVal)) == "object" && oldVal != null && (typeof newVal === 'undefined' ? 'undefined' : _typeof(newVal)) == "object" && newVal != null) { + _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key)); + } else { + if (oldVal != newVal) { + changed = true; + patches.push({ op: "replace", path: path + "/" + escapePathComponent(key), value: deepClone(newVal) }); + } + } + } else { + patches.push({ op: "remove", path: path + "/" + escapePathComponent(key) }); + deleted = true; // property has been deleted + } + } + if (!deleted && newKeys.length == oldKeys.length) { + return; + } + for (var t = 0; t < newKeys.length; t++) { + var key = newKeys[t]; + if (!mirror.hasOwnProperty(key)) { + patches.push({ op: "add", path: path + "/" + escapePathComponent(key), value: deepClone(obj[key]) }); + } + } } - }]); - - function SamplesGenerator(dataFactory) { - _classCallCheck(this, SamplesGenerator); - - /** - * Samples prepared for calculations. - * - * @type {Map} - * @default {null} - */ - this.samples = null; - /** - * Function which give the data to collect samples. - * - * @type {Function} - */ - this.dataFactory = dataFactory; - /** - * Custom number of samples to take of each value length. - * - * @type {Number} - * @default {null} - */ - this.customSampleCount = null; - /** - * `true` if duplicate samples collection should be allowed, `false` otherwise. - * - * @type {Boolean} - * @default {false} - */ - this.allowDuplicates = false; - } - - /** - * Get the sample count for this instance. - * - * @returns {Number} - */ - - - _createClass(SamplesGenerator, [{ - key: 'getSampleCount', - value: function getSampleCount() { - if (this.customSampleCount) { - return this.customSampleCount; - } - return SamplesGenerator.SAMPLE_COUNT; + var _isArray; + if (Array.isArray) { + _isArray = Array.isArray; + } else { + _isArray = function _isArray(obj) { + return obj.push && typeof obj.length === 'number'; + }; } - }, { - key: 'setSampleCount', - - - /** - * Set the sample count. - * - * @param {Number} sampleCount Number of samples to be collected. - */ - value: function setSampleCount(sampleCount) { - this.customSampleCount = sampleCount; + //3x faster than cached /^\d+$/.test(str) + function isInteger(str) { + var i = 0; + var len = str.length; + var charCode; + while (i < len) { + charCode = str.charCodeAt(i); + if (charCode >= 48 && charCode <= 57) { + i++; + continue; + } + return false; + } + return true; } - - /** - * Set if the generator should accept duplicate values. - * - * @param {Boolean} allowDuplicates `true` to allow duplicate values. - */ - - }, { - key: 'setAllowDuplicates', - value: function setAllowDuplicates(allowDuplicates) { - this.allowDuplicates = allowDuplicates; + /// Apply a json-patch operation on an object tree + function apply(tree, patches, validate) { + var result = false, + p = 0, + plen = patches.length, + patch, + key; + while (p < plen) { + patch = patches[p]; + p++; + // Find the object + var path = patch.path || ""; + var keys = path.split('/'); + var obj = tree; + var t = 1; //skip empty element - http://jsperf.com/to-shift-or-not-to-shift + var len = keys.length; + var existingPathFragment = undefined; + while (true) { + key = keys[t]; + if (validate) { + if (existingPathFragment === undefined) { + if (obj[key] === undefined) { + existingPathFragment = keys.slice(0, t).join('/'); + } else if (t == len - 1) { + existingPathFragment = patch.path; + } + if (existingPathFragment !== undefined) { + this.validator(patch, p - 1, tree, existingPathFragment); + } + } + } + t++; + if (key === undefined) { + if (t >= len) { + result = rootOps[patch.op].call(patch, obj, key, tree); // Apply patch + break; + } + } + if (_isArray(obj)) { + if (key === '-') { + key = obj.length; + } else { + if (validate && !isInteger(key)) { + throw new JsonPatchError("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", p - 1, patch.path, patch); + } + key = parseInt(key, 10); + } + if (t >= len) { + if (validate && patch.op === "add" && key > obj.length) { + throw new JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", p - 1, patch.path, patch); + } + result = arrOps[patch.op].call(patch, obj, key, tree); // Apply patch + break; + } + } else { + if (key && key.indexOf('~') != -1) key = key.replace(/~1/g, '/').replace(/~0/g, '~'); // escape chars + if (t >= len) { + result = objOps[patch.op].call(patch, obj, key, tree); // Apply patch + break; + } + } + obj = obj[key]; + } + } + return result; } - - /** - * Generate samples for row. You can control which area should be sampled by passing `rowRange` object and `colRange` object. - * - * @param {Object|Number} rowRange - * @param {Object} colRange - * @returns {Object} - */ - - }, { - key: 'generateRowSamples', - value: function generateRowSamples(rowRange, colRange) { - return this.generateSamples('row', colRange, rowRange); + jsonpatch.apply = apply; + function compare(tree1, tree2) { + var patches = []; + _generate(tree1, tree2, patches, ''); + return patches; } - + jsonpatch.compare = compare; + var JsonPatchError = function (_super) { + __extends(JsonPatchError, _super); + function JsonPatchError(message, name, index, operation, tree) { + _super.call(this, message); + this.message = message; + this.name = name; + this.index = index; + this.operation = operation; + this.tree = tree; + } + return JsonPatchError; + }(OriginalError); + jsonpatch.JsonPatchError = JsonPatchError; + jsonpatch.Error = JsonPatchError; /** - * Generate samples for column. You can control which area should be sampled by passing `colRange` object and `rowRange` object. - * - * @param {Object} colRange Column index. - * @param {Object} rowRange Column index. - * @returns {Object} + * Recursively checks whether an object has any undefined values inside. */ - - }, { - key: 'generateColumnSamples', - value: function generateColumnSamples(colRange, rowRange) { - return this.generateSamples('col', rowRange, colRange); + function hasUndefined(obj) { + if (obj === undefined) { + return true; + } + if (typeof obj == "array" || (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) == "object") { + for (var i in obj) { + if (hasUndefined(obj[i])) { + return true; + } + } + } + return false; } - /** - * Generate collection of samples. - * - * @param {String} type Type to generate. Can be `col` or `row`. - * @param {Object} range - * @param {Object|Number} specifierRange - * @returns {Map} + * Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error. + * @param {object} operation - operation object (patch) + * @param {number} index - index of operation in the sequence + * @param {object} [tree] - object where the operation is supposed to be applied + * @param {string} [existingPathFragment] - comes along with `tree` */ - - }, { - key: 'generateSamples', - value: function generateSamples(type, range, specifierRange) { - var _this = this; - - var samples = new Map(); - - if (typeof specifierRange === 'number') { - specifierRange = { from: specifierRange, to: specifierRange }; - } - (0, _number.rangeEach)(specifierRange.from, specifierRange.to, function (index) { - var sample = _this.generateSample(type, range, index); - - samples.set(index, sample); - }); - - return samples; + function validator(operation, index, tree, existingPathFragment) { + if ((typeof operation === 'undefined' ? 'undefined' : _typeof(operation)) !== 'object' || operation === null || _isArray(operation)) { + throw new JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, tree); + } else if (!objOps[operation.op]) { + throw new JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, tree); + } else if (typeof operation.path !== 'string') { + throw new JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, tree); + } else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') { + throw new JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, tree); + } else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) { + throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, tree); + } else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && hasUndefined(operation.value)) { + throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', index, operation, tree); + } else if (tree) { + if (operation.op == "add") { + var pathLen = operation.path.split("/").length; + var existingPathLen = existingPathFragment.split("/").length; + if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) { + throw new JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, tree); + } + } else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') { + if (operation.path !== existingPathFragment) { + throw new JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, tree); + } + } else if (operation.op === 'move' || operation.op === 'copy') { + var existingValue = { op: "_get", path: operation.from, value: undefined }; + var error = jsonpatch.validate([existingValue], tree); + if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') { + throw new JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, tree); + } + } + } } - + jsonpatch.validator = validator; /** - * Generate sample for specified type (`row` or `col`). - * - * @param {String} type Samples type `row` or `col`. - * @param {Object} range - * @param {Number} specifierValue - * @returns {Map} + * Validates a sequence of operations. If `tree` parameter is provided, the sequence is additionally validated against the object tree. + * If error is encountered, returns a JsonPatchError object + * @param sequence + * @param tree + * @returns {JsonPatchError|undefined} */ - - }, { - key: 'generateSample', - value: function generateSample(type, range, specifierValue) { - var _this2 = this; - - var samples = new Map(); - var sampledValues = []; - var length = void 0; - - (0, _number.rangeEach)(range.from, range.to, function (index) { - var value = void 0; - - if (type === 'row') { - value = _this2.dataFactory(specifierValue, index); - } else if (type === 'col') { - value = _this2.dataFactory(index, specifierValue); - } else { - throw new Error('Unsupported sample type'); - } - - if ((0, _object.isObject)(value)) { - length = Object.keys(value).length; - } else if (Array.isArray(value)) { - length = value.length; - } else { - length = (0, _mixed.stringify)(value).length; - } - - if (!samples.has(length)) { - samples.set(length, { - needed: _this2.getSampleCount(), - strings: [] - }); - } - var sample = samples.get(length); - - if (sample.needed) { - var duplicate = sampledValues.indexOf(value) > -1; - - if (!duplicate || _this2.allowDuplicates) { - var computedKey = type === 'row' ? 'col' : 'row'; - - sample.strings.push(_defineProperty({ value: value }, computedKey, index)); - sampledValues.push(value); - sample.needed--; - } - } - }); - - return samples; - } - }]); - - return SamplesGenerator; -}(); - -exports.default = SamplesGenerator; - -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { - -// false -> Array#indexOf -// true -> Array#includes -var toIObject = __webpack_require__(23) - , toLength = __webpack_require__(24) - , toIndex = __webpack_require__(59); -module.exports = function(IS_INCLUDES){ - return function($this, el, fromIndex){ - var O = toIObject($this) - , length = toLength(O.length) - , index = toIndex(fromIndex, length) - , value; - // Array#includes uses SameValueZero equality algorithm - if(IS_INCLUDES && el != el)while(length > index){ - value = O[index++]; - if(value != value)return true; - // Array#toIndex ignores holes, Array#includes - not - } else for(;length > index; index++)if(IS_INCLUDES || index in O){ - if(O[index] === el)return IS_INCLUDES || index || 0; - } return !IS_INCLUDES && -1; - }; -}; - -/***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { - -// getting tag from 19.1.3.6 Object.prototype.toString() -var cof = __webpack_require__(38) - , TAG = __webpack_require__(10)('toStringTag') - // ES3 wrong here - , ARG = cof(function(){ return arguments; }()) == 'Arguments'; - -// fallback for IE11 Script Access Denied error -var tryGet = function(it, key){ - try { - return it[key]; - } catch(e){ /* empty */ } -}; - -module.exports = function(it){ - var O, T, B; - return it === undefined ? 'Undefined' : it === null ? 'Null' - // @@toStringTag case - : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T - // builtinTag case - : ARG ? cof(O) - // ES3 arguments fallback - : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; -}; - -/***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var dP = __webpack_require__(19).f - , create = __webpack_require__(79) - , redefineAll = __webpack_require__(58) - , ctx = __webpack_require__(29) - , anInstance = __webpack_require__(51) - , defined = __webpack_require__(30) - , forOf = __webpack_require__(55) - , $iterDefine = __webpack_require__(167) - , step = __webpack_require__(168) - , setSpecies = __webpack_require__(173) - , DESCRIPTORS = __webpack_require__(21) - , fastKey = __webpack_require__(46).fastKey - , SIZE = DESCRIPTORS ? '_s' : 'size'; - -var getEntry = function(that, key){ - // fast case - var index = fastKey(key), entry; - if(index !== 'F')return that._i[index]; - // frozen object case - for(entry = that._f; entry; entry = entry.n){ - if(entry.k == key)return entry; - } -}; - -module.exports = { - getConstructor: function(wrapper, NAME, IS_MAP, ADDER){ - var C = wrapper(function(that, iterable){ - anInstance(that, C, NAME, '_i'); - that._i = create(null); // index - that._f = undefined; // first entry - that._l = undefined; // last entry - that[SIZE] = 0; // size - if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that); - }); - redefineAll(C.prototype, { - // 23.1.3.1 Map.prototype.clear() - // 23.2.3.2 Set.prototype.clear() - clear: function clear(){ - for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){ - entry.r = true; - if(entry.p)entry.p = entry.p.n = undefined; - delete data[entry.i]; - } - that._f = that._l = undefined; - that[SIZE] = 0; - }, - // 23.1.3.3 Map.prototype.delete(key) - // 23.2.3.4 Set.prototype.delete(value) - 'delete': function(key){ - var that = this - , entry = getEntry(that, key); - if(entry){ - var next = entry.n - , prev = entry.p; - delete that._i[entry.i]; - entry.r = true; - if(prev)prev.n = next; - if(next)next.p = prev; - if(that._f == entry)that._f = next; - if(that._l == entry)that._l = prev; - that[SIZE]--; - } return !!entry; - }, - // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined) - // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined) - forEach: function forEach(callbackfn /*, that = undefined */){ - anInstance(this, C, 'forEach'); - var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3) - , entry; - while(entry = entry ? entry.n : this._f){ - f(entry.v, entry.k, this); - // revert to the last existing entry - while(entry && entry.r)entry = entry.p; - } - }, - // 23.1.3.7 Map.prototype.has(key) - // 23.2.3.7 Set.prototype.has(value) - has: function has(key){ - return !!getEntry(this, key); - } - }); - if(DESCRIPTORS)dP(C.prototype, 'size', { - get: function(){ - return defined(this[SIZE]); - } - }); - return C; - }, - def: function(that, key, value){ - var entry = getEntry(that, key) - , prev, index; - // change existing entry - if(entry){ - entry.v = value; - // create new entry - } else { - that._l = entry = { - i: index = fastKey(key, true), // <- index - k: key, // <- key - v: value, // <- value - p: prev = that._l, // <- previous entry - n: undefined, // <- next entry - r: false // <- removed - }; - if(!that._f)that._f = entry; - if(prev)prev.n = entry; - that[SIZE]++; - // add to index - if(index !== 'F')that._i[index] = entry; - } return that; - }, - getEntry: getEntry, - setStrong: function(C, NAME, IS_MAP){ - // add .keys, .values, .entries, [@@iterator] - // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11 - $iterDefine(C, NAME, function(iterated, kind){ - this._t = iterated; // target - this._k = kind; // kind - this._l = undefined; // previous - }, function(){ - var that = this - , kind = that._k - , entry = that._l; - // revert to the last existing entry - while(entry && entry.r)entry = entry.p; - // get next entry - if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){ - // or finish the iteration - that._t = undefined; - return step(1); - } - // return step by kind - if(kind == 'keys' )return step(0, entry.k); - if(kind == 'values')return step(0, entry.v); - return step(0, [entry.k, entry.v]); - }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true); - - // add [@@species], 23.1.2.2, 23.2.2.2 - setSpecies(NAME); - } -}; + function validate(sequence, tree) { + try { + if (!_isArray(sequence)) { + throw new JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY'); + } + if (tree) { + tree = JSON.parse(JSON.stringify(tree)); //clone tree so that we can safely try applying operations + apply.call(this, tree, sequence, true); + } else { + for (var i = 0; i < sequence.length; i++) { + this.validator(sequence[i], i); + } + } + } catch (e) { + if (e instanceof JsonPatchError) { + return e; + } else { + throw e; + } + } + } + jsonpatch.validate = validate; +})(jsonpatch || (jsonpatch = {})); +if (true) { + exports.apply = jsonpatch.apply; + exports.observe = jsonpatch.observe; + exports.unobserve = jsonpatch.unobserve; + exports.generate = jsonpatch.generate; + exports.compare = jsonpatch.compare; + exports.validate = jsonpatch.validate; + exports.validator = jsonpatch.validator; + exports.JsonPatchError = jsonpatch.JsonPatchError; + exports.Error = jsonpatch.Error; +} /***/ }), -/* 159 */ +/* 180 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var redefineAll = __webpack_require__(58) - , getWeak = __webpack_require__(46).getWeak - , anObject = __webpack_require__(18) - , isObject = __webpack_require__(15) - , anInstance = __webpack_require__(51) - , forOf = __webpack_require__(55) - , createArrayMethod = __webpack_require__(52) - , $has = __webpack_require__(22) - , arrayFind = createArrayMethod(5) - , arrayFindIndex = createArrayMethod(6) - , id = 0; -// fallback for uncaught frozen keys -var uncaughtFrozenStore = function(that){ - return that._l || (that._l = new UncaughtFrozenStore); -}; -var UncaughtFrozenStore = function(){ - this.a = []; -}; -var findUncaughtFrozen = function(store, key){ - return arrayFind(store.a, function(it){ - return it[0] === key; - }); -}; -UncaughtFrozenStore.prototype = { - get: function(key){ - var entry = findUncaughtFrozen(this, key); - if(entry)return entry[1]; - }, - has: function(key){ - return !!findUncaughtFrozen(this, key); - }, - set: function(key, value){ - var entry = findUncaughtFrozen(this, key); - if(entry)entry[1] = value; - else this.a.push([key, value]); - }, - 'delete': function(key){ - var index = arrayFindIndex(this.a, function(it){ - return it[0] === key; - }); - if(~index)this.a.splice(index, 1); - return !!~index; - } -}; +exports.__esModule = true; -module.exports = { - getConstructor: function(wrapper, NAME, IS_MAP, ADDER){ - var C = wrapper(function(that, iterable){ - anInstance(that, C, NAME, '_i'); - that._i = id++; // collection id - that._l = undefined; // leak store for uncaught frozen objects - if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that); - }); - redefineAll(C.prototype, { - // 23.3.3.2 WeakMap.prototype.delete(key) - // 23.4.3.3 WeakSet.prototype.delete(value) - 'delete': function(key){ - if(!isObject(key))return false; - var data = getWeak(key); - if(data === true)return uncaughtFrozenStore(this)['delete'](key); - return data && $has(data, this._i) && delete data[this._i]; - }, - // 23.3.3.4 WeakMap.prototype.has(key) - // 23.4.3.4 WeakSet.prototype.has(value) - has: function has(key){ - if(!isObject(key))return false; - var data = getWeak(key); - if(data === true)return uncaughtFrozenStore(this).has(key); - return data && $has(data, this._i); - } - }); - return C; - }, - def: function(that, key, value){ - var data = getWeak(anObject(key), true); - if(data === true)uncaughtFrozenStore(that).set(key, value); - else data[that._i] = value; - return that; - }, - ufstore: uncaughtFrozenStore -}; +__webpack_require__(89); -/***/ }), -/* 160 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(103); -module.exports = __webpack_require__(13).document && document.documentElement; +__webpack_require__(104); -/***/ }), -/* 161 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(108); -module.exports = !__webpack_require__(21) && !__webpack_require__(31)(function(){ - return Object.defineProperty(__webpack_require__(74)('div'), 'a', {get: function(){ return 7; }}).a != 7; -}); +__webpack_require__(109); -/***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(111); -// check on default Array iterator -var Iterators = __webpack_require__(45) - , ITERATOR = __webpack_require__(10)('iterator') - , ArrayProto = Array.prototype; +__webpack_require__(113); -module.exports = function(it){ - return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); -}; +__webpack_require__(114); -/***/ }), -/* 163 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(115); -// 7.2.2 IsArray(argument) -var cof = __webpack_require__(38); -module.exports = Array.isArray || function isArray(arg){ - return cof(arg) == 'Array'; -}; +__webpack_require__(116); -/***/ }), -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(117); -// 20.1.2.3 Number.isInteger(number) -var isObject = __webpack_require__(15) - , floor = Math.floor; -module.exports = function isInteger(it){ - return !isObject(it) && isFinite(it) && floor(it) === it; -}; +__webpack_require__(118); -/***/ }), -/* 165 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(119); -// 7.2.8 IsRegExp(argument) -var isObject = __webpack_require__(15) - , cof = __webpack_require__(38) - , MATCH = __webpack_require__(10)('match'); -module.exports = function(it){ - var isRegExp; - return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp'); -}; +__webpack_require__(120); -/***/ }), -/* 166 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(122); -// call something on iterator step with safe closing on error -var anObject = __webpack_require__(18); -module.exports = function(iterator, fn, value, entries){ - try { - return entries ? fn(anObject(value)[0], value[1]) : fn(value); - // 7.4.6 IteratorClose(iterator, completion) - } catch(e){ - var ret = iterator['return']; - if(ret !== undefined)anObject(ret.call(iterator)); - throw e; - } -}; +__webpack_require__(124); -/***/ }), -/* 167 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(125); -"use strict"; +__webpack_require__(126); -var LIBRARY = __webpack_require__(56) - , $export = __webpack_require__(3) - , redefine = __webpack_require__(33) - , hide = __webpack_require__(32) - , has = __webpack_require__(22) - , Iterators = __webpack_require__(45) - , $iterCreate = __webpack_require__(287) - , setToStringTag = __webpack_require__(48) - , getPrototypeOf = __webpack_require__(292) - , ITERATOR = __webpack_require__(10)('iterator') - , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` - , FF_ITERATOR = '@@iterator' - , KEYS = 'keys' - , VALUES = 'values'; - -var returnThis = function(){ return this; }; - -module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ - $iterCreate(Constructor, NAME, next); - var getMethod = function(kind){ - if(!BUGGY && kind in proto)return proto[kind]; - switch(kind){ - case KEYS: return function keys(){ return new Constructor(this, kind); }; - case VALUES: return function values(){ return new Constructor(this, kind); }; - } return function entries(){ return new Constructor(this, kind); }; - }; - var TAG = NAME + ' Iterator' - , DEF_VALUES = DEFAULT == VALUES - , VALUES_BUG = false - , proto = Base.prototype - , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] - , $default = $native || getMethod(DEFAULT) - , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined - , $anyNative = NAME == 'Array' ? proto.entries || $native : $native - , methods, key, IteratorPrototype; - // Fix native - if($anyNative){ - IteratorPrototype = getPrototypeOf($anyNative.call(new Base)); - if(IteratorPrototype !== Object.prototype){ - // Set @@toStringTag to native iterators - setToStringTag(IteratorPrototype, TAG, true); - // fix for some old engines - if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); - } - } - // fix Array#{values, @@iterator}.name in V8 / FF - if(DEF_VALUES && $native && $native.name !== VALUES){ - VALUES_BUG = true; - $default = function values(){ return $native.call(this); }; - } - // Define iterator - if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ - hide(proto, ITERATOR, $default); - } - // Plug for library - Iterators[NAME] = $default; - Iterators[TAG] = returnThis; - if(DEFAULT){ - methods = { - values: DEF_VALUES ? $default : getMethod(VALUES), - keys: IS_SET ? $default : getMethod(KEYS), - entries: $entries - }; - if(FORCED)for(key in methods){ - if(!(key in proto))redefine(proto, key, methods[key]); - } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); - } - return methods; -}; +__webpack_require__(127); -/***/ }), -/* 168 */ -/***/ (function(module, exports) { +__webpack_require__(128); -module.exports = function(done, value){ - return {value: value, done: !!done}; -}; +__webpack_require__(129); -/***/ }), -/* 169 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(130); -"use strict"; +__webpack_require__(131); -// 19.1.2.1 Object.assign(target, source, ...) -var getKeys = __webpack_require__(39) - , gOPS = __webpack_require__(57) - , pIE = __webpack_require__(47) - , toObject = __webpack_require__(41) - , IObject = __webpack_require__(77) - , $assign = Object.assign; +__webpack_require__(132); -// should work with symbols and should have deterministic property order (V8 bug) -module.exports = !$assign || __webpack_require__(31)(function(){ - var A = {} - , B = {} - , S = Symbol() - , K = 'abcdefghijklmnopqrst'; - A[S] = 7; - K.split('').forEach(function(k){ B[k] = k; }); - return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K; -}) ? function assign(target, source){ // eslint-disable-line no-unused-vars - var T = toObject(target) - , aLen = arguments.length - , index = 1 - , getSymbols = gOPS.f - , isEnum = pIE.f; - while(aLen > index){ - var S = IObject(arguments[index++]) - , keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S) - , length = keys.length - , j = 0 - , key; - while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key]; - } return T; -} : $assign; +__webpack_require__(133); -/***/ }), -/* 170 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(134); -var has = __webpack_require__(22) - , toIObject = __webpack_require__(23) - , arrayIndexOf = __webpack_require__(156)(false) - , IE_PROTO = __webpack_require__(82)('IE_PROTO'); - -module.exports = function(object, names){ - var O = toIObject(object) - , i = 0 - , result = [] - , key; - for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key); - // Don't enum bug & hidden keys - while(names.length > i)if(has(O, key = names[i++])){ - ~arrayIndexOf(result, key) || result.push(key); - } - return result; -}; +__webpack_require__(135); -/***/ }), -/* 171 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(136); -var getKeys = __webpack_require__(39) - , toIObject = __webpack_require__(23) - , isEnum = __webpack_require__(47).f; -module.exports = function(isEntries){ - return function(it){ - var O = toIObject(it) - , keys = getKeys(O) - , length = keys.length - , i = 0 - , result = [] - , key; - while(length > i)if(isEnum.call(O, key = keys[i++])){ - result.push(isEntries ? [key, O[key]] : O[key]); - } return result; - }; -}; +__webpack_require__(78); -/***/ }), -/* 172 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(137); -// Works with __proto__ only. Old v8 can't work with null proto objects. -/* eslint-disable no-proto */ -var isObject = __webpack_require__(15) - , anObject = __webpack_require__(18); -var check = function(O, proto){ - anObject(O); - if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!"); -}; -module.exports = { - set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line - function(test, buggy, set){ - try { - set = __webpack_require__(29)(Function.call, __webpack_require__(80).f(Object.prototype, '__proto__').set, 2); - set(test, []); - buggy = !(test instanceof Array); - } catch(e){ buggy = true; } - return function setPrototypeOf(O, proto){ - check(O, proto); - if(buggy)O.__proto__ = proto; - else set(O, proto); - return O; - }; - }({}, false) : undefined), - check: check -}; +__webpack_require__(138); -/***/ }), -/* 173 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(140); -"use strict"; +__webpack_require__(141); -var global = __webpack_require__(13) - , dP = __webpack_require__(19) - , DESCRIPTORS = __webpack_require__(21) - , SPECIES = __webpack_require__(10)('species'); +__webpack_require__(142); -module.exports = function(KEY){ - var C = global[KEY]; - if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, { - configurable: true, - get: function(){ return this; } - }); -}; +__webpack_require__(143); -/***/ }), -/* 174 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(144); -// https://github.com/tc39/proposal-string-pad-start-end -var toLength = __webpack_require__(24) - , repeat = __webpack_require__(175) - , defined = __webpack_require__(30); - -module.exports = function(that, maxLength, fillString, left){ - var S = String(defined(that)) - , stringLength = S.length - , fillStr = fillString === undefined ? ' ' : String(fillString) - , intMaxLength = toLength(maxLength); - if(intMaxLength <= stringLength || fillStr == '')return S; - var fillLen = intMaxLength - stringLength - , stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length)); - if(stringFiller.length > fillLen)stringFiller = stringFiller.slice(0, fillLen); - return left ? stringFiller + S : S + stringFiller; -}; +__webpack_require__(145); +__webpack_require__(146); -/***/ }), -/* 175 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(148); -"use strict"; +__webpack_require__(149); -var toInteger = __webpack_require__(60) - , defined = __webpack_require__(30); +__webpack_require__(150); -module.exports = function repeat(count){ - var str = String(defined(this)) - , res = '' - , n = toInteger(count); - if(n < 0 || n == Infinity)throw RangeError("Count can't be negative"); - for(;n > 0; (n >>>= 1) && (str += str))if(n & 1)res += str; - return res; -}; +__webpack_require__(152); -/***/ }), -/* 176 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(153); -exports.f = __webpack_require__(10); +__webpack_require__(154); -/***/ }), -/* 177 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(201); -var classof = __webpack_require__(157) - , ITERATOR = __webpack_require__(10)('iterator') - , Iterators = __webpack_require__(45); -module.exports = __webpack_require__(44).getIteratorMethod = function(it){ - if(it != undefined)return it[ITERATOR] - || it['@@iterator'] - || Iterators[classof(it)]; -}; +__webpack_require__(202); -/***/ }), -/* 178 */ -/***/ (function(module, exports, __webpack_require__) { +__webpack_require__(203); -"use strict"; +var _editors = __webpack_require__(15); +var _renderers = __webpack_require__(9); -exports.__esModule = true; -exports.default = jQueryWrapper; -function jQueryWrapper(Handsontable) { - var jQuery = typeof window === 'undefined' ? false : window.jQuery; +var _validators = __webpack_require__(27); - if (!jQuery) { - return; - } +var _cellTypes = __webpack_require__(81); - jQuery.fn.handsontable = function (action) { - var $this = this.first(); // Use only first element from list - var instance = $this.data('handsontable'); +var _core = __webpack_require__(82); - // Init case - if (typeof action !== 'string') { - var userSettings = action || {}; +var _core2 = _interopRequireDefault(_core); - if (instance) { - instance.updateSettings(userSettings); - } else { - instance = new Handsontable.Core($this[0], userSettings); - $this.data('handsontable', instance); - instance.init(); - } +var _jquery = __webpack_require__(246); - return $this; - } +var _jquery2 = _interopRequireDefault(_jquery); - // Action case - var args = []; - var output = void 0; +var _eventManager = __webpack_require__(4); - if (arguments.length > 1) { - for (var i = 1, ilen = arguments.length; i < ilen; i++) { - args.push(arguments[i]); - } - } +var _eventManager2 = _interopRequireDefault(_eventManager); - if (instance) { - if (typeof instance[action] !== 'undefined') { - output = instance[action].apply(instance, args); +var _pluginHooks = __webpack_require__(7); - if (action === 'destroy') { - $this.removeData(); - } - } else { - throw new Error('Handsontable do not provide action: ' + action); - } - } +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - return output; - }; -}; +var _ghostTable = __webpack_require__(85); -/***/ }), -/* 179 */ -/***/ (function(module, exports, __webpack_require__) { +var _ghostTable2 = _interopRequireDefault(_ghostTable); -"use strict"; +var _array = __webpack_require__(2); +var arrayHelpers = _interopRequireWildcard(_array); -exports.__esModule = true; -exports.Base = exports.UndoRedo = exports.TouchScroll = exports.Search = exports.PersistentState = exports.ObserveChanges = exports.MultipleSelectionHandles = exports.MergeCells = exports.ManualRowResize = exports.ManualRowMove = exports.ManualColumnResize = exports.ManualColumnMove = exports.ManualColumnFreeze = exports.DragToScroll = exports.CustomBorders = exports.CopyPaste = exports.ContextMenu = exports.Comments = exports.ColumnSorting = exports.AutoRowSize = exports.AutoFill = exports.AutoColumnSize = undefined; +var _browser = __webpack_require__(26); -var _autoColumnSize = __webpack_require__(212); +var browserHelpers = _interopRequireWildcard(_browser); -var _autoColumnSize2 = _interopRequireDefault(_autoColumnSize); +var _data = __webpack_require__(84); -var _autofill = __webpack_require__(214); +var dataHelpers = _interopRequireWildcard(_data); -var _autofill2 = _interopRequireDefault(_autofill); +var _date = __webpack_require__(170); -var _autoRowSize = __webpack_require__(213); +var dateHelpers = _interopRequireWildcard(_date); -var _autoRowSize2 = _interopRequireDefault(_autoRowSize); +var _feature = __webpack_require__(34); -var _columnSorting = __webpack_require__(216); +var featureHelpers = _interopRequireWildcard(_feature); -var _columnSorting2 = _interopRequireDefault(_columnSorting); +var _function = __webpack_require__(35); -var _comments = __webpack_require__(218); +var functionHelpers = _interopRequireWildcard(_function); -var _comments2 = _interopRequireDefault(_comments); +var _mixed = __webpack_require__(22); -var _contextMenu = __webpack_require__(221); +var mixedHelpers = _interopRequireWildcard(_mixed); -var _contextMenu2 = _interopRequireDefault(_contextMenu); +var _number = __webpack_require__(6); -var _copyPaste = __webpack_require__(238); +var numberHelpers = _interopRequireWildcard(_number); -var _copyPaste2 = _interopRequireDefault(_copyPaste); +var _object = __webpack_require__(1); -var _customBorders = __webpack_require__(240); +var objectHelpers = _interopRequireWildcard(_object); -var _customBorders2 = _interopRequireDefault(_customBorders); +var _setting = __webpack_require__(83); -var _dragToScroll = __webpack_require__(241); +var settingHelpers = _interopRequireWildcard(_setting); -var _dragToScroll2 = _interopRequireDefault(_dragToScroll); +var _string = __webpack_require__(32); -var _manualColumnFreeze = __webpack_require__(244); +var stringHelpers = _interopRequireWildcard(_string); -var _manualColumnFreeze2 = _interopRequireDefault(_manualColumnFreeze); +var _unicode = __webpack_require__(17); -var _manualColumnMove = __webpack_require__(246); +var unicodeHelpers = _interopRequireWildcard(_unicode); -var _manualColumnMove2 = _interopRequireDefault(_manualColumnMove); +var _element = __webpack_require__(0); -var _manualColumnResize = __webpack_require__(249); +var domHelpers = _interopRequireWildcard(_element); -var _manualColumnResize2 = _interopRequireDefault(_manualColumnResize); +var _event = __webpack_require__(8); -var _manualRowMove = __webpack_require__(250); +var domEventHelpers = _interopRequireWildcard(_event); -var _manualRowMove2 = _interopRequireDefault(_manualRowMove); +var _index = __webpack_require__(247); -var _manualRowResize = __webpack_require__(254); +var plugins = _interopRequireWildcard(_index); -var _manualRowResize2 = _interopRequireDefault(_manualRowResize); +var _plugins = __webpack_require__(5); -var _mergeCells = __webpack_require__(255); +var _defaultSettings = __webpack_require__(174); -var _mergeCells2 = _interopRequireDefault(_mergeCells); +var _defaultSettings2 = _interopRequireDefault(_defaultSettings); -var _multipleSelectionHandles = __webpack_require__(256); +var _rootInstance = __webpack_require__(173); -var _multipleSelectionHandles2 = _interopRequireDefault(_multipleSelectionHandles); +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } -var _observeChanges = __webpack_require__(258); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _observeChanges2 = _interopRequireDefault(_observeChanges); +function Handsontable(rootElement, userSettings) { + var instance = new _core2.default(rootElement, userSettings || {}, _rootInstance.rootInstanceSymbol); -var _persistentState = __webpack_require__(260); + instance.init(); -var _persistentState2 = _interopRequireDefault(_persistentState); + return instance; +} -var _search = __webpack_require__(261); +(0, _jquery2.default)(Handsontable); -var _search2 = _interopRequireDefault(_search); +Handsontable.Core = _core2.default; +Handsontable.DefaultSettings = _defaultSettings2.default; +Handsontable.EventManager = _eventManager2.default; +Handsontable._getListenersCounter = _eventManager.getListenersCounter; // For MemoryLeak tests -var _touchScroll = __webpack_require__(262); +Handsontable.buildDate = '12/09/2017 13:23:01'; +Handsontable.packageName = 'handsontable'; +Handsontable.version = '0.34.3'; -var _touchScroll2 = _interopRequireDefault(_touchScroll); +var baseVersion = ''; -var _undoRedo = __webpack_require__(263); +if (baseVersion) { + Handsontable.baseVersion = baseVersion; +} -var _undoRedo2 = _interopRequireDefault(_undoRedo); +// Export Hooks singleton +Handsontable.hooks = _pluginHooks2.default.getSingleton(); -var _base = __webpack_require__(12); +// TODO: Remove this exports after rewrite tests about this module +Handsontable.__GhostTable = _ghostTable2.default; +// -var _base2 = _interopRequireDefault(_base); +// Export all helpers to the Handsontable object +var HELPERS = [arrayHelpers, browserHelpers, dataHelpers, dateHelpers, featureHelpers, functionHelpers, mixedHelpers, numberHelpers, objectHelpers, settingHelpers, stringHelpers, unicodeHelpers]; +var DOM = [domHelpers, domEventHelpers]; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +Handsontable.helper = {}; +Handsontable.dom = {}; -exports.AutoColumnSize = _autoColumnSize2.default; -exports.AutoFill = _autofill2.default; -exports.AutoRowSize = _autoRowSize2.default; -exports.ColumnSorting = _columnSorting2.default; -exports.Comments = _comments2.default; -exports.ContextMenu = _contextMenu2.default; -exports.CopyPaste = _copyPaste2.default; -exports.CustomBorders = _customBorders2.default; -exports.DragToScroll = _dragToScroll2.default; -exports.ManualColumnFreeze = _manualColumnFreeze2.default; -exports.ManualColumnMove = _manualColumnMove2.default; -exports.ManualColumnResize = _manualColumnResize2.default; -exports.ManualRowMove = _manualRowMove2.default; -exports.ManualRowResize = _manualRowResize2.default; -exports.MergeCells = _mergeCells2.default; -exports.MultipleSelectionHandles = _multipleSelectionHandles2.default; -exports.ObserveChanges = _observeChanges2.default; -exports.PersistentState = _persistentState2.default; -exports.Search = _search2.default; -exports.TouchScroll = _touchScroll2.default; -exports.UndoRedo = _undoRedo2.default; -exports.Base = _base2.default; +// Fill general helpers. +arrayHelpers.arrayEach(HELPERS, function (helper) { + arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) { + if (key.charAt(0) !== '_') { + Handsontable.helper[key] = helper[key]; + } + }); +}); -/***/ }), -/* 180 */ -/***/ (function(module, exports) { +// Fill DOM helpers. +arrayHelpers.arrayEach(DOM, function (helper) { + arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) { + if (key.charAt(0) !== '_') { + Handsontable.dom[key] = helper[key]; + } + }); +}); -// removed by extract-text-webpack-plugin +// Export cell types. +Handsontable.cellTypes = {}; -/***/ }), -/* 181 */ -/***/ (function(module, exports) { +arrayHelpers.arrayEach((0, _cellTypes.getRegisteredCellTypeNames)(), function (cellTypeName) { + Handsontable.cellTypes[cellTypeName] = (0, _cellTypes.getCellType)(cellTypeName); +}); -// removed by extract-text-webpack-plugin +Handsontable.cellTypes.registerCellType = _cellTypes.registerCellType; +Handsontable.cellTypes.getCellType = _cellTypes.getCellType; -/***/ }), -/* 182 */ -/***/ (function(module, exports) { +// Export all registered editors from the Handsontable. +Handsontable.editors = {}; -// removed by extract-text-webpack-plugin +arrayHelpers.arrayEach((0, _editors.getRegisteredEditorNames)(), function (editorName) { + Handsontable.editors[stringHelpers.toUpperCaseFirst(editorName) + 'Editor'] = (0, _editors.getEditor)(editorName); +}); -/***/ }), -/* 183 */ -/***/ (function(module, exports) { +Handsontable.editors.registerEditor = _editors.registerEditor; +Handsontable.editors.getEditor = _editors.getEditor; +// Export all registered renderers from the Handsontable. +Handsontable.renderers = {}; +arrayHelpers.arrayEach((0, _renderers.getRegisteredRendererNames)(), function (rendererName) { + var renderer = (0, _renderers.getRenderer)(rendererName); -/***/ }), -/* 184 */ -/***/ (function(module, exports, __webpack_require__) { + if (rendererName === 'base') { + Handsontable.renderers.cellDecorator = renderer; + } + Handsontable.renderers[stringHelpers.toUpperCaseFirst(rendererName) + 'Renderer'] = renderer; +}); -"use strict"; +Handsontable.renderers.registerRenderer = _renderers.registerRenderer; +Handsontable.renderers.getRenderer = _renderers.getRenderer; +// Export all registered validators from the Handsontable. +Handsontable.validators = {}; -/** - * autoResize - resizes a DOM element to the width and height of another DOM element - * - * Copyright 2014, Marcin Warpechowski - * Licensed under the MIT license - */ +arrayHelpers.arrayEach((0, _validators.getRegisteredValidatorNames)(), function (validatorName) { + Handsontable.validators[stringHelpers.toUpperCaseFirst(validatorName) + 'Validator'] = (0, _validators.getValidator)(validatorName); +}); -function autoResize() { - var defaults = { - minHeight: 200, - maxHeight: 300, - minWidth: 100, - maxWidth: 300 - }, - el, - body = document.body, - text = document.createTextNode(''), - span = document.createElement('SPAN'), - observe = function observe(element, event, handler) { - if (element.attachEvent) { - element.attachEvent('on' + event, handler); - } else { - element.addEventListener(event, handler, false); - } - }, - _unObserve = function _unObserve(element, event, handler) { - if (element.removeEventListener) { - element.removeEventListener(event, handler, false); - } else { - element.detachEvent('on' + event, handler); - } - }, - resize = function resize(newChar) { - var width, scrollHeight; +Handsontable.validators.registerValidator = _validators.registerValidator; +Handsontable.validators.getValidator = _validators.getValidator; - if (!newChar) { - newChar = ""; - } else if (!/^[a-zA-Z \.,\\\/\|0-9]$/.test(newChar)) { - newChar = "."; - } +// Export all registered plugins from the Handsontable. +Handsontable.plugins = {}; - if (text.textContent !== void 0) { - text.textContent = el.value + newChar; - } else { - text.data = el.value + newChar; //IE8 - } - span.style.fontSize = getComputedStyle(el).fontSize; - span.style.fontFamily = getComputedStyle(el).fontFamily; - span.style.whiteSpace = "pre"; +arrayHelpers.arrayEach(Object.getOwnPropertyNames(plugins), function (pluginName) { + var plugin = plugins[pluginName]; + + if (pluginName === 'Base') { + Handsontable.plugins[pluginName + 'Plugin'] = plugin; + } else { + Handsontable.plugins[pluginName] = plugin; + } +}); - body.appendChild(span); - width = span.clientWidth + 2; - body.removeChild(span); +Handsontable.plugins.registerPlugin = _plugins.registerPlugin; - el.style.height = defaults.minHeight + 'px'; +exports.default = Handsontable; - if (defaults.minWidth > width) { - el.style.width = defaults.minWidth + 'px'; - } else if (width > defaults.maxWidth) { - el.style.width = defaults.maxWidth + 'px'; - } else { - el.style.width = width + 'px'; - } - scrollHeight = el.scrollHeight ? el.scrollHeight - 1 : 0; +/***/ }), +/* 181 */ +/***/ (function(module, exports, __webpack_require__) { - if (defaults.minHeight > scrollHeight) { - el.style.height = defaults.minHeight + 'px'; - } else if (defaults.maxHeight < scrollHeight) { - el.style.height = defaults.maxHeight + 'px'; - el.style.overflowY = 'visible'; - } else { - el.style.height = scrollHeight + 'px'; - } - }, - delayedResize = function delayedResize() { - window.setTimeout(resize, 0); - }, - extendDefaults = function extendDefaults(config) { +var dP = __webpack_require__(18); +var anObject = __webpack_require__(16); +var getKeys = __webpack_require__(36); - if (config && config.minHeight) { - if (config.minHeight == 'inherit') { - defaults.minHeight = el.clientHeight; - } else { - var minHeight = parseInt(config.minHeight); - if (!isNaN(minHeight)) { - defaults.minHeight = minHeight; - } - } - } +module.exports = __webpack_require__(20) ? Object.defineProperties : function defineProperties(O, Properties) { + anObject(O); + var keys = getKeys(Properties); + var length = keys.length; + var i = 0; + var P; + while (length > i) dP.f(O, P = keys[i++], Properties[P]); + return O; +}; - if (config && config.maxHeight) { - if (config.maxHeight == 'inherit') { - defaults.maxHeight = el.clientHeight; - } else { - var maxHeight = parseInt(config.maxHeight); - if (!isNaN(maxHeight)) { - defaults.maxHeight = maxHeight; - } - } - } - if (config && config.minWidth) { - if (config.minWidth == 'inherit') { - defaults.minWidth = el.clientWidth; - } else { - var minWidth = parseInt(config.minWidth); - if (!isNaN(minWidth)) { - defaults.minWidth = minWidth; - } - } - } +/***/ }), +/* 182 */ +/***/ (function(module, exports, __webpack_require__) { - if (config && config.maxWidth) { - if (config.maxWidth == 'inherit') { - defaults.maxWidth = el.clientWidth; - } else { - var maxWidth = parseInt(config.maxWidth); - if (!isNaN(maxWidth)) { - defaults.maxWidth = maxWidth; - } - } - } +"use strict"; - if (!span.firstChild) { - span.className = "autoResize"; - span.style.display = 'inline-block'; - span.appendChild(text); - } - }, - _init = function _init(el_, config, doObserve) { - el = el_; - extendDefaults(config); +var create = __webpack_require__(66); +var descriptor = __webpack_require__(43); +var setToStringTag = __webpack_require__(46); +var IteratorPrototype = {}; - if (el.nodeName == 'TEXTAREA') { +// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() +__webpack_require__(29)(IteratorPrototype, __webpack_require__(10)('iterator'), function () { return this; }); - el.style.resize = 'none'; - el.style.overflowY = ''; - el.style.height = defaults.minHeight + 'px'; - el.style.minWidth = defaults.minWidth + 'px'; - el.style.maxWidth = defaults.maxWidth + 'px'; - el.style.overflowY = 'hidden'; - } +module.exports = function (Constructor, NAME, next) { + Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) }); + setToStringTag(Constructor, NAME + ' Iterator'); +}; - if (doObserve) { - observe(el, 'change', resize); - observe(el, 'cut', delayedResize); - observe(el, 'paste', delayedResize); - observe(el, 'drop', delayedResize); - observe(el, 'keydown', delayedResize); - observe(el, 'focus', resize); - } - resize(); - }; +/***/ }), +/* 183 */ +/***/ (function(module, exports, __webpack_require__) { - function getComputedStyle(element) { - return element.currentStyle || document.defaultView.getComputedStyle(element); - } +// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) +var has = __webpack_require__(24); +var toObject = __webpack_require__(38); +var IE_PROTO = __webpack_require__(68)('IE_PROTO'); +var ObjectProto = Object.prototype; - return { - init: function init(el_, config, doObserve) { - _init(el_, config, doObserve); - }, - unObserve: function unObserve() { - _unObserve(el, 'change', resize); - _unObserve(el, 'cut', delayedResize); - _unObserve(el, 'paste', delayedResize); - _unObserve(el, 'drop', delayedResize); - _unObserve(el, 'keydown', delayedResize); - _unObserve(el, 'focus', resize); - }, - resize: resize - }; -} +module.exports = Object.getPrototypeOf || function (O) { + O = toObject(O); + if (has(O, IE_PROTO)) return O[IE_PROTO]; + if (typeof O.constructor == 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } return O instanceof Object ? ObjectProto : null; +}; + + +/***/ }), +/* 184 */ +/***/ (function(module, exports, __webpack_require__) { + +var isObject = __webpack_require__(14); +var setPrototypeOf = __webpack_require__(102).set; +module.exports = function (that, target, C) { + var S = target.constructor; + var P; + if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) { + setPrototypeOf(that, P); + } return that; +}; -if (true) { - module.exports = autoResize; -} /***/ }), /* 185 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// 9.4.2.3 ArraySpeciesCreate(originalArray, length) +var speciesConstructor = __webpack_require__(186); +module.exports = function (original, length) { + return new (speciesConstructor(original))(length); +}; -exports.__esModule = true; -var _element = __webpack_require__(0); +/***/ }), +/* 186 */ +/***/ (function(module, exports, __webpack_require__) { -var _base = __webpack_require__(28); +var isObject = __webpack_require__(14); +var isArray = __webpack_require__(105); +var SPECIES = __webpack_require__(10)('species'); -var _base2 = _interopRequireDefault(_base); +module.exports = function (original) { + var C; + if (isArray(original)) { + C = original.constructor; + // cross-realm fallback + if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined; + if (isObject(C)) { + C = C[SPECIES]; + if (C === null) C = undefined; + } + } return C === undefined ? Array : C; +}; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +/***/ }), +/* 187 */ +/***/ (function(module, exports, __webpack_require__) { -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +// 7.3.20 SpeciesConstructor(O, defaultConstructor) +var anObject = __webpack_require__(16); +var aFunction = __webpack_require__(54); +var SPECIES = __webpack_require__(10)('species'); +module.exports = function (O, D) { + var C = anObject(O).constructor; + var S; + return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); +}; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -/** - * A overlay that renders ALL available rows & columns positioned on top of the original Walkontable instance and all other overlays. - * Used for debugging purposes to see if the other overlays (that render only part of the rows & columns) are positioned correctly - * - * @class DebugOverlay - */ -var DebugOverlay = function (_Overlay) { - _inherits(DebugOverlay, _Overlay); +/***/ }), +/* 188 */ +/***/ (function(module, exports) { - /** - * @param {Walkontable} wotInstance - */ - function DebugOverlay(wotInstance) { - _classCallCheck(this, DebugOverlay); +// fast apply, http://jsperf.lnkit.com/fast-apply/5 +module.exports = function (fn, args, that) { + var un = that === undefined; + switch (args.length) { + case 0: return un ? fn() + : fn.call(that); + case 1: return un ? fn(args[0]) + : fn.call(that, args[0]); + case 2: return un ? fn(args[0], args[1]) + : fn.call(that, args[0], args[1]); + case 3: return un ? fn(args[0], args[1], args[2]) + : fn.call(that, args[0], args[1], args[2]); + case 4: return un ? fn(args[0], args[1], args[2], args[3]) + : fn.call(that, args[0], args[1], args[2], args[3]); + } return fn.apply(that, args); +}; - var _this = _possibleConstructorReturn(this, (DebugOverlay.__proto__ || Object.getPrototypeOf(DebugOverlay)).call(this, wotInstance)); - _this.clone = _this.makeClone(_base2.default.CLONE_DEBUG); - _this.clone.wtTable.holder.style.opacity = 0.4; - _this.clone.wtTable.holder.style.textShadow = '0 0 2px #ff0000'; +/***/ }), +/* 189 */ +/***/ (function(module, exports, __webpack_require__) { - (0, _element.addClass)(_this.clone.wtTable.holder.parentNode, 'wtDebugVisible'); - return _this; - } +var global = __webpack_require__(11); +var macrotask = __webpack_require__(73).set; +var Observer = global.MutationObserver || global.WebKitMutationObserver; +var process = global.process; +var Promise = global.Promise; +var isNode = __webpack_require__(37)(process) == 'process'; - return DebugOverlay; -}(_base2.default); +module.exports = function () { + var head, last, notify; -_base2.default.registerOverlay(_base2.default.CLONE_DEBUG, DebugOverlay); + var flush = function () { + var parent, fn; + if (isNode && (parent = process.domain)) parent.exit(); + while (head) { + fn = head.fn; + head = head.next; + try { + fn(); + } catch (e) { + if (head) notify(); + else last = undefined; + throw e; + } + } last = undefined; + if (parent) parent.enter(); + }; + + // Node.js + if (isNode) { + notify = function () { + process.nextTick(flush); + }; + // browsers with MutationObserver + } else if (Observer) { + var toggle = true; + var node = document.createTextNode(''); + new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new + notify = function () { + node.data = toggle = !toggle; + }; + // environments with maybe non-completely correct, but existent Promise + } else if (Promise && Promise.resolve) { + var promise = Promise.resolve(); + notify = function () { + promise.then(flush); + }; + // for other environments - macrotask based on: + // - setImmediate + // - MessageChannel + // - window.postMessag + // - onreadystatechange + // - setTimeout + } else { + notify = function () { + // strange IE + webpack dev server bug - use .call(global) + macrotask.call(global, flush); + }; + } + + return function (fn) { + var task = { fn: fn, next: undefined }; + if (last) last.next = task; + if (!head) { + head = task; + notify(); + } last = task; + }; +}; -exports.default = DebugOverlay; /***/ }), -/* 186 */ -/***/ (function(module, exports, __webpack_require__) { +/* 190 */ +/***/ (function(module, exports) { -"use strict"; +module.exports = function (exec) { + try { + return { e: false, v: exec() }; + } catch (e) { + return { e: true, v: e }; + } +}; -exports.__esModule = true; +/***/ }), +/* 191 */ +/***/ (function(module, exports, __webpack_require__) { -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var anObject = __webpack_require__(16); +var isObject = __webpack_require__(14); +var newPromiseCapability = __webpack_require__(110); + +module.exports = function (C, x) { + anObject(C); + if (isObject(x) && x.constructor === C) return x; + var promiseCapability = newPromiseCapability.f(C); + var resolve = promiseCapability.resolve; + resolve(x); + return promiseCapability.promise; +}; -var _element = __webpack_require__(0); -var _base = __webpack_require__(28); +/***/ }), +/* 192 */ +/***/ (function(module, exports, __webpack_require__) { -var _base2 = _interopRequireDefault(_base); +var global = __webpack_require__(11); +var core = __webpack_require__(44); +var LIBRARY = __webpack_require__(57); +var wksExt = __webpack_require__(112); +var defineProperty = __webpack_require__(18).f; +module.exports = function (name) { + var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {}); + if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) }); +}; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +/***/ }), +/* 193 */ +/***/ (function(module, exports, __webpack_require__) { -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +// all enumerable object keys, includes symbols +var getKeys = __webpack_require__(36); +var gOPS = __webpack_require__(60); +var pIE = __webpack_require__(48); +module.exports = function (it) { + var result = getKeys(it); + var getSymbols = gOPS.f; + if (getSymbols) { + var symbols = getSymbols(it); + var isEnum = pIE.f; + var i = 0; + var key; + while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key); + } return result; +}; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -/** - * @class LeftOverlay - */ -var LeftOverlay = function (_Overlay) { - _inherits(LeftOverlay, _Overlay); +/***/ }), +/* 194 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * @param {Walkontable} wotInstance - */ - function LeftOverlay(wotInstance) { - _classCallCheck(this, LeftOverlay); +// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window +var toIObject = __webpack_require__(25); +var gOPN = __webpack_require__(74).f; +var toString = {}.toString; - var _this = _possibleConstructorReturn(this, (LeftOverlay.__proto__ || Object.getPrototypeOf(LeftOverlay)).call(this, wotInstance)); +var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames + ? Object.getOwnPropertyNames(window) : []; - _this.clone = _this.makeClone(_base2.default.CLONE_LEFT); - return _this; +var getWindowNames = function (it) { + try { + return gOPN(it); + } catch (e) { + return windowNames.slice(); } +}; - /** - * Checks if overlay should be fully rendered - * - * @returns {Boolean} - */ - +module.exports.f = function getOwnPropertyNames(it) { + return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it)); +}; - _createClass(LeftOverlay, [{ - key: 'shouldBeRendered', - value: function shouldBeRendered() { - return !!(this.wot.getSetting('fixedColumnsLeft') || this.wot.getSetting('rowHeaders').length); - } - /** - * Updates the left overlay position - */ +/***/ }), +/* 195 */ +/***/ (function(module, exports) { - }, { - key: 'resetFixedPosition', - value: function resetFixedPosition() { - if (!this.needFullRender || !this.wot.wtTable.holder.parentNode) { - // removed from DOM - return; - } - var overlayRoot = this.clone.wtTable.holder.parentNode; - var headerPosition = 0; - var preventOverflow = this.wot.getSetting('preventOverflow'); +// 7.2.9 SameValue(x, y) +module.exports = Object.is || function is(x, y) { + // eslint-disable-next-line no-self-compare + return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y; +}; - if (this.trimmingContainer === window && (!preventOverflow || preventOverflow !== 'horizontal')) { - var box = this.wot.wtTable.hider.getBoundingClientRect(); - var left = Math.ceil(box.left); - var right = Math.ceil(box.right); - var finalLeft = void 0; - var finalTop = void 0; - finalTop = this.wot.wtTable.hider.style.top; - finalTop = finalTop === '' ? 0 : finalTop; +/***/ }), +/* 196 */ +/***/ (function(module, exports, __webpack_require__) { - if (left < 0 && right - overlayRoot.offsetWidth > 0) { - finalLeft = -left; - } else { - finalLeft = 0; - } - headerPosition = finalLeft; - finalLeft += 'px'; +var toInteger = __webpack_require__(51); +var defined = __webpack_require__(33); +// true -> String#at +// false -> String#codePointAt +module.exports = function (TO_STRING) { + return function (that, pos) { + var s = String(defined(that)); + var i = toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) return TO_STRING ? '' : undefined; + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; +}; - (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop); - } else { - headerPosition = this.getScrollPosition(); - (0, _element.resetCssTransform)(overlayRoot); - } - this.adjustHeaderBordersPosition(headerPosition); - this.adjustElementsSize(); - } +/***/ }), +/* 197 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Sets the main overlay's horizontal scroll position - * - * @param {Number} pos - */ +"use strict"; - }, { - key: 'setScrollPosition', - value: function setScrollPosition(pos) { - if (this.mainTableScrollableElement === window) { - window.scrollTo(pos, (0, _element.getWindowScrollTop)()); - } else { - this.mainTableScrollableElement.scrollLeft = pos; - } - } +// 21.2.5.3 get RegExp.prototype.flags +var anObject = __webpack_require__(16); +module.exports = function () { + var that = anObject(this); + var result = ''; + if (that.global) result += 'g'; + if (that.ignoreCase) result += 'i'; + if (that.multiline) result += 'm'; + if (that.unicode) result += 'u'; + if (that.sticky) result += 'y'; + return result; +}; - /** - * Triggers onScroll hook callback - */ - }, { - key: 'onScroll', - value: function onScroll() { - this.wot.getSetting('onScrollVertically'); - } +/***/ }), +/* 198 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Calculates total sum cells width - * - * @param {Number} from Column index which calculates started from - * @param {Number} to Column index where calculation is finished - * @returns {Number} Width sum - */ +"use strict"; +// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length) - }, { - key: 'sumCellSizes', - value: function sumCellSizes(from, to) { - var sum = 0; - var defaultColumnWidth = this.wot.wtSettings.defaultColumnWidth; +var toObject = __webpack_require__(38); +var toAbsoluteIndex = __webpack_require__(52); +var toLength = __webpack_require__(21); + +module.exports = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) { + var O = toObject(this); + var len = toLength(O.length); + var to = toAbsoluteIndex(target, len); + var from = toAbsoluteIndex(start, len); + var end = arguments.length > 2 ? arguments[2] : undefined; + var count = Math.min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to); + var inc = 1; + if (from < to && to < from + count) { + inc = -1; + from += count - 1; + to += count - 1; + } + while (count-- > 0) { + if (from in O) O[to] = O[from]; + else delete O[to]; + to += inc; + from += inc; + } return O; +}; - while (from < to) { - sum += this.wot.wtTable.getStretchedColumnWidth(from) || defaultColumnWidth; - from++; - } - return sum; - } +/***/ }), +/* 199 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Adjust overlay root element, childs and master table element sizes (width, height). - * - * @param {Boolean} [force=false] - */ +"use strict"; +// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length) - }, { - key: 'adjustElementsSize', - value: function adjustElementsSize() { - var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; +var toObject = __webpack_require__(38); +var toAbsoluteIndex = __webpack_require__(52); +var toLength = __webpack_require__(21); +module.exports = function fill(value /* , start = 0, end = @length */) { + var O = toObject(this); + var length = toLength(O.length); + var aLen = arguments.length; + var index = toAbsoluteIndex(aLen > 1 ? arguments[1] : undefined, length); + var end = aLen > 2 ? arguments[2] : undefined; + var endPos = end === undefined ? length : toAbsoluteIndex(end, length); + while (endPos > index) O[index++] = value; + return O; +}; - this.updateTrimmingContainer(); - if (this.needFullRender || force) { - this.adjustRootElementSize(); - this.adjustRootChildrenSize(); +/***/ }), +/* 200 */ +/***/ (function(module, exports, __webpack_require__) { - if (!force) { - this.areElementSizesAdjusted = true; - } - } - } +// all object keys, includes non-enumerable and symbols +var gOPN = __webpack_require__(74); +var gOPS = __webpack_require__(60); +var anObject = __webpack_require__(16); +var Reflect = __webpack_require__(11).Reflect; +module.exports = Reflect && Reflect.ownKeys || function ownKeys(it) { + var keys = gOPN.f(anObject(it)); + var getSymbols = gOPS.f; + return getSymbols ? keys.concat(getSymbols(it)) : keys; +}; - /** - * Adjust overlay root element size (width and height). - */ - }, { - key: 'adjustRootElementSize', - value: function adjustRootElementSize() { - var masterHolder = this.wot.wtTable.holder; - var scrollbarHeight = masterHolder.clientHeight === masterHolder.offsetHeight ? 0 : (0, _element.getScrollbarWidth)(); - var overlayRoot = this.clone.wtTable.holder.parentNode; - var overlayRootStyle = overlayRoot.style; - var preventOverflow = this.wot.getSetting('preventOverflow'); - var tableWidth = void 0; +/***/ }), +/* 201 */ +/***/ (function(module, exports) { - if (this.trimmingContainer !== window || preventOverflow === 'vertical') { - var height = this.wot.wtViewport.getWorkspaceHeight() - scrollbarHeight; +// removed by extract-text-webpack-plugin - height = Math.min(height, (0, _element.innerHeight)(this.wot.wtTable.wtRootElement)); +/***/ }), +/* 202 */ +/***/ (function(module, exports) { - overlayRootStyle.height = height + 'px'; - } else { - overlayRootStyle.height = ''; - } +// removed by extract-text-webpack-plugin - this.clone.wtTable.holder.style.height = overlayRootStyle.height; +/***/ }), +/* 203 */ +/***/ (function(module, exports) { - tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE); - overlayRootStyle.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px'; - } +// removed by extract-text-webpack-plugin - /** - * Adjust overlay root childs size - */ +/***/ }), +/* 204 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'adjustRootChildrenSize', - value: function adjustRootChildrenSize() { - var scrollbarWidth = (0, _element.getScrollbarWidth)(); +"use strict"; - this.clone.wtTable.hider.style.height = this.hider.style.height; - this.clone.wtTable.holder.style.height = this.clone.wtTable.holder.parentNode.style.height; - if (scrollbarWidth === 0) { - scrollbarWidth = 30; - } - this.clone.wtTable.holder.style.width = parseInt(this.clone.wtTable.holder.parentNode.style.width, 10) + scrollbarWidth + 'px'; - } +exports.__esModule = true; - /** - * Adjust the overlay dimensions and position - */ +var _element = __webpack_require__(0); - }, { - key: 'applyToDOM', - value: function applyToDOM() { - var total = this.wot.getSetting('totalColumns'); +var _base = __webpack_require__(31); - if (!this.areElementSizesAdjusted) { - this.adjustElementsSize(); - } - if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') { - this.spreader.style.left = this.wot.wtViewport.columnsRenderCalculator.startPosition + 'px'; - } else if (total === 0) { - this.spreader.style.left = '0'; - } else { - throw new Error('Incorrect value of the columnsRenderCalculator'); - } - this.spreader.style.right = ''; +var _base2 = _interopRequireDefault(_base); - if (this.needFullRender) { - this.syncOverlayOffset(); - } - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - /** - * Synchronize calculated top position to an element - */ +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - }, { - key: 'syncOverlayOffset', - value: function syncOverlayOffset() { - if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') { - this.clone.wtTable.spreader.style.top = this.wot.wtViewport.rowsRenderCalculator.startPosition + 'px'; - } else { - this.clone.wtTable.spreader.style.top = ''; - } - } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - /** - * Scrolls horizontally to a column at the left edge of the viewport - * - * @param sourceCol {Number} Column index which you want to scroll to - * @param [beyondRendered=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default) - */ +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - }, { - key: 'scrollTo', - value: function scrollTo(sourceCol, beyondRendered) { - var newX = this.getTableParentOffset(); - var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot; - var mainHolder = sourceInstance.wtTable.holder; - var scrollbarCompensation = 0; +/** + * A overlay that renders ALL available rows & columns positioned on top of the original Walkontable instance and all other overlays. + * Used for debugging purposes to see if the other overlays (that render only part of the rows & columns) are positioned correctly + * + * @class DebugOverlay + */ +var DebugOverlay = function (_Overlay) { + _inherits(DebugOverlay, _Overlay); - if (beyondRendered && mainHolder.offsetWidth !== mainHolder.clientWidth) { - scrollbarCompensation = (0, _element.getScrollbarWidth)(); - } - if (beyondRendered) { - newX += this.sumCellSizes(0, sourceCol + 1); - newX -= this.wot.wtViewport.getViewportWidth(); - } else { - newX += this.sumCellSizes(this.wot.getSetting('fixedColumnsLeft'), sourceCol); - } - newX += scrollbarCompensation; + /** + * @param {Walkontable} wotInstance + */ + function DebugOverlay(wotInstance) { + _classCallCheck(this, DebugOverlay); - this.setScrollPosition(newX); - } + var _this = _possibleConstructorReturn(this, (DebugOverlay.__proto__ || Object.getPrototypeOf(DebugOverlay)).call(this, wotInstance)); - /** - * Gets table parent left position - * - * @returns {Number} - */ + _this.clone = _this.makeClone(_base2.default.CLONE_DEBUG); + _this.clone.wtTable.holder.style.opacity = 0.4; + _this.clone.wtTable.holder.style.textShadow = '0 0 2px #ff0000'; - }, { - key: 'getTableParentOffset', - value: function getTableParentOffset() { - var preventOverflow = this.wot.getSetting('preventOverflow'); - var offset = 0; + (0, _element.addClass)(_this.clone.wtTable.holder.parentNode, 'wtDebugVisible'); + return _this; + } - if (!preventOverflow && this.trimmingContainer === window) { - offset = this.wot.wtTable.holderOffset.left; - } + return DebugOverlay; +}(_base2.default); - return offset; - } +_base2.default.registerOverlay(_base2.default.CLONE_DEBUG, DebugOverlay); - /** - * Gets the main overlay's horizontal scroll position - * - * @returns {Number} Main table's vertical scroll position - */ +exports.default = DebugOverlay; - }, { - key: 'getScrollPosition', - value: function getScrollPosition() { - return (0, _element.getScrollLeft)(this.mainTableScrollableElement); - } +/***/ }), +/* 205 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Adds css classes to hide the header border's header (cell-selection border hiding issue) - * - * @param {Number} position Header X position if trimming container is window or scroll top if not - */ +"use strict"; - }, { - key: 'adjustHeaderBordersPosition', - value: function adjustHeaderBordersPosition(position) { - var masterParent = this.wot.wtTable.holder.parentNode; - var rowHeaders = this.wot.getSetting('rowHeaders'); - var fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft'); - var totalRows = this.wot.getSetting('totalRows'); - if (totalRows) { - (0, _element.removeClass)(masterParent, 'emptyRows'); - } else { - (0, _element.addClass)(masterParent, 'emptyRows'); - } +exports.__esModule = true; +exports.toSingleLine = toSingleLine; - if (fixedColumnsLeft && !rowHeaders.length) { - (0, _element.addClass)(masterParent, 'innerBorderLeft'); - } else if (!fixedColumnsLeft && rowHeaders.length) { - var previousState = (0, _element.hasClass)(masterParent, 'innerBorderLeft'); +var _array = __webpack_require__(2); - if (position) { - (0, _element.addClass)(masterParent, 'innerBorderLeft'); - } else { - (0, _element.removeClass)(masterParent, 'innerBorderLeft'); - } - if (!previousState && position || previousState && !position) { - this.wot.wtOverlays.adjustElementsSize(); - } - } - } - }]); +/** + * Tags a multiline string and return new one without line break characters and following spaces. + * + * @param {Array} strings Parts of the entire string without expressions. + * @param {...String} expressions Expressions converted to strings, which are added to the entire string. + * @returns {String} + */ +function toSingleLine(strings) { + for (var _len = arguments.length, expressions = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + expressions[_key - 1] = arguments[_key]; + } - return LeftOverlay; -}(_base2.default); + var result = (0, _array.arrayReduce)(strings, function (previousValue, currentValue, index) { -_base2.default.registerOverlay(_base2.default.CLONE_LEFT, LeftOverlay); + var valueWithoutWhiteSpaces = currentValue.replace(/(?:\r?\n\s+)/g, ''); + var expressionForIndex = expressions[index] ? expressions[index] : ''; -exports.default = LeftOverlay; + return previousValue + valueWithoutWhiteSpaces + expressionForIndex; + }, ''); + + return result.trim(); +} /* eslint-disable import/prefer-default-export */ /***/ }), -/* 187 */ +/* 206 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43894,7 +44139,7 @@ var _createClass = function () { function defineProperties(target, props) { for var _element = __webpack_require__(0); -var _base = __webpack_require__(28); +var _base = __webpack_require__(31); var _base2 = _interopRequireDefault(_base); @@ -43907,20 +44152,20 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** - * @class TopOverlay + * @class LeftOverlay */ -var TopOverlay = function (_Overlay) { - _inherits(TopOverlay, _Overlay); +var LeftOverlay = function (_Overlay) { + _inherits(LeftOverlay, _Overlay); /** * @param {Walkontable} wotInstance */ - function TopOverlay(wotInstance) { - _classCallCheck(this, TopOverlay); + function LeftOverlay(wotInstance) { + _classCallCheck(this, LeftOverlay); - var _this = _possibleConstructorReturn(this, (TopOverlay.__proto__ || Object.getPrototypeOf(TopOverlay)).call(this, wotInstance)); + var _this = _possibleConstructorReturn(this, (LeftOverlay.__proto__ || Object.getPrototypeOf(LeftOverlay)).call(this, wotInstance)); - _this.clone = _this.makeClone(_base2.default.CLONE_TOP); + _this.clone = _this.makeClone(_base2.default.CLONE_LEFT); return _this; } @@ -43931,14 +44176,14 @@ var TopOverlay = function (_Overlay) { */ - _createClass(TopOverlay, [{ + _createClass(LeftOverlay, [{ key: 'shouldBeRendered', value: function shouldBeRendered() { - return !!(this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length); + return !!(this.wot.getSetting('fixedColumnsLeft') || this.wot.getSetting('rowHeaders').length); } /** - * Updates the top overlay position + * Updates the left overlay position */ }, { @@ -43952,37 +44197,36 @@ var TopOverlay = function (_Overlay) { var headerPosition = 0; var preventOverflow = this.wot.getSetting('preventOverflow'); - if (this.trimmingContainer === window && (!preventOverflow || preventOverflow !== 'vertical')) { + if (this.trimmingContainer === window && (!preventOverflow || preventOverflow !== 'horizontal')) { var box = this.wot.wtTable.hider.getBoundingClientRect(); - var top = Math.ceil(box.top); - var bottom = Math.ceil(box.bottom); + var left = Math.ceil(box.left); + var right = Math.ceil(box.right); var finalLeft = void 0; var finalTop = void 0; - finalLeft = this.wot.wtTable.hider.style.left; - finalLeft = finalLeft === '' ? 0 : finalLeft; + finalTop = this.wot.wtTable.hider.style.top; + finalTop = finalTop === '' ? 0 : finalTop; - if (top < 0 && bottom - overlayRoot.offsetHeight > 0) { - finalTop = -top; + if (left < 0 && right - overlayRoot.offsetWidth > 0) { + finalLeft = -left; } else { - finalTop = 0; + finalLeft = 0; } - headerPosition = finalTop; - finalTop += 'px'; + headerPosition = finalLeft; + finalLeft += 'px'; (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop); } else { headerPosition = this.getScrollPosition(); (0, _element.resetCssTransform)(overlayRoot); } - this.adjustHeaderBordersPosition(headerPosition); this.adjustElementsSize(); } /** - * Sets the main overlay's vertical scroll position + * Sets the main overlay's horizontal scroll position * * @param {Number} pos */ @@ -43991,9 +44235,9 @@ var TopOverlay = function (_Overlay) { key: 'setScrollPosition', value: function setScrollPosition(pos) { if (this.mainTableScrollableElement === window) { - window.scrollTo((0, _element.getWindowScrollLeft)(), pos); + window.scrollTo(pos, (0, _element.getWindowScrollTop)()); } else { - this.mainTableScrollableElement.scrollTop = pos; + this.mainTableScrollableElement.scrollLeft = pos; } } @@ -44004,27 +44248,25 @@ var TopOverlay = function (_Overlay) { }, { key: 'onScroll', value: function onScroll() { - this.wot.getSetting('onScrollHorizontally'); + this.wot.getSetting('onScrollVertically'); } /** - * Calculates total sum cells height + * Calculates total sum cells width * - * @param {Number} from Row index which calculates started from - * @param {Number} to Row index where calculation is finished - * @returns {Number} Height sum + * @param {Number} from Column index which calculates started from + * @param {Number} to Column index where calculation is finished + * @returns {Number} Width sum */ }, { key: 'sumCellSizes', value: function sumCellSizes(from, to) { var sum = 0; - var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight; + var defaultColumnWidth = this.wot.wtSettings.defaultColumnWidth; while (from < to) { - var height = this.wot.wtTable.getRowHeight(from); - - sum += height === void 0 ? defaultRowHeight : height; + sum += this.wot.wtTable.getStretchedColumnWidth(from) || defaultColumnWidth; from++; } @@ -44062,26 +44304,26 @@ var TopOverlay = function (_Overlay) { key: 'adjustRootElementSize', value: function adjustRootElementSize() { var masterHolder = this.wot.wtTable.holder; - var scrollbarWidth = masterHolder.clientWidth === masterHolder.offsetWidth ? 0 : (0, _element.getScrollbarWidth)(); + var scrollbarHeight = masterHolder.clientHeight === masterHolder.offsetHeight ? 0 : (0, _element.getScrollbarWidth)(); var overlayRoot = this.clone.wtTable.holder.parentNode; var overlayRootStyle = overlayRoot.style; var preventOverflow = this.wot.getSetting('preventOverflow'); - var tableHeight = void 0; + var tableWidth = void 0; - if (this.trimmingContainer !== window || preventOverflow === 'horizontal') { - var width = this.wot.wtViewport.getWorkspaceWidth() - scrollbarWidth; + if (this.trimmingContainer !== window || preventOverflow === 'vertical') { + var height = this.wot.wtViewport.getWorkspaceHeight() - scrollbarHeight; - width = Math.min(width, (0, _element.innerWidth)(this.wot.wtTable.wtRootElement)); + height = Math.min(height, (0, _element.innerHeight)(this.wot.wtTable.wtRootElement)); - overlayRootStyle.width = width + 'px'; + overlayRootStyle.height = height + 'px'; } else { - overlayRootStyle.width = ''; + overlayRootStyle.height = ''; } - this.clone.wtTable.holder.style.width = overlayRootStyle.width; + this.clone.wtTable.holder.style.height = overlayRootStyle.height; - tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE); - overlayRootStyle.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px'; + tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE); + overlayRootStyle.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px'; } /** @@ -44093,13 +44335,13 @@ var TopOverlay = function (_Overlay) { value: function adjustRootChildrenSize() { var scrollbarWidth = (0, _element.getScrollbarWidth)(); - this.clone.wtTable.hider.style.width = this.hider.style.width; - this.clone.wtTable.holder.style.width = this.clone.wtTable.holder.parentNode.style.width; + this.clone.wtTable.hider.style.height = this.hider.style.height; + this.clone.wtTable.holder.style.height = this.clone.wtTable.holder.parentNode.style.height; if (scrollbarWidth === 0) { scrollbarWidth = 30; } - this.clone.wtTable.holder.style.height = parseInt(this.clone.wtTable.holder.parentNode.style.height, 10) + scrollbarWidth + 'px'; + this.clone.wtTable.holder.style.width = parseInt(this.clone.wtTable.holder.parentNode.style.width, 10) + scrollbarWidth + 'px'; } /** @@ -44109,20 +44351,19 @@ var TopOverlay = function (_Overlay) { }, { key: 'applyToDOM', value: function applyToDOM() { - var total = this.wot.getSetting('totalRows'); + var total = this.wot.getSetting('totalColumns'); if (!this.areElementSizesAdjusted) { this.adjustElementsSize(); } - if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') { - this.spreader.style.top = this.wot.wtViewport.rowsRenderCalculator.startPosition + 'px'; + if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') { + this.spreader.style.left = this.wot.wtViewport.columnsRenderCalculator.startPosition + 'px'; } else if (total === 0) { - // can happen if there are 0 rows - this.spreader.style.top = '0'; + this.spreader.style.left = '0'; } else { - throw new Error('Incorrect value of the rowsRenderCalculator'); + throw new Error('Incorrect value of the columnsRenderCalculator'); } - this.spreader.style.bottom = ''; + this.spreader.style.right = ''; if (this.needFullRender) { this.syncOverlayOffset(); @@ -44130,57 +44371,50 @@ var TopOverlay = function (_Overlay) { } /** - * Synchronize calculated left position to an element + * Synchronize calculated top position to an element */ }, { key: 'syncOverlayOffset', value: function syncOverlayOffset() { - if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') { - this.clone.wtTable.spreader.style.left = this.wot.wtViewport.columnsRenderCalculator.startPosition + 'px'; + if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') { + this.clone.wtTable.spreader.style.top = this.wot.wtViewport.rowsRenderCalculator.startPosition + 'px'; } else { - this.clone.wtTable.spreader.style.left = ''; + this.clone.wtTable.spreader.style.top = ''; } } /** - * Scrolls vertically to a row + * Scrolls horizontally to a column at the left edge of the viewport * - * @param sourceRow {Number} Row index which you want to scroll to - * @param [bottomEdge=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default) + * @param sourceCol {Number} Column index which you want to scroll to + * @param [beyondRendered=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default) */ }, { key: 'scrollTo', - value: function scrollTo(sourceRow, bottomEdge) { - var newY = this.getTableParentOffset(); + value: function scrollTo(sourceCol, beyondRendered) { + var newX = this.getTableParentOffset(); var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot; var mainHolder = sourceInstance.wtTable.holder; var scrollbarCompensation = 0; - if (bottomEdge && mainHolder.offsetHeight !== mainHolder.clientHeight) { + if (beyondRendered && mainHolder.offsetWidth !== mainHolder.clientWidth) { scrollbarCompensation = (0, _element.getScrollbarWidth)(); } - - if (bottomEdge) { - var fixedRowsBottom = this.wot.getSetting('fixedRowsBottom'); - var fixedRowsTop = this.wot.getSetting('fixedRowsTop'); - var totalRows = this.wot.getSetting('totalRows'); - - newY += this.sumCellSizes(0, sourceRow + 1); - newY -= this.wot.wtViewport.getViewportHeight() - this.sumCellSizes(totalRows - fixedRowsBottom, totalRows); - // Fix 1 pixel offset when cell is selected - newY += 1; + if (beyondRendered) { + newX += this.sumCellSizes(0, sourceCol + 1); + newX -= this.wot.wtViewport.getViewportWidth(); } else { - newY += this.sumCellSizes(this.wot.getSetting('fixedRowsTop'), sourceRow); + newX += this.sumCellSizes(this.wot.getSetting('fixedColumnsLeft'), sourceCol); } - newY += scrollbarCompensation; + newX += scrollbarCompensation; - this.setScrollPosition(newY); + this.setScrollPosition(newX); } /** - * Gets table parent top position + * Gets table parent left position * * @returns {Number} */ @@ -44188,14 +44422,18 @@ var TopOverlay = function (_Overlay) { }, { key: 'getTableParentOffset', value: function getTableParentOffset() { - if (this.mainTableScrollableElement === window) { - return this.wot.wtTable.holderOffset.top; + var preventOverflow = this.wot.getSetting('preventOverflow'); + var offset = 0; + + if (!preventOverflow && this.trimmingContainer === window) { + offset = this.wot.wtTable.holderOffset.left; } - return 0; + + return offset; } /** - * Gets the main overlay's vertical scroll position + * Gets the main overlay's horizontal scroll position * * @returns {Number} Main table's vertical scroll position */ @@ -44203,212 +44441,55 @@ var TopOverlay = function (_Overlay) { }, { key: 'getScrollPosition', value: function getScrollPosition() { - return (0, _element.getScrollTop)(this.mainTableScrollableElement); - } - - /** - * Redraw borders of selection - * - * @param {WalkontableSelection} selection Selection for redraw - */ - - }, { - key: 'redrawSelectionBorders', - value: function redrawSelectionBorders(selection) { - if (selection && selection.cellRange) { - var border = selection.getBorder(this.wot); - - if (border) { - var corners = selection.getCorners(); - border.disappear(); - border.appear(corners); - } - } - } - - /** - * Redrawing borders of all selections - */ - - }, { - key: 'redrawAllSelectionsBorders', - value: function redrawAllSelectionsBorders() { - var selections = this.wot.selections; - - this.redrawSelectionBorders(selections.current); - this.redrawSelectionBorders(selections.area); - this.redrawSelectionBorders(selections.fill); - this.wot.wtTable.wot.wtOverlays.leftOverlay.refresh(); + return (0, _element.getScrollLeft)(this.mainTableScrollableElement); } /** * Adds css classes to hide the header border's header (cell-selection border hiding issue) * - * @param {Number} position Header Y position if trimming container is window or scroll top if not + * @param {Number} position Header X position if trimming container is window or scroll top if not */ }, { key: 'adjustHeaderBordersPosition', value: function adjustHeaderBordersPosition(position) { var masterParent = this.wot.wtTable.holder.parentNode; - var totalColumns = this.wot.getSetting('totalColumns'); + var rowHeaders = this.wot.getSetting('rowHeaders'); + var fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft'); + var totalRows = this.wot.getSetting('totalRows'); - if (totalColumns) { - (0, _element.removeClass)(masterParent, 'emptyColumns'); + if (totalRows) { + (0, _element.removeClass)(masterParent, 'emptyRows'); } else { - (0, _element.addClass)(masterParent, 'emptyColumns'); - } - - if (this.wot.getSetting('fixedRowsTop') === 0 && this.wot.getSetting('columnHeaders').length > 0) { - var previousState = (0, _element.hasClass)(masterParent, 'innerBorderTop'); - - if (position || this.wot.getSetting('totalRows') === 0) { - (0, _element.addClass)(masterParent, 'innerBorderTop'); - } else { - (0, _element.removeClass)(masterParent, 'innerBorderTop'); - } - - if (!previousState && position || previousState && !position) { - this.wot.wtOverlays.adjustElementsSize(); - - // cell borders should be positioned once again, - // because we added / removed 1px border from table header - this.redrawAllSelectionsBorders(); - } - } - - // nasty workaround for double border in the header, TODO: find a pure-css solution - if (this.wot.getSetting('rowHeaders').length === 0) { - var secondHeaderCell = this.clone.wtTable.THEAD.querySelectorAll('th:nth-of-type(2)'); - - if (secondHeaderCell) { - for (var i = 0; i < secondHeaderCell.length; i++) { - secondHeaderCell[i].style['border-left-width'] = 0; - } - } - } - } - }]); - - return TopOverlay; -}(_base2.default); - -_base2.default.registerOverlay(_base2.default.CLONE_TOP, TopOverlay); - -exports.default = TopOverlay; - -/***/ }), -/* 188 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _element = __webpack_require__(0); - -var _base = __webpack_require__(28); - -var _base2 = _interopRequireDefault(_base); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -/** - * @class TopLeftCornerOverlay - */ -var TopLeftCornerOverlay = function (_Overlay) { - _inherits(TopLeftCornerOverlay, _Overlay); - - /** - * @param {Walkontable} wotInstance - */ - function TopLeftCornerOverlay(wotInstance) { - _classCallCheck(this, TopLeftCornerOverlay); - - var _this = _possibleConstructorReturn(this, (TopLeftCornerOverlay.__proto__ || Object.getPrototypeOf(TopLeftCornerOverlay)).call(this, wotInstance)); - - _this.clone = _this.makeClone(_base2.default.CLONE_TOP_LEFT_CORNER); - return _this; - } - - /** - * Checks if overlay should be fully rendered - * - * @returns {Boolean} - */ - - - _createClass(TopLeftCornerOverlay, [{ - key: 'shouldBeRendered', - value: function shouldBeRendered() { - return !!((this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length) && (this.wot.getSetting('fixedColumnsLeft') || this.wot.getSetting('rowHeaders').length)); - } - - /** - * Updates the corner overlay position - */ - - }, { - key: 'resetFixedPosition', - value: function resetFixedPosition() { - this.updateTrimmingContainer(); - - if (!this.wot.wtTable.holder.parentNode) { - // removed from DOM - return; + (0, _element.addClass)(masterParent, 'emptyRows'); } - var overlayRoot = this.clone.wtTable.holder.parentNode; - var tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE); - var tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE); - var preventOverflow = this.wot.getSetting('preventOverflow'); - if (this.trimmingContainer === window) { - var box = this.wot.wtTable.hider.getBoundingClientRect(); - var top = Math.ceil(box.top); - var left = Math.ceil(box.left); - var bottom = Math.ceil(box.bottom); - var right = Math.ceil(box.right); - var finalLeft = '0'; - var finalTop = '0'; + if (fixedColumnsLeft && !rowHeaders.length) { + (0, _element.addClass)(masterParent, 'innerBorderLeft'); + } else if (!fixedColumnsLeft && rowHeaders.length) { + var previousState = (0, _element.hasClass)(masterParent, 'innerBorderLeft'); - if (!preventOverflow || preventOverflow === 'vertical') { - if (left < 0 && right - overlayRoot.offsetWidth > 0) { - finalLeft = -left + 'px'; - } + if (position) { + (0, _element.addClass)(masterParent, 'innerBorderLeft'); + } else { + (0, _element.removeClass)(masterParent, 'innerBorderLeft'); } - - if (!preventOverflow || preventOverflow === 'horizontal') { - if (top < 0 && bottom - overlayRoot.offsetHeight > 0) { - finalTop = -top + 'px'; - } + if (!previousState && position || previousState && !position) { + this.wot.wtOverlays.adjustElementsSize(); } - (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop); - } else { - (0, _element.resetCssTransform)(overlayRoot); } - overlayRoot.style.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px'; - overlayRoot.style.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px'; } }]); - return TopLeftCornerOverlay; + return LeftOverlay; }(_base2.default); -_base2.default.registerOverlay(_base2.default.CLONE_TOP_LEFT_CORNER, TopLeftCornerOverlay); +_base2.default.registerOverlay(_base2.default.CLONE_LEFT, LeftOverlay); -exports.default = TopLeftCornerOverlay; +exports.default = LeftOverlay; /***/ }), -/* 189 */ +/* 207 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44416,478 +44497,415 @@ exports.default = TopLeftCornerOverlay; exports.__esModule = true; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _element = __webpack_require__(0); -var _border2 = __webpack_require__(136); - -var _border3 = _interopRequireDefault(_border2); - -var _coords = __webpack_require__(42); - -var _coords2 = _interopRequireDefault(_coords); +var _base = __webpack_require__(31); -var _range = __webpack_require__(68); - -var _range2 = _interopRequireDefault(_range); +var _base2 = _interopRequireDefault(_base); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + /** - * @class Selection + * @class TopOverlay */ -var Selection = function () { +var TopOverlay = function (_Overlay) { + _inherits(TopOverlay, _Overlay); + /** - * @param {Object} settings - * @param {CellRange} cellRange + * @param {Walkontable} wotInstance */ - function Selection(settings, cellRange) { - _classCallCheck(this, Selection); + function TopOverlay(wotInstance) { + _classCallCheck(this, TopOverlay); - this.settings = settings; - this.cellRange = cellRange || null; - this.instanceBorders = {}; + var _this = _possibleConstructorReturn(this, (TopOverlay.__proto__ || Object.getPrototypeOf(TopOverlay)).call(this, wotInstance)); + + _this.clone = _this.makeClone(_base2.default.CLONE_TOP); + return _this; } /** - * Each Walkontable clone requires it's own border for every selection. This method creates and returns selection - * borders per instance + * Checks if overlay should be fully rendered * - * @param {Walkontable} wotInstance - * @returns {Border} + * @returns {Boolean} */ - _createClass(Selection, [{ - key: 'getBorder', - value: function getBorder(wotInstance) { - if (this.instanceBorders[wotInstance.guid]) { - return this.instanceBorders[wotInstance.guid]; - } - - // where is this returned? - this.instanceBorders[wotInstance.guid] = new _border3.default(wotInstance, this.settings); + _createClass(TopOverlay, [{ + key: 'shouldBeRendered', + value: function shouldBeRendered() { + return !!(this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length); } /** - * Checks if selection is empty - * - * @returns {Boolean} + * Updates the top overlay position */ }, { - key: 'isEmpty', - value: function isEmpty() { - return this.cellRange === null; - } + key: 'resetFixedPosition', + value: function resetFixedPosition() { + if (!this.needFullRender || !this.wot.wtTable.holder.parentNode) { + // removed from DOM + return; + } + var overlayRoot = this.clone.wtTable.holder.parentNode; + var headerPosition = 0; + var preventOverflow = this.wot.getSetting('preventOverflow'); - /** - * Adds a cell coords to the selection - * - * @param {CellCoords} coords - */ + if (this.trimmingContainer === window && (!preventOverflow || preventOverflow !== 'vertical')) { + var box = this.wot.wtTable.hider.getBoundingClientRect(); + var top = Math.ceil(box.top); + var bottom = Math.ceil(box.bottom); + var finalLeft = void 0; + var finalTop = void 0; - }, { - key: 'add', - value: function add(coords) { - if (this.isEmpty()) { - this.cellRange = new _range2.default(coords, coords, coords); + finalLeft = this.wot.wtTable.hider.style.left; + finalLeft = finalLeft === '' ? 0 : finalLeft; + + if (top < 0 && bottom - overlayRoot.offsetHeight > 0) { + finalTop = -top; + } else { + finalTop = 0; + } + headerPosition = finalTop; + finalTop += 'px'; + + (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop); } else { - this.cellRange.expand(coords); + headerPosition = this.getScrollPosition(); + (0, _element.resetCssTransform)(overlayRoot); } + + this.adjustHeaderBordersPosition(headerPosition); + + this.adjustElementsSize(); } /** - * If selection range from or to property equals oldCoords, replace it with newCoords. Return boolean - * information about success + * Sets the main overlay's vertical scroll position * - * @param {CellCoords} oldCoords - * @param {CellCoords} newCoords - * @returns {Boolean} + * @param {Number} pos */ }, { - key: 'replace', - value: function replace(oldCoords, newCoords) { - if (!this.isEmpty()) { - if (this.cellRange.from.isEqual(oldCoords)) { - this.cellRange.from = newCoords; - - return true; - } - if (this.cellRange.to.isEqual(oldCoords)) { - this.cellRange.to = newCoords; - - return true; - } + key: 'setScrollPosition', + value: function setScrollPosition(pos) { + if (this.mainTableScrollableElement === window) { + window.scrollTo((0, _element.getWindowScrollLeft)(), pos); + } else { + this.mainTableScrollableElement.scrollTop = pos; } - - return false; } /** - * Clears selection + * Triggers onScroll hook callback */ }, { - key: 'clear', - value: function clear() { - this.cellRange = null; + key: 'onScroll', + value: function onScroll() { + this.wot.getSetting('onScrollHorizontally'); } /** - * Returns the top left (TL) and bottom right (BR) selection coordinates + * Calculates total sum cells height * - * @returns {Array} Returns array of coordinates for example `[1, 1, 5, 5]` + * @param {Number} from Row index which calculates started from + * @param {Number} to Row index where calculation is finished + * @returns {Number} Height sum */ }, { - key: 'getCorners', - value: function getCorners() { - var topLeft = this.cellRange.getTopLeftCorner(); - var bottomRight = this.cellRange.getBottomRightCorner(); + key: 'sumCellSizes', + value: function sumCellSizes(from, to) { + var sum = 0; + var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight; - return [topLeft.row, topLeft.col, bottomRight.row, bottomRight.col]; + while (from < to) { + var height = this.wot.wtTable.getRowHeight(from); + + sum += height === void 0 ? defaultRowHeight : height; + from++; + } + + return sum; } /** - * Adds class name to cell element at given coords + * Adjust overlay root element, childs and master table element sizes (width, height). * - * @param {Walkontable} wotInstance Walkontable instance - * @param {Number} sourceRow Cell row coord - * @param {Number} sourceColumn Cell column coord - * @param {String} className Class name + * @param {Boolean} [force=false] */ }, { - key: 'addClassAtCoords', - value: function addClassAtCoords(wotInstance, sourceRow, sourceColumn, className) { - var TD = wotInstance.wtTable.getCell(new _coords2.default(sourceRow, sourceColumn)); + key: 'adjustElementsSize', + value: function adjustElementsSize() { + var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - if ((typeof TD === 'undefined' ? 'undefined' : _typeof(TD)) === 'object') { - (0, _element.addClass)(TD, className); + this.updateTrimmingContainer(); + + if (this.needFullRender || force) { + this.adjustRootElementSize(); + this.adjustRootChildrenSize(); + + if (!force) { + this.areElementSizesAdjusted = true; + } } } /** - * @param wotInstance + * Adjust overlay root element size (width and height). */ }, { - key: 'draw', - value: function draw(wotInstance) { - if (this.isEmpty()) { - if (this.settings.border) { - var border = this.getBorder(wotInstance); + key: 'adjustRootElementSize', + value: function adjustRootElementSize() { + var masterHolder = this.wot.wtTable.holder; + var scrollbarWidth = masterHolder.clientWidth === masterHolder.offsetWidth ? 0 : (0, _element.getScrollbarWidth)(); + var overlayRoot = this.clone.wtTable.holder.parentNode; + var overlayRootStyle = overlayRoot.style; + var preventOverflow = this.wot.getSetting('preventOverflow'); + var tableHeight = void 0; - if (border) { - border.disappear(); - } - } + if (this.trimmingContainer !== window || preventOverflow === 'horizontal') { + var width = this.wot.wtViewport.getWorkspaceWidth() - scrollbarWidth; - return; + width = Math.min(width, (0, _element.innerWidth)(this.wot.wtTable.wtRootElement)); + + overlayRootStyle.width = width + 'px'; + } else { + overlayRootStyle.width = ''; } - var renderedRows = wotInstance.wtTable.getRenderedRowsCount(); - var renderedColumns = wotInstance.wtTable.getRenderedColumnsCount(); - var corners = this.getCorners(); - var sourceRow = void 0, - sourceCol = void 0, - TH = void 0; - for (var column = 0; column < renderedColumns; column++) { - sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(column); + this.clone.wtTable.holder.style.width = overlayRootStyle.width; - if (sourceCol >= corners[1] && sourceCol <= corners[3]) { - TH = wotInstance.wtTable.getColumnHeader(sourceCol); + tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE); + overlayRootStyle.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px'; + } - if (TH) { - var newClasses = []; + /** + * Adjust overlay root childs size + */ - if (this.settings.highlightHeaderClassName) { - newClasses.push(this.settings.highlightHeaderClassName); - } + }, { + key: 'adjustRootChildrenSize', + value: function adjustRootChildrenSize() { + var scrollbarWidth = (0, _element.getScrollbarWidth)(); - if (this.settings.highlightColumnClassName) { - newClasses.push(this.settings.highlightColumnClassName); - } + this.clone.wtTable.hider.style.width = this.hider.style.width; + this.clone.wtTable.holder.style.width = this.clone.wtTable.holder.parentNode.style.width; - (0, _element.addClass)(TH, newClasses); - } - } + if (scrollbarWidth === 0) { + scrollbarWidth = 30; } + this.clone.wtTable.holder.style.height = parseInt(this.clone.wtTable.holder.parentNode.style.height, 10) + scrollbarWidth + 'px'; + } - for (var row = 0; row < renderedRows; row++) { - sourceRow = wotInstance.wtTable.rowFilter.renderedToSource(row); - - if (sourceRow >= corners[0] && sourceRow <= corners[2]) { - TH = wotInstance.wtTable.getRowHeader(sourceRow); - - if (TH) { - var _newClasses = []; - - if (this.settings.highlightHeaderClassName) { - _newClasses.push(this.settings.highlightHeaderClassName); - } - - if (this.settings.highlightRowClassName) { - _newClasses.push(this.settings.highlightRowClassName); - } - - (0, _element.addClass)(TH, _newClasses); - } - } + /** + * Adjust the overlay dimensions and position + */ - for (var _column = 0; _column < renderedColumns; _column++) { - sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(_column); + }, { + key: 'applyToDOM', + value: function applyToDOM() { + var total = this.wot.getSetting('totalRows'); - if (sourceRow >= corners[0] && sourceRow <= corners[2] && sourceCol >= corners[1] && sourceCol <= corners[3]) { - // selected cell - if (this.settings.className) { - this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.className); - } - } else if (sourceRow >= corners[0] && sourceRow <= corners[2]) { - // selection is in this row - if (this.settings.highlightRowClassName) { - this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightRowClassName); - } - } else if (sourceCol >= corners[1] && sourceCol <= corners[3]) { - // selection is in this column - if (this.settings.highlightColumnClassName) { - this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightColumnClassName); - } - } - } + if (!this.areElementSizesAdjusted) { + this.adjustElementsSize(); } - wotInstance.getSetting('onBeforeDrawBorders', corners, this.settings.className); - - if (this.settings.border) { - var _border = this.getBorder(wotInstance); + if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') { + this.spreader.style.top = this.wot.wtViewport.rowsRenderCalculator.startPosition + 'px'; + } else if (total === 0) { + // can happen if there are 0 rows + this.spreader.style.top = '0'; + } else { + throw new Error('Incorrect value of the rowsRenderCalculator'); + } + this.spreader.style.bottom = ''; - if (_border) { - // warning! border.appear modifies corners! - _border.appear(corners); - } + if (this.needFullRender) { + this.syncOverlayOffset(); } } - }]); - - return Selection; -}(); - -exports.default = Selection; - -/***/ }), -/* 190 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _editors = __webpack_require__(14); - -var _renderers = __webpack_require__(9); - -var _validators = __webpack_require__(26); - -var CELL_TYPE = 'autocomplete'; - -exports.default = { - editor: (0, _editors.getEditor)(CELL_TYPE), - renderer: (0, _renderers.getRenderer)(CELL_TYPE), - validator: (0, _validators.getValidator)(CELL_TYPE) -}; - -/***/ }), -/* 191 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _editors = __webpack_require__(14); - -var _renderers = __webpack_require__(9); - -var CELL_TYPE = 'checkbox'; - -exports.default = { - editor: (0, _editors.getEditor)(CELL_TYPE), - renderer: (0, _renderers.getRenderer)(CELL_TYPE) -}; - -/***/ }), -/* 192 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _editors = __webpack_require__(14); - -var _renderers = __webpack_require__(9); - -var _validators = __webpack_require__(26); - -var CELL_TYPE = 'date'; - -exports.default = { - editor: (0, _editors.getEditor)(CELL_TYPE), - // displays small gray arrow on right side of the cell - renderer: (0, _renderers.getRenderer)('autocomplete'), - validator: (0, _validators.getValidator)(CELL_TYPE) -}; - -/***/ }), -/* 193 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _editors = __webpack_require__(14); - -var _renderers = __webpack_require__(9); - -var _validators = __webpack_require__(26); - -var CELL_TYPE = 'dropdown'; - -exports.default = { - editor: (0, _editors.getEditor)(CELL_TYPE), - // displays small gray arrow on right side of the cell - renderer: (0, _renderers.getRenderer)('autocomplete'), - validator: (0, _validators.getValidator)('autocomplete') -}; - -/***/ }), -/* 194 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -var _editors = __webpack_require__(14); - -var _renderers = __webpack_require__(9); - -var CELL_TYPE = 'handsontable'; - -exports.default = { - editor: (0, _editors.getEditor)(CELL_TYPE), - // displays small gray arrow on right side of the cell - renderer: (0, _renderers.getRenderer)('autocomplete') -}; - -/***/ }), -/* 195 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _editors = __webpack_require__(14); - -var _renderers = __webpack_require__(9); - -var _validators = __webpack_require__(26); + /** + * Synchronize calculated left position to an element + */ -var CELL_TYPE = 'numeric'; + }, { + key: 'syncOverlayOffset', + value: function syncOverlayOffset() { + if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') { + this.clone.wtTable.spreader.style.left = this.wot.wtViewport.columnsRenderCalculator.startPosition + 'px'; + } else { + this.clone.wtTable.spreader.style.left = ''; + } + } -exports.default = { - editor: (0, _editors.getEditor)(CELL_TYPE), - renderer: (0, _renderers.getRenderer)(CELL_TYPE), - validator: (0, _validators.getValidator)(CELL_TYPE), - dataType: 'number' -}; + /** + * Scrolls vertically to a row + * + * @param sourceRow {Number} Row index which you want to scroll to + * @param [bottomEdge=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default) + */ -/***/ }), -/* 196 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: 'scrollTo', + value: function scrollTo(sourceRow, bottomEdge) { + var newY = this.getTableParentOffset(); + var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot; + var mainHolder = sourceInstance.wtTable.holder; + var scrollbarCompensation = 0; -"use strict"; + if (bottomEdge && mainHolder.offsetHeight !== mainHolder.clientHeight) { + scrollbarCompensation = (0, _element.getScrollbarWidth)(); + } + if (bottomEdge) { + var fixedRowsBottom = this.wot.getSetting('fixedRowsBottom'); + var fixedRowsTop = this.wot.getSetting('fixedRowsTop'); + var totalRows = this.wot.getSetting('totalRows'); -exports.__esModule = true; + newY += this.sumCellSizes(0, sourceRow + 1); + newY -= this.wot.wtViewport.getViewportHeight() - this.sumCellSizes(totalRows - fixedRowsBottom, totalRows); + // Fix 1 pixel offset when cell is selected + newY += 1; + } else { + newY += this.sumCellSizes(this.wot.getSetting('fixedRowsTop'), sourceRow); + } + newY += scrollbarCompensation; -var _editors = __webpack_require__(14); + this.setScrollPosition(newY); + } -var _renderers = __webpack_require__(9); + /** + * Gets table parent top position + * + * @returns {Number} + */ -var _validators = __webpack_require__(26); + }, { + key: 'getTableParentOffset', + value: function getTableParentOffset() { + if (this.mainTableScrollableElement === window) { + return this.wot.wtTable.holderOffset.top; + } + return 0; + } -var CELL_TYPE = 'password'; + /** + * Gets the main overlay's vertical scroll position + * + * @returns {Number} Main table's vertical scroll position + */ -exports.default = { - editor: (0, _editors.getEditor)(CELL_TYPE), - renderer: (0, _renderers.getRenderer)(CELL_TYPE), - copyable: false -}; + }, { + key: 'getScrollPosition', + value: function getScrollPosition() { + return (0, _element.getScrollTop)(this.mainTableScrollableElement); + } -/***/ }), -/* 197 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Redraw borders of selection + * + * @param {WalkontableSelection} selection Selection for redraw + */ -"use strict"; + }, { + key: 'redrawSelectionBorders', + value: function redrawSelectionBorders(selection) { + if (selection && selection.cellRange) { + var border = selection.getBorder(this.wot); + if (border) { + var corners = selection.getCorners(); + border.disappear(); + border.appear(corners); + } + } + } -exports.__esModule = true; + /** + * Redrawing borders of all selections + */ -var _browser = __webpack_require__(25); + }, { + key: 'redrawAllSelectionsBorders', + value: function redrawAllSelectionsBorders() { + var selections = this.wot.selections; -var _editors = __webpack_require__(14); + this.redrawSelectionBorders(selections.current); + this.redrawSelectionBorders(selections.area); + this.redrawSelectionBorders(selections.fill); + this.wot.wtTable.wot.wtOverlays.leftOverlay.refresh(); + } -var _renderers = __webpack_require__(9); + /** + * Adds css classes to hide the header border's header (cell-selection border hiding issue) + * + * @param {Number} position Header Y position if trimming container is window or scroll top if not + */ -var CELL_TYPE = 'text'; + }, { + key: 'adjustHeaderBordersPosition', + value: function adjustHeaderBordersPosition(position) { + var masterParent = this.wot.wtTable.holder.parentNode; + var totalColumns = this.wot.getSetting('totalColumns'); -exports.default = { - editor: (0, _browser.isMobileBrowser)() ? (0, _editors.getEditor)('mobile') : (0, _editors.getEditor)(CELL_TYPE), - renderer: (0, _renderers.getRenderer)(CELL_TYPE) -}; + if (totalColumns) { + (0, _element.removeClass)(masterParent, 'emptyColumns'); + } else { + (0, _element.addClass)(masterParent, 'emptyColumns'); + } -/***/ }), -/* 198 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.wot.getSetting('fixedRowsTop') === 0 && this.wot.getSetting('columnHeaders').length > 0) { + var previousState = (0, _element.hasClass)(masterParent, 'innerBorderTop'); -"use strict"; + if (position || this.wot.getSetting('totalRows') === 0) { + (0, _element.addClass)(masterParent, 'innerBorderTop'); + } else { + (0, _element.removeClass)(masterParent, 'innerBorderTop'); + } + if (!previousState && position || previousState && !position) { + this.wot.wtOverlays.adjustElementsSize(); -exports.__esModule = true; + // cell borders should be positioned once again, + // because we added / removed 1px border from table header + this.redrawAllSelectionsBorders(); + } + } -var _editors = __webpack_require__(14); + // nasty workaround for double border in the header, TODO: find a pure-css solution + if (this.wot.getSetting('rowHeaders').length === 0) { + var secondHeaderCell = this.clone.wtTable.THEAD.querySelectorAll('th:nth-of-type(2)'); -var _renderers = __webpack_require__(9); + if (secondHeaderCell) { + for (var i = 0; i < secondHeaderCell.length; i++) { + secondHeaderCell[i].style['border-left-width'] = 0; + } + } + } + } + }]); -var _validators = __webpack_require__(26); + return TopOverlay; +}(_base2.default); -var CELL_TYPE = 'time'; +_base2.default.registerOverlay(_base2.default.CLONE_TOP, TopOverlay); -exports.default = { - editor: (0, _editors.getEditor)('text'), - // displays small gray arrow on right side of the cell - renderer: (0, _renderers.getRenderer)('text'), - validator: (0, _validators.getValidator)(CELL_TYPE) -}; +exports.default = TopOverlay; /***/ }), -/* 199 */ +/* 208 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44895,1167 +44913,1062 @@ exports.default = { exports.__esModule = true; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _SheetClip = __webpack_require__(134); - -var _SheetClip2 = _interopRequireDefault(_SheetClip); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _data = __webpack_require__(64); +var _element = __webpack_require__(0); -var _setting = __webpack_require__(65); +var _base = __webpack_require__(31); -var _object = __webpack_require__(1); +var _base2 = _interopRequireDefault(_base); -var _array = __webpack_require__(2); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _interval = __webpack_require__(273); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var _interval2 = _interopRequireDefault(_interval); +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } -var _number = __webpack_require__(6); +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var _multiMap = __webpack_require__(211); +/** + * @class TopLeftCornerOverlay + */ +var TopLeftCornerOverlay = function (_Overlay) { + _inherits(TopLeftCornerOverlay, _Overlay); -var _multiMap2 = _interopRequireDefault(_multiMap); + /** + * @param {Walkontable} wotInstance + */ + function TopLeftCornerOverlay(wotInstance) { + _classCallCheck(this, TopLeftCornerOverlay); -var _pluginHooks = __webpack_require__(8); + var _this = _possibleConstructorReturn(this, (TopLeftCornerOverlay.__proto__ || Object.getPrototypeOf(TopLeftCornerOverlay)).call(this, wotInstance)); -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + _this.clone = _this.makeClone(_base2.default.CLONE_TOP_LEFT_CORNER); + return _this; + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** + * Checks if overlay should be fully rendered + * + * @returns {Boolean} + */ -/** - * Utility class that gets and saves data from/to the data source using mapping of columns numbers to object property names - * @todo refactor arguments of methods getRange, getText to be numbers (not objects) - * @todo remove priv, GridSettings from object constructor - * - * @param {Object} instance Instance of Handsontable - * @param {*} priv - * @param {*} GridSettings Grid settings - * @util - * @class DataMap - */ -function DataMap(instance, priv, GridSettings) { - var _this = this; - this.instance = instance; - this.priv = priv; - this.GridSettings = GridSettings; - this.dataSource = this.instance.getSettings().data; - this.cachedLength = null; - this.skipCache = false; - this.latestSourceRowsCount = 0; + _createClass(TopLeftCornerOverlay, [{ + key: 'shouldBeRendered', + value: function shouldBeRendered() { + return !!((this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length) && (this.wot.getSetting('fixedColumnsLeft') || this.wot.getSetting('rowHeaders').length)); + } - if (this.dataSource && this.dataSource[0]) { - this.duckSchema = this.recursiveDuckSchema(this.dataSource[0]); - } else { - this.duckSchema = {}; - } - this.createMap(); - this.interval = _interval2.default.create(function () { - return _this.clearLengthCache(); - }, '15fps'); + /** + * Updates the corner overlay position + */ - this.instance.addHook('skipLengthCache', function (delay) { - return _this.onSkipLengthCache(delay); - }); - this.onSkipLengthCache(500); -} + }, { + key: 'resetFixedPosition', + value: function resetFixedPosition() { + this.updateTrimmingContainer(); -DataMap.prototype.DESTINATION_RENDERER = 1; -DataMap.prototype.DESTINATION_CLIPBOARD_GENERATOR = 2; + if (!this.wot.wtTable.holder.parentNode) { + // removed from DOM + return; + } + var overlayRoot = this.clone.wtTable.holder.parentNode; + var tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE); + var tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE); + var preventOverflow = this.wot.getSetting('preventOverflow'); -/** - * @param {Object|Array} object - * @returns {Object|Array} - */ -DataMap.prototype.recursiveDuckSchema = function (object) { - return (0, _object.duckSchema)(object); -}; + if (this.trimmingContainer === window) { + var box = this.wot.wtTable.hider.getBoundingClientRect(); + var top = Math.ceil(box.top); + var left = Math.ceil(box.left); + var bottom = Math.ceil(box.bottom); + var right = Math.ceil(box.right); + var finalLeft = '0'; + var finalTop = '0'; -/** - * @param {Object} schema - * @param {Number} lastCol - * @param {Number} parent - * @returns {Number} - */ -DataMap.prototype.recursiveDuckColumns = function (schema, lastCol, parent) { - var prop, i; - if (typeof lastCol === 'undefined') { - lastCol = 0; - parent = ''; - } - if ((typeof schema === 'undefined' ? 'undefined' : _typeof(schema)) === 'object' && !Array.isArray(schema)) { - for (i in schema) { - if ((0, _object.hasOwnProperty)(schema, i)) { - if (schema[i] === null) { - prop = parent + i; - this.colToPropCache.push(prop); - this.propToColCache.set(prop, lastCol); + if (!preventOverflow || preventOverflow === 'vertical') { + if (left < 0 && right - overlayRoot.offsetWidth > 0) { + finalLeft = -left + 'px'; + } + } - lastCol++; - } else { - lastCol = this.recursiveDuckColumns(schema[i], lastCol, i + '.'); + if (!preventOverflow || preventOverflow === 'horizontal') { + if (top < 0 && bottom - overlayRoot.offsetHeight > 0) { + finalTop = -top + 'px'; + } } + (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop); + } else { + (0, _element.resetCssTransform)(overlayRoot); } + overlayRoot.style.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px'; + overlayRoot.style.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px'; } - } - - return lastCol; -}; + }]); -DataMap.prototype.createMap = function () { - var i = void 0; - var schema = this.getSchema(); + return TopLeftCornerOverlay; +}(_base2.default); - if (typeof schema === 'undefined') { - throw new Error('trying to create `columns` definition but you didn\'t provide `schema` nor `data`'); - } +_base2.default.registerOverlay(_base2.default.CLONE_TOP_LEFT_CORNER, TopLeftCornerOverlay); - this.colToPropCache = []; - this.propToColCache = new _multiMap2.default(); +exports.default = TopLeftCornerOverlay; - var columns = this.instance.getSettings().columns; +/***/ }), +/* 209 */ +/***/ (function(module, exports, __webpack_require__) { - if (columns) { - var maxCols = this.instance.getSettings().maxCols; - var columnsLen = Math.min(maxCols, columns.length); - var filteredIndex = 0; - var columnsAsFunc = false; - var schemaLen = (0, _object.deepObjectSize)(schema); +"use strict"; - if (typeof columns === 'function') { - columnsLen = schemaLen > 0 ? schemaLen : this.instance.countSourceCols(); - columnsAsFunc = true; - } - for (i = 0; i < columnsLen; i++) { - var column = columnsAsFunc ? columns(i) : columns[i]; +exports.__esModule = true; - if ((0, _object.isObject)(column)) { - if (typeof column.data !== 'undefined') { - var index = columnsAsFunc ? filteredIndex : i; - this.colToPropCache[index] = column.data; - this.propToColCache.set(column.data, index); - } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - filteredIndex++; - } - } - } else { - this.recursiveDuckColumns(schema); - } -}; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -/** - * Returns property name that corresponds with the given column index. - * - * @param {Number} col Visual column index. - * @returns {Number} Physical column index. - */ -DataMap.prototype.colToProp = function (col) { - col = this.instance.runHooks('modifyCol', col); +var _element = __webpack_require__(0); - if (!isNaN(col) && this.colToPropCache && typeof this.colToPropCache[col] !== 'undefined') { - return this.colToPropCache[col]; - } +var _border2 = __webpack_require__(167); - return col; -}; +var _border3 = _interopRequireDefault(_border2); -/** - * @param {Object} prop - * @fires Hooks#modifyCol - * @returns {*} - */ -DataMap.prototype.propToCol = function (prop) { - var col; +var _coords = __webpack_require__(49); - if (typeof this.propToColCache.get(prop) === 'undefined') { - col = prop; - } else { - col = this.propToColCache.get(prop); - } - col = this.instance.runHooks('unmodifyCol', col); +var _coords2 = _interopRequireDefault(_coords); - return col; -}; +var _range = __webpack_require__(79); -/** - * @returns {Object} - */ -DataMap.prototype.getSchema = function () { - var schema = this.instance.getSettings().dataSchema; +var _range2 = _interopRequireDefault(_range); - if (schema) { - if (typeof schema === 'function') { - return schema(); - } - return schema; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return this.duckSchema; -}; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * Creates row at the bottom of the data array. - * - * @param {Number} [index] Physical index of the row before which the new row will be inserted. - * @param {Number} [amount] An amount of rows to add. - * @param {String} [source] Source of method call. - * @fires Hooks#afterCreateRow - * @returns {Number} Returns number of created rows. + * @class Selection */ -DataMap.prototype.createRow = function (index, amount, source) { - var row, - colCount = this.instance.countCols(), - numberOfCreatedRows = 0, - currentIndex; +var Selection = function () { + /** + * @param {Object} settings + * @param {CellRange} cellRange + */ + function Selection(settings, cellRange) { + _classCallCheck(this, Selection); - if (!amount) { - amount = 1; + this.settings = settings; + this.cellRange = cellRange || null; + this.instanceBorders = {}; } - if (typeof index !== 'number' || index >= this.instance.countSourceRows()) { - index = this.instance.countSourceRows(); - } - this.instance.runHooks('beforeCreateRow', index, amount, source); + /** + * Each Walkontable clone requires it's own border for every selection. This method creates and returns selection + * borders per instance + * + * @param {Walkontable} wotInstance + * @returns {Border} + */ - currentIndex = index; - var maxRows = this.instance.getSettings().maxRows; - while (numberOfCreatedRows < amount && this.instance.countSourceRows() < maxRows) { - if (this.instance.dataType === 'array') { - if (this.instance.getSettings().dataSchema) { - // Clone template array - row = (0, _object.deepClone)(this.getSchema()); - } else { - row = []; - /* eslint-disable no-loop-func */ - (0, _number.rangeEach)(colCount - 1, function () { - return row.push(null); - }); + _createClass(Selection, [{ + key: 'getBorder', + value: function getBorder(wotInstance) { + if (this.instanceBorders[wotInstance.guid]) { + return this.instanceBorders[wotInstance.guid]; } - } else if (this.instance.dataType === 'function') { - row = this.instance.getSettings().dataSchema(index); - } else { - row = {}; - (0, _object.deepExtend)(row, this.getSchema()); - } - if (index === this.instance.countSourceRows()) { - this.dataSource.push(row); - } else { - this.spliceData(index, 0, row); + // where is this returned? + this.instanceBorders[wotInstance.guid] = new _border3.default(wotInstance, this.settings); } - numberOfCreatedRows++; - currentIndex++; - } - - this.instance.runHooks('afterCreateRow', index, numberOfCreatedRows, source); - this.instance.forceFullRender = true; // used when data was changed + /** + * Checks if selection is empty + * + * @returns {Boolean} + */ - return numberOfCreatedRows; -}; + }, { + key: 'isEmpty', + value: function isEmpty() { + return this.cellRange === null; + } -/** - * Creates col at the right of the data array. - * - * @param {Number} [index] Visual index of the column before which the new column will be inserted - * @param {Number} [amount] An amount of columns to add. - * @param {String} [source] Source of method call. - * @fires Hooks#afterCreateCol - * @returns {Number} Returns number of created columns - */ -DataMap.prototype.createCol = function (index, amount, source) { - if (!this.instance.isColumnModificationAllowed()) { - throw new Error('Cannot create new column. When data source in an object, ' + 'you can only have as much columns as defined in first data row, data schema or in the \'columns\' setting.' + 'If you want to be able to add new columns, you have to use array datasource.'); - } - var rlen = this.instance.countSourceRows(), - data = this.dataSource, - constructor, - numberOfCreatedCols = 0, - currentIndex; + /** + * Adds a cell coords to the selection + * + * @param {CellCoords} coords + */ - if (!amount) { - amount = 1; - } + }, { + key: 'add', + value: function add(coords) { + if (this.isEmpty()) { + this.cellRange = new _range2.default(coords, coords, coords); + } else { + this.cellRange.expand(coords); + } + } - if (typeof index !== 'number' || index >= this.instance.countCols()) { - index = this.instance.countCols(); - } - this.instance.runHooks('beforeCreateCol', index, amount, source); + /** + * If selection range from or to property equals oldCoords, replace it with newCoords. Return boolean + * information about success + * + * @param {CellCoords} oldCoords + * @param {CellCoords} newCoords + * @returns {Boolean} + */ - currentIndex = index; + }, { + key: 'replace', + value: function replace(oldCoords, newCoords) { + if (!this.isEmpty()) { + if (this.cellRange.from.isEqual(oldCoords)) { + this.cellRange.from = newCoords; - var maxCols = this.instance.getSettings().maxCols; - while (numberOfCreatedCols < amount && this.instance.countCols() < maxCols) { - constructor = (0, _setting.columnFactory)(this.GridSettings, this.priv.columnsSettingConflicts); + return true; + } + if (this.cellRange.to.isEqual(oldCoords)) { + this.cellRange.to = newCoords; - if (typeof index !== 'number' || index >= this.instance.countCols()) { - if (rlen > 0) { - for (var r = 0; r < rlen; r++) { - if (typeof data[r] === 'undefined') { - data[r] = []; - } - data[r].push(null); + return true; } - } else { - data.push([null]); - } - // Add new column constructor - this.priv.columnSettings.push(constructor); - } else { - for (var _r = 0; _r < rlen; _r++) { - data[_r].splice(currentIndex, 0, null); } - // Add new column constructor at given index - this.priv.columnSettings.splice(currentIndex, 0, constructor); + + return false; } - numberOfCreatedCols++; - currentIndex++; - } + /** + * Clears selection + */ - this.instance.runHooks('afterCreateCol', index, numberOfCreatedCols, source); - this.instance.forceFullRender = true; // used when data was changed + }, { + key: 'clear', + value: function clear() { + this.cellRange = null; + } - return numberOfCreatedCols; -}; + /** + * Returns the top left (TL) and bottom right (BR) selection coordinates + * + * @returns {Array} Returns array of coordinates for example `[1, 1, 5, 5]` + */ -/** - * Removes row from the data array. - * - * @param {Number} [index] Visual index of the row to be removed. If not provided, the last row will be removed - * @param {Number} [amount] Amount of the rows to be removed. If not provided, one row will be removed - * @param {String} [source] Source of method call. - * @fires Hooks#beforeRemoveRow - * @fires Hooks#afterRemoveRow - */ -DataMap.prototype.removeRow = function (index, amount, source) { - if (!amount) { - amount = 1; - } - if (typeof index !== 'number') { - index = -amount; - } + }, { + key: 'getCorners', + value: function getCorners() { + var topLeft = this.cellRange.getTopLeftCorner(); + var bottomRight = this.cellRange.getBottomRightCorner(); - amount = this.instance.runHooks('modifyRemovedAmount', amount, index); + return [topLeft.row, topLeft.col, bottomRight.row, bottomRight.col]; + } - index = (this.instance.countSourceRows() + index) % this.instance.countSourceRows(); + /** + * Adds class name to cell element at given coords + * + * @param {Walkontable} wotInstance Walkontable instance + * @param {Number} sourceRow Cell row coord + * @param {Number} sourceColumn Cell column coord + * @param {String} className Class name + */ - var logicRows = this.visualRowsToPhysical(index, amount); - var actionWasNotCancelled = this.instance.runHooks('beforeRemoveRow', index, amount, logicRows, source); + }, { + key: 'addClassAtCoords', + value: function addClassAtCoords(wotInstance, sourceRow, sourceColumn, className) { + var TD = wotInstance.wtTable.getCell(new _coords2.default(sourceRow, sourceColumn)); - if (actionWasNotCancelled === false) { - return; - } + if ((typeof TD === 'undefined' ? 'undefined' : _typeof(TD)) === 'object') { + (0, _element.addClass)(TD, className); + } + } - var data = this.dataSource; - var newData = void 0; + /** + * @param wotInstance + */ - newData = this.filterData(index, amount); + }, { + key: 'draw', + value: function draw(wotInstance) { + if (this.isEmpty()) { + if (this.settings.border) { + var border = this.getBorder(wotInstance); - if (newData) { - data.length = 0; - Array.prototype.push.apply(data, newData); - } + if (border) { + border.disappear(); + } + } - this.instance.runHooks('afterRemoveRow', index, amount, logicRows, source); + return; + } + var renderedRows = wotInstance.wtTable.getRenderedRowsCount(); + var renderedColumns = wotInstance.wtTable.getRenderedColumnsCount(); + var corners = this.getCorners(); + var sourceRow = void 0, + sourceCol = void 0, + TH = void 0; - this.instance.forceFullRender = true; // used when data was changed -}; + for (var column = 0; column < renderedColumns; column++) { + sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(column); -/** - * Removes column from the data array. - * - * @param {Number} [index] Visual index of the column to be removed. If not provided, the last column will be removed - * @param {Number} [amount] Amount of the columns to be removed. If not provided, one column will be removed - * @param {String} [source] Source of method call. - * @fires Hooks#beforeRemoveCol - * @fires Hooks#afterRemoveCol - */ -DataMap.prototype.removeCol = function (index, amount, source) { - if (this.instance.dataType === 'object' || this.instance.getSettings().columns) { - throw new Error('cannot remove column with object data source or columns option specified'); - } - if (!amount) { - amount = 1; - } - if (typeof index !== 'number') { - index = -amount; - } + if (sourceCol >= corners[1] && sourceCol <= corners[3]) { + TH = wotInstance.wtTable.getColumnHeader(sourceCol); - index = (this.instance.countCols() + index) % this.instance.countCols(); + if (TH) { + var newClasses = []; - var logicColumns = this.visualColumnsToPhysical(index, amount); - var descendingLogicColumns = logicColumns.slice(0).sort(function (a, b) { - return b - a; - }); - var actionWasNotCancelled = this.instance.runHooks('beforeRemoveCol', index, amount, logicColumns, source); + if (this.settings.highlightHeaderClassName) { + newClasses.push(this.settings.highlightHeaderClassName); + } - if (actionWasNotCancelled === false) { - return; - } + if (this.settings.highlightColumnClassName) { + newClasses.push(this.settings.highlightColumnClassName); + } - var isTableUniform = true; - var removedColumnsCount = descendingLogicColumns.length; - var data = this.dataSource; + (0, _element.addClass)(TH, newClasses); + } + } + } - for (var c = 0; c < removedColumnsCount; c++) { - if (isTableUniform && logicColumns[0] !== logicColumns[c] - c) { - isTableUniform = false; - } - } + for (var row = 0; row < renderedRows; row++) { + sourceRow = wotInstance.wtTable.rowFilter.renderedToSource(row); - if (isTableUniform) { - for (var r = 0, rlen = this.instance.countSourceRows(); r < rlen; r++) { - data[r].splice(logicColumns[0], amount); - } - } else { - for (var _r2 = 0, _rlen = this.instance.countSourceRows(); _r2 < _rlen; _r2++) { - for (var _c = 0; _c < removedColumnsCount; _c++) { - data[_r2].splice(descendingLogicColumns[_c], 1); - } - } + if (sourceRow >= corners[0] && sourceRow <= corners[2]) { + TH = wotInstance.wtTable.getRowHeader(sourceRow); - for (var _c2 = 0; _c2 < removedColumnsCount; _c2++) { - this.priv.columnSettings.splice(logicColumns[_c2], 1); - } - } + if (TH) { + var _newClasses = []; - this.instance.runHooks('afterRemoveCol', index, amount, logicColumns, source); + if (this.settings.highlightHeaderClassName) { + _newClasses.push(this.settings.highlightHeaderClassName); + } - this.instance.forceFullRender = true; // used when data was changed -}; + if (this.settings.highlightRowClassName) { + _newClasses.push(this.settings.highlightRowClassName); + } -/** - * Add/Removes data from the column. - * - * @param {Number} col Physical index of column in which do you want to do splice - * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end - * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed - * @returns {Array} Returns removed portion of columns - */ -DataMap.prototype.spliceCol = function (col, index, amount /* , elements... */) { - var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : []; + (0, _element.addClass)(TH, _newClasses); + } + } - var colData = this.instance.getDataAtCol(col); - var removed = colData.slice(index, index + amount); - var after = colData.slice(index + amount); + for (var _column = 0; _column < renderedColumns; _column++) { + sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(_column); - (0, _array.extendArray)(elements, after); - var i = 0; - while (i < amount) { - elements.push(null); // add null in place of removed elements - i++; - } - (0, _array.to2dArray)(elements); - this.instance.populateFromArray(index, col, elements, null, null, 'spliceCol'); + if (sourceRow >= corners[0] && sourceRow <= corners[2] && sourceCol >= corners[1] && sourceCol <= corners[3]) { + // selected cell + if (this.settings.className) { + this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.className); + } + } else if (sourceRow >= corners[0] && sourceRow <= corners[2]) { + // selection is in this row + if (this.settings.highlightRowClassName) { + this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightRowClassName); + } + } else if (sourceCol >= corners[1] && sourceCol <= corners[3]) { + // selection is in this column + if (this.settings.highlightColumnClassName) { + this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightColumnClassName); + } + } + } + } + wotInstance.getSetting('onBeforeDrawBorders', corners, this.settings.className); - return removed; -}; + if (this.settings.border) { + var _border = this.getBorder(wotInstance); -/** - * Add/Removes data from the row. - * - * @param {Number} row Physical index of row in which do you want to do splice - * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end. - * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed. - * @returns {Array} Returns removed portion of rows - */ -DataMap.prototype.spliceRow = function (row, index, amount /* , elements... */) { - var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : []; + if (_border) { + // warning! border.appear modifies corners! + _border.appear(corners); + } + } + } + }]); - var rowData = this.instance.getSourceDataAtRow(row); - var removed = rowData.slice(index, index + amount); - var after = rowData.slice(index + amount); + return Selection; +}(); - (0, _array.extendArray)(elements, after); - var i = 0; - while (i < amount) { - elements.push(null); // add null in place of removed elements - i++; - } - this.instance.populateFromArray(row, index, [elements], null, null, 'spliceRow'); +exports.default = Selection; - return removed; -}; +/***/ }), +/* 210 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Add/remove row(s) to/from the data source. - * - * @param {Number} index Physical index of the element to remove. - * @param {Number} amount Number of rows to add/remove. - * @param {Object} element Row to add. - */ -DataMap.prototype.spliceData = function (index, amount, element) { - var continueSplicing = this.instance.runHooks('beforeDataSplice', index, amount, element); +"use strict"; - if (continueSplicing !== false) { - this.dataSource.splice(index, amount, element); - } -}; /** - * Filter unwanted data elements from the data source. + * autoResize - resizes a DOM element to the width and height of another DOM element * - * @param {Number} index Visual index of the element to remove. - * @param {Number} amount Number of rows to add/remove. - * @returns {Array} + * Copyright 2014, Marcin Warpechowski + * Licensed under the MIT license */ -DataMap.prototype.filterData = function (index, amount) { - var physicalRows = this.visualRowsToPhysical(index, amount); - var continueSplicing = this.instance.runHooks('beforeDataFilter', index, amount, physicalRows); - if (continueSplicing !== false) { - var newData = this.dataSource.filter(function (row, index) { - return physicalRows.indexOf(index) == -1; - }); +function autoResize() { + var defaults = { + minHeight: 200, + maxHeight: 300, + minWidth: 100, + maxWidth: 300 + }, + el, + body = document.body, + text = document.createTextNode(''), + span = document.createElement('SPAN'), + observe = function observe(element, event, handler) { + if (element.attachEvent) { + element.attachEvent('on' + event, handler); + } else { + element.addEventListener(event, handler, false); + } + }, + _unObserve = function _unObserve(element, event, handler) { + if (element.removeEventListener) { + element.removeEventListener(event, handler, false); + } else { + element.detachEvent('on' + event, handler); + } + }, + resize = function resize(newChar) { + var width, scrollHeight; - return newData; - } -}; + if (!newChar) { + newChar = ""; + } else if (!/^[a-zA-Z \.,\\\/\|0-9]$/.test(newChar)) { + newChar = "."; + } -/** - * Returns single value from the data array. - * - * @param {Number} row Visual row index. - * @param {Number} prop - */ -DataMap.prototype.get = function (row, prop) { - row = this.instance.runHooks('modifyRow', row); + if (text.textContent !== void 0) { + text.textContent = el.value + newChar; + } else { + text.data = el.value + newChar; //IE8 + } + span.style.fontSize = getComputedStyle(el).fontSize; + span.style.fontFamily = getComputedStyle(el).fontFamily; + span.style.whiteSpace = "pre"; - var dataRow = this.dataSource[row]; - // TODO: To remove, use 'modifyData' hook instead (see below) - var modifiedRowData = this.instance.runHooks('modifyRowData', row); + body.appendChild(span); + width = span.clientWidth + 2; + body.removeChild(span); - dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow; - // + el.style.height = defaults.minHeight + 'px'; - var value = null; + if (defaults.minWidth > width) { + el.style.width = defaults.minWidth + 'px'; + } else if (width > defaults.maxWidth) { + el.style.width = defaults.maxWidth + 'px'; + } else { + el.style.width = width + 'px'; + } + scrollHeight = el.scrollHeight ? el.scrollHeight - 1 : 0; - // try to get value under property `prop` (includes dot) - if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) { - value = dataRow[prop]; - } else if (typeof prop === 'string' && prop.indexOf('.') > -1) { - var sliced = prop.split('.'); - var out = dataRow; + if (defaults.minHeight > scrollHeight) { + el.style.height = defaults.minHeight + 'px'; + } else if (defaults.maxHeight < scrollHeight) { + el.style.height = defaults.maxHeight + 'px'; + el.style.overflowY = 'visible'; + } else { + el.style.height = scrollHeight + 'px'; + } + }, + delayedResize = function delayedResize() { + window.setTimeout(resize, 0); + }, + extendDefaults = function extendDefaults(config) { - if (!out) { - return null; + if (config && config.minHeight) { + if (config.minHeight == 'inherit') { + defaults.minHeight = el.clientHeight; + } else { + var minHeight = parseInt(config.minHeight); + if (!isNaN(minHeight)) { + defaults.minHeight = minHeight; + } + } } - for (var i = 0, ilen = sliced.length; i < ilen; i++) { - out = out[sliced[i]]; - if (typeof out === 'undefined') { - return null; + if (config && config.maxHeight) { + if (config.maxHeight == 'inherit') { + defaults.maxHeight = el.clientHeight; + } else { + var maxHeight = parseInt(config.maxHeight); + if (!isNaN(maxHeight)) { + defaults.maxHeight = maxHeight; + } } } - value = out; - } else if (typeof prop === 'function') { - /** - * allows for interacting with complex structures, for example - * d3/jQuery getter/setter properties: - * - * {columns: [{ - * data: function(row, value){ - * if(arguments.length === 1){ - * return row.property(); - * } - * row.property(value); - * } - * }]} - */ - value = prop(this.dataSource.slice(row, row + 1)[0]); - } - if (this.instance.hasHook('modifyData')) { - var valueHolder = (0, _object.createObjectPropListener)(value); + if (config && config.minWidth) { + if (config.minWidth == 'inherit') { + defaults.minWidth = el.clientWidth; + } else { + var minWidth = parseInt(config.minWidth); + if (!isNaN(minWidth)) { + defaults.minWidth = minWidth; + } + } + } - this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'get'); + if (config && config.maxWidth) { + if (config.maxWidth == 'inherit') { + defaults.maxWidth = el.clientWidth; + } else { + var maxWidth = parseInt(config.maxWidth); + if (!isNaN(maxWidth)) { + defaults.maxWidth = maxWidth; + } + } + } - if (valueHolder.isTouched()) { - value = valueHolder.value; + if (!span.firstChild) { + span.className = "autoResize"; + span.style.display = 'inline-block'; + span.appendChild(text); + } + }, + _init = function _init(el_, config, doObserve) { + el = el_; + extendDefaults(config); + + if (el.nodeName == 'TEXTAREA') { + + el.style.resize = 'none'; + el.style.overflowY = ''; + el.style.height = defaults.minHeight + 'px'; + el.style.minWidth = defaults.minWidth + 'px'; + el.style.maxWidth = defaults.maxWidth + 'px'; + el.style.overflowY = 'hidden'; + } + + if (doObserve) { + observe(el, 'change', resize); + observe(el, 'cut', delayedResize); + observe(el, 'paste', delayedResize); + observe(el, 'drop', delayedResize); + observe(el, 'keydown', delayedResize); + observe(el, 'focus', resize); } + + resize(); + }; + + function getComputedStyle(element) { + return element.currentStyle || document.defaultView.getComputedStyle(element); } - return value; -}; - -var copyableLookup = (0, _data.cellMethodLookupFactory)('copyable', false); + return { + init: function init(el_, config, doObserve) { + _init(el_, config, doObserve); + }, + unObserve: function unObserve() { + _unObserve(el, 'change', resize); + _unObserve(el, 'cut', delayedResize); + _unObserve(el, 'paste', delayedResize); + _unObserve(el, 'drop', delayedResize); + _unObserve(el, 'keydown', delayedResize); + _unObserve(el, 'focus', resize); + }, + resize: resize + }; +} -/** - * Returns single value from the data array (intended for clipboard copy to an external application). - * - * @param {Number} row Physical row index. - * @param {Number} prop - * @returns {String} - */ -DataMap.prototype.getCopyable = function (row, prop) { - if (copyableLookup.call(this.instance, row, this.propToCol(prop))) { - return this.get(row, prop); - } - return ''; -}; +if (true) { + module.exports = autoResize; +} -/** - * Saves single value to the data array. - * - * @param {Number} row Visual row index. - * @param {Number} prop - * @param {String} value - * @param {String} [source] Source of hook runner. - */ -DataMap.prototype.set = function (row, prop, value, source) { - row = this.instance.runHooks('modifyRow', row, source || 'datamapGet'); +/***/ }), +/* 211 */ +/***/ (function(module, exports, __webpack_require__) { - var dataRow = this.dataSource[row]; - // TODO: To remove, use 'modifyData' hook instead (see below) - var modifiedRowData = this.instance.runHooks('modifyRowData', row); +"use strict"; - dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow; - // - if (this.instance.hasHook('modifyData')) { - var valueHolder = (0, _object.createObjectPropListener)(value); +exports.__esModule = true; - this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'set'); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (valueHolder.isTouched()) { - value = valueHolder.value; - } - } +var _baseEditor = __webpack_require__(41); - // try to set value under property `prop` (includes dot) - if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) { - dataRow[prop] = value; - } else if (typeof prop === 'string' && prop.indexOf('.') > -1) { - var sliced = prop.split('.'); - var out = dataRow; - var i = 0; - var ilen = void 0; +var _baseEditor2 = _interopRequireDefault(_baseEditor); - for (i = 0, ilen = sliced.length - 1; i < ilen; i++) { - if (typeof out[sliced[i]] === 'undefined') { - out[sliced[i]] = {}; - } - out = out[sliced[i]]; - } - out[sliced[i]] = value; - } else if (typeof prop === 'function') { - /* see the `function` handler in `get` */ - prop(this.dataSource.slice(row, row + 1)[0], value); - } else { - dataRow[prop] = value; - } -}; +var _element = __webpack_require__(0); -/** - * This ridiculous piece of code maps rows Id that are present in table data to those displayed for user. - * The trick is, the physical row id (stored in settings.data) is not necessary the same - * as the visual (displayed) row id (e.g. when sorting is applied). - * - * @param {Number} index Visual row index. - * @param {Number} amount - * @fires Hooks#modifyRow - * @returns {Number} - */ -DataMap.prototype.visualRowsToPhysical = function (index, amount) { - var totalRows = this.instance.countSourceRows(); - var physicRow = (totalRows + index) % totalRows; - var logicRows = []; - var rowsToRemove = amount; - var row; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - while (physicRow < totalRows && rowsToRemove) { - row = this.instance.runHooks('modifyRow', physicRow); - logicRows.push(row); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - rowsToRemove--; - physicRow++; - } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - return logicRows; -}; +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** - * - * @param index Visual column index. - * @param amount - * @returns {Array} + * @private + * @editor CheckboxEditor + * @class CheckboxEditor */ -DataMap.prototype.visualColumnsToPhysical = function (index, amount) { - var totalCols = this.instance.countCols(); - var physicalCol = (totalCols + index) % totalCols; - var visualCols = []; - var colsToRemove = amount; - - while (physicalCol < totalCols && colsToRemove) { - var col = this.instance.runHooks('modifyCol', physicalCol); +var CheckboxEditor = function (_BaseEditor) { + _inherits(CheckboxEditor, _BaseEditor); - visualCols.push(col); + function CheckboxEditor() { + _classCallCheck(this, CheckboxEditor); - colsToRemove--; - physicalCol++; + return _possibleConstructorReturn(this, (CheckboxEditor.__proto__ || Object.getPrototypeOf(CheckboxEditor)).apply(this, arguments)); } - return visualCols; -}; + _createClass(CheckboxEditor, [{ + key: 'beginEditing', + value: function beginEditing(initialValue, event) { + // editorManager return double click event as undefined + if (event === void 0) { + var checkbox = this.TD.querySelector('input[type="checkbox"]'); -/** - * Clears the data array. - */ -DataMap.prototype.clear = function () { - for (var r = 0; r < this.instance.countSourceRows(); r++) { - for (var c = 0; c < this.instance.countCols(); c++) { - this.set(r, this.colToProp(c), ''); + if (!(0, _element.hasClass)(checkbox, 'htBadValue')) { + checkbox.click(); + } + } } - } -}; + }, { + key: 'finishEditing', + value: function finishEditing() {} + }, { + key: 'init', + value: function init() {} + }, { + key: 'open', + value: function open() {} + }, { + key: 'close', + value: function close() {} + }, { + key: 'getValue', + value: function getValue() {} + }, { + key: 'setValue', + value: function setValue() {} + }, { + key: 'focus', + value: function focus() {} + }]); -/** - * Clear cached data length. - */ -DataMap.prototype.clearLengthCache = function () { - this.cachedLength = null; -}; + return CheckboxEditor; +}(_baseEditor2.default); -/** - * Get data length. - * - * @returns {Number} - */ -DataMap.prototype.getLength = function () { - var _this2 = this; +exports.default = CheckboxEditor; - var maxRows = void 0, - maxRowsFromSettings = this.instance.getSettings().maxRows; +/***/ }), +/* 212 */ +/***/ (function(module, exports, __webpack_require__) { - if (maxRowsFromSettings < 0 || maxRowsFromSettings === 0) { - maxRows = 0; - } else { - maxRows = maxRowsFromSettings || Infinity; - } +"use strict"; - var length = this.instance.countSourceRows(); - if (this.instance.hasHook('modifyRow')) { - var reValidate = this.skipCache; +exports.__esModule = true; - this.interval.start(); - if (length !== this.latestSourceRowsCount) { - reValidate = true; - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - this.latestSourceRowsCount = length; - if (this.cachedLength === null || reValidate) { - (0, _number.rangeEach)(length - 1, function (row) { - row = _this2.instance.runHooks('modifyRow', row); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - if (row === null) { - --length; - } - }); - this.cachedLength = length; - } else { - length = this.cachedLength; - } - } else { - this.interval.stop(); - } +var _moment = __webpack_require__(63); - return Math.min(length, maxRows); -}; +var _moment2 = _interopRequireDefault(_moment); -/** - * Returns the data array. - * - * @returns {Array} - */ -DataMap.prototype.getAll = function () { - var start = { - row: 0, - col: 0 - }; +var _pikaday = __webpack_require__(213); - var end = { - row: Math.max(this.instance.countSourceRows() - 1, 0), - col: Math.max(this.instance.countCols() - 1, 0) - }; +var _pikaday2 = _interopRequireDefault(_pikaday); - if (start.row - end.row === 0 && !this.instance.countSourceRows()) { - return []; - } +__webpack_require__(214); - return this.getRange(start, end, DataMap.prototype.DESTINATION_RENDERER); -}; +var _element = __webpack_require__(0); -/** - * Returns data range as array. - * - * @param {Object} [start] Start selection position. Visual indexes. - * @param {Object} [end] End selection position. Visual indexes. - * @param {Number} destination Destination of datamap.get - * @returns {Array} - */ -DataMap.prototype.getRange = function (start, end, destination) { - var r, - rlen, - c, - clen, - output = [], - row; +var _object = __webpack_require__(1); - var maxRows = this.instance.getSettings().maxRows; - var maxCols = this.instance.getSettings().maxCols; +var _eventManager = __webpack_require__(4); - if (maxRows === 0 || maxCols === 0) { - return []; - } +var _eventManager2 = _interopRequireDefault(_eventManager); - var getFn = destination === this.DESTINATION_CLIPBOARD_GENERATOR ? this.getCopyable : this.get; +var _unicode = __webpack_require__(17); - rlen = Math.min(Math.max(maxRows - 1, 0), Math.max(start.row, end.row)); - clen = Math.min(Math.max(maxCols - 1, 0), Math.max(start.col, end.col)); +var _event = __webpack_require__(8); - for (r = Math.min(start.row, end.row); r <= rlen; r++) { - row = []; - var physicalRow = this.instance.runHooks('modifyRow', r); +var _textEditor = __webpack_require__(50); - for (c = Math.min(start.col, end.col); c <= clen; c++) { +var _textEditor2 = _interopRequireDefault(_textEditor); - if (physicalRow === null) { - break; - } - row.push(getFn.call(this, r, this.colToProp(c))); - } - if (physicalRow !== null) { - output.push(row); - } - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return output; -}; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -/** - * Return data as text (tab separated columns). - * - * @param {Object} [start] Start selection position. Visual indexes. - * @param {Object} [end] End selection position. Visual indexes. - * @returns {String} - */ -DataMap.prototype.getText = function (start, end) { - return _SheetClip2.default.stringify(this.getRange(start, end, this.DESTINATION_RENDERER)); -}; +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } -/** - * Return data as copyable text (tab separated columns intended for clipboard copy to an external application). - * - * @param {Object} [start] Start selection position. Visual indexes. - * @param {Object} [end] End selection position. Visual indexes. - * @returns {String} - */ -DataMap.prototype.getCopyableText = function (start, end) { - return _SheetClip2.default.stringify(this.getRange(start, end, this.DESTINATION_CLIPBOARD_GENERATOR)); -}; +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** - * `skipLengthCache` callback. * @private - * @param {Number} delay Time of the delay in milliseconds. + * @editor DateEditor + * @class DateEditor + * @dependencies TextEditor moment pikaday */ -DataMap.prototype.onSkipLengthCache = function (delay) { - var _this3 = this; - - this.skipCache = true; - setTimeout(function () { - _this3.skipCache = false; - }, delay); -}; +var DateEditor = function (_TextEditor) { + _inherits(DateEditor, _TextEditor); -/** - * Destroy instance. - */ -DataMap.prototype.destroy = function () { - this.interval.stop(); + /** + * @param {Core} hotInstance Handsontable instance + * @private + */ + function DateEditor(hotInstance) { + _classCallCheck(this, DateEditor); - this.interval = null; - this.instance = null; - this.priv = null; - this.GridSettings = null; - this.dataSource = null; - this.cachedLength = null; - this.duckSchema = null; -}; + // TODO: Move this option to general settings + var _this = _possibleConstructorReturn(this, (DateEditor.__proto__ || Object.getPrototypeOf(DateEditor)).call(this, hotInstance)); -exports.default = DataMap; + _this.defaultDateFormat = 'DD/MM/YYYY'; + _this.isCellEdited = false; + _this.parentDestroyed = false; + return _this; + } -/***/ }), -/* 200 */ -/***/ (function(module, exports, __webpack_require__) { + _createClass(DateEditor, [{ + key: 'init', + value: function init() { + var _this2 = this; -"use strict"; + if (typeof _moment2.default !== 'function') { + throw new Error('You need to include moment.js to your project.'); + } + if (typeof _pikaday2.default !== 'function') { + throw new Error('You need to include Pikaday to your project.'); + } + _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'init', this).call(this); + this.instance.addHook('afterDestroy', function () { + _this2.parentDestroyed = true; + _this2.destroyElements(); + }); + } -exports.__esModule = true; + /** + * Create data picker instance + */ -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + }, { + key: 'createElements', + value: function createElements() { + _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'createElements', this).call(this); -var _object = __webpack_require__(1); + this.datePicker = document.createElement('DIV'); + this.datePickerStyle = this.datePicker.style; + this.datePickerStyle.position = 'absolute'; + this.datePickerStyle.top = 0; + this.datePickerStyle.left = 0; + this.datePickerStyle.zIndex = 9999; -var _array = __webpack_require__(2); + (0, _element.addClass)(this.datePicker, 'htDatepickerHolder'); + document.body.appendChild(this.datePicker); -var _number = __webpack_require__(6); + this.$datePicker = new _pikaday2.default(this.getDatePickerConfig()); + var eventManager = new _eventManager2.default(this); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** + * Prevent recognizing clicking on datepicker as clicking outside of table + */ + eventManager.addEventListener(this.datePicker, 'mousedown', function (event) { + return (0, _event.stopPropagation)(event); + }); + this.hideDatepicker(); + } -/** - * @class DataSource - * @private - */ -var DataSource = function () { - function DataSource(hotInstance) { - var dataSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + /** + * Destroy data picker instance + */ - _classCallCheck(this, DataSource); + }, { + key: 'destroyElements', + value: function destroyElements() { + this.$datePicker.destroy(); + } /** - * Instance of Handsontable. + * Prepare editor to appear * - * @type {Handsontable} + * @param {Number} row Row index + * @param {Number} col Column index + * @param {String} prop Property name (passed when datasource is an array of objects) + * @param {HTMLTableCellElement} td Table cell element + * @param {*} originalValue Original value + * @param {Object} cellProperties Object with cell properties ({@see Core#getCellMeta}) */ - this.hot = hotInstance; + + }, { + key: 'prepare', + value: function prepare(row, col, prop, td, originalValue, cellProperties) { + this._opened = false; + _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'prepare', this).call(this, row, col, prop, td, originalValue, cellProperties); + } + /** - * Data source + * Open editor * - * @type {Array} + * @param {Event} [event=null] */ - this.data = dataSource; + + }, { + key: 'open', + value: function open() { + var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'open', this).call(this); + this.showDatepicker(event); + } + /** - * Type of data source. - * - * @type {String} - * @default 'array' + * Close editor */ - this.dataType = 'array'; - this.colToProp = function () {}; - this.propToCol = function () {}; - } + }, { + key: 'close', + value: function close() { + var _this3 = this; - /** - * Get all data. - * - * @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided - * in another format. - * @returns {Array} - */ + this._opened = false; + this.instance._registerTimeout(setTimeout(function () { + _this3.instance.selection.refreshBorders(); + }, 0)); + _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'close', this).call(this); + } - _createClass(DataSource, [{ - key: 'getData', - value: function getData() { - var toArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + /** + * @param {Boolean} [isCancelled=false] + * @param {Boolean} [ctrlDown=false] + */ - var result = this.data; + }, { + key: 'finishEditing', + value: function finishEditing() { + var isCancelled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var ctrlDown = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - if (toArray) { - result = this.getByRange({ row: 0, col: 0 }, { row: Math.max(this.countRows() - 1, 0), col: Math.max(this.countColumns() - 1, 0) }, true); - } + if (isCancelled) { + // pressed ESC, restore original value + // var value = this.instance.getDataAtCell(this.row, this.col); + var value = this.originalValue; - return result; + if (value !== void 0) { + this.setValue(value); + } + } + this.hideDatepicker(); + _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'finishEditing', this).call(this, isCancelled, ctrlDown); } /** - * Set new data source. + * Show data picker * - * @param data {Array} + * @param {Event} event */ }, { - key: 'setData', - value: function setData(data) { - this.data = data; - } + key: 'showDatepicker', + value: function showDatepicker(event) { + this.$datePicker.config(this.getDatePickerConfig()); - /** - * Returns array of column values from the data source. `column` is the index of the row in the data source. - * - * @param {Number} column Visual column index. - * @returns {Array} - */ + var offset = this.TD.getBoundingClientRect(); + var dateFormat = this.cellProperties.dateFormat || this.defaultDateFormat; + var datePickerConfig = this.$datePicker.config(); + var dateStr = void 0; + var isMouseDown = this.instance.view.isMouseDown(); + var isMeta = event ? (0, _unicode.isMetaKey)(event.keyCode) : false; - }, { - key: 'getAtColumn', - value: function getAtColumn(column) { - var _this = this; + this.datePickerStyle.top = window.pageYOffset + offset.top + (0, _element.outerHeight)(this.TD) + 'px'; + this.datePickerStyle.left = window.pageXOffset + offset.left + 'px'; - var result = []; + this.$datePicker._onInputFocus = function () {}; + datePickerConfig.format = dateFormat; - (0, _array.arrayEach)(this.data, function (row) { - var property = _this.colToProp(column); + if (this.originalValue) { + dateStr = this.originalValue; - if (typeof property === 'string') { - row = (0, _object.getProperty)(row, property); - } else { - row = row[property]; + if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) { + this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true); } - result.push(row); - }); - return result; + // workaround for date/time cells - pikaday resets the cell value to 12:00 AM by default, this will overwrite the value. + if (this.getValue() !== this.originalValue) { + this.setValue(this.originalValue); + } + + if (!isMeta && !isMouseDown) { + this.setValue(''); + } + } else if (this.cellProperties.defaultDate) { + dateStr = this.cellProperties.defaultDate; + + datePickerConfig.defaultDate = dateStr; + + if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) { + this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true); + } + + if (!isMeta && !isMouseDown) { + this.setValue(''); + } + } else { + // if a default date is not defined, set a soft-default-date: display the current day and month in the + // datepicker, but don't fill the editor input + this.$datePicker.gotoToday(); + } + + this.datePickerStyle.display = 'block'; + this.$datePicker.show(); } /** - * Returns a single row of the data (array or object, depending on what you have). `row` is the index of the row in the data source. - * - * @param {Number} row Physical row index. - * @returns {Array|Object} + * Hide data picker */ }, { - key: 'getAtRow', - value: function getAtRow(row) { - return this.data[row]; + key: 'hideDatepicker', + value: function hideDatepicker() { + this.datePickerStyle.display = 'none'; + this.$datePicker.hide(); } /** - * Returns a single value from the data. + * Get date picker options. * - * @param {Number} row Physical row index. - * @param {Number} column Visual column index. - * @returns {*} + * @returns {Object} */ }, { - key: 'getAtCell', - value: function getAtCell(row, column) { - var result = null; + key: 'getDatePickerConfig', + value: function getDatePickerConfig() { + var _this4 = this; - var modifyRowData = this.hot.runHooks('modifyRowData', row); + var htInput = this.TEXTAREA; + var options = {}; - var dataRow = isNaN(modifyRowData) ? modifyRowData : this.data[row]; + if (this.cellProperties && this.cellProperties.datePickerConfig) { + (0, _object.deepExtend)(options, this.cellProperties.datePickerConfig); + } + var origOnSelect = options.onSelect; + var origOnClose = options.onClose; - if (dataRow) { - var prop = this.colToProp(column); + options.field = htInput; + options.trigger = htInput; + options.container = this.datePicker; + options.bound = false; + options.format = options.format || this.defaultDateFormat; + options.reposition = options.reposition || false; + options.onSelect = function (dateStr) { + if (!isNaN(dateStr.getTime())) { + dateStr = (0, _moment2.default)(dateStr).format(_this4.cellProperties.dateFormat || _this4.defaultDateFormat); + } + _this4.setValue(dateStr); + _this4.hideDatepicker(); - if (typeof prop === 'string') { - result = (0, _object.getProperty)(dataRow, prop); - } else if (typeof prop === 'function') { - result = prop(this.data.slice(row, row + 1)[0]); - } else { - result = dataRow[prop]; + if (origOnSelect) { + origOnSelect(); } - } + }; + options.onClose = function () { + if (!_this4.parentDestroyed) { + _this4.finishEditing(false); + } + if (origOnClose) { + origOnClose(); + } + }; - return result; + return options; } + }]); - /** - * Returns source data by passed range. - * - * @param {Object} start Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects). - * @param {Object} end Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects). - * @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided - * in another format. - * @returns {Array} - */ + return DateEditor; +}(_textEditor2.default); - }, { - key: 'getByRange', - value: function getByRange(start, end) { - var _this2 = this; +exports.default = DateEditor; - var toArray = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; +/***/ }), +/* 213 */ +/***/ (function(module, exports) { - var startRow = Math.min(start.row, end.row); - var startCol = Math.min(start.col, end.col); - var endRow = Math.max(start.row, end.row); - var endCol = Math.max(start.col, end.col); - var result = []; +module.exports = __WEBPACK_EXTERNAL_MODULE_213__; - (0, _number.rangeEach)(startRow, endRow, function (currentRow) { - var row = _this2.getAtRow(currentRow); - var newRow = void 0; +/***/ }), +/* 214 */ +/***/ (function(module, exports) { - if (_this2.dataType === 'array') { - newRow = row.slice(startCol, endCol + 1); - } else if (_this2.dataType === 'object') { - newRow = toArray ? [] : {}; - (0, _number.rangeEach)(startCol, endCol, function (column) { - var prop = _this2.colToProp(column); - if (toArray) { - newRow.push(row[prop]); - } else { - newRow[prop] = row[prop]; - } - }); - } +/***/ }), +/* 215 */ +/***/ (function(module, exports, __webpack_require__) { - result.push(newRow); - }); +"use strict"; - return result; - } - /** - * Count number of rows. - * - * @returns {Number} - */ +exports.__esModule = true; - }, { - key: 'countRows', - value: function countRows() { - return Array.isArray(this.data) ? this.data.length : 0; - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - /** - * Count number of columns. - * - * @returns {Number} - */ +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - }, { - key: 'countColumns', - value: function countColumns() { - var result = 0; +var _autocompleteEditor = __webpack_require__(168); - if (Array.isArray(this.data)) { - if (this.dataType === 'array') { - result = this.data[0].length; - } else if (this.dataType === 'object') { - result = Object.keys(this.data[0]).length; - } - } +var _autocompleteEditor2 = _interopRequireDefault(_autocompleteEditor); - return result; - } +var _pluginHooks = __webpack_require__(7); - /** - * Destroy instance. - */ +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - }, { - key: 'destroy', - value: function destroy() { - this.data = null; - this.hot = null; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/** + * @private + * @editor DropdownEditor + * @class DropdownEditor + * @dependencies AutocompleteEditor + */ +var DropdownEditor = function (_AutocompleteEditor) { + _inherits(DropdownEditor, _AutocompleteEditor); + + function DropdownEditor() { + _classCallCheck(this, DropdownEditor); + + return _possibleConstructorReturn(this, (DropdownEditor.__proto__ || Object.getPrototypeOf(DropdownEditor)).apply(this, arguments)); + } + + _createClass(DropdownEditor, [{ + key: 'prepare', + value: function prepare(row, col, prop, td, originalValue, cellProperties) { + _get(DropdownEditor.prototype.__proto__ || Object.getPrototypeOf(DropdownEditor.prototype), 'prepare', this).call(this, row, col, prop, td, originalValue, cellProperties); + this.cellProperties.filter = false; + this.cellProperties.strict = true; } }]); - return DataSource; -}(); + return DropdownEditor; +}(_autocompleteEditor2.default); -exports.default = DataSource; +_pluginHooks2.default.getSingleton().add('beforeValidate', function (value, row, col, source) { + var cellMeta = this.getCellMeta(row, this.propToCol(col)); + + if (cellMeta.editor === DropdownEditor) { + if (cellMeta.strict === void 0) { + cellMeta.filter = false; + cellMeta.strict = true; + } + } +}); + +exports.default = DropdownEditor; /***/ }), -/* 201 */ +/* 216 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46063,430 +45976,379 @@ exports.default = DataSource; exports.__esModule = true; -var _src = __webpack_require__(11); +var _unicode = __webpack_require__(17); + +var _event = __webpack_require__(8); -var _unicode = __webpack_require__(16); +var _element = __webpack_require__(0); -var _event = __webpack_require__(7); +var _baseEditor = __webpack_require__(41); -var _editors = __webpack_require__(14); +var _baseEditor2 = _interopRequireDefault(_baseEditor); var _eventManager = __webpack_require__(4); var _eventManager2 = _interopRequireDefault(_eventManager); -var _baseEditor = __webpack_require__(36); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function EditorManager(instance, priv, selection) { - var _this = this, - destroyed = false, - eventManager, - activeEditor; +var MobileTextEditor = _baseEditor2.default.prototype.extend(); +var domDimensionsCache = {}; - eventManager = new _eventManager2.default(instance); +/** + * @private + * @editor MobileTextEditor + * @class MobileTextEditor + */ +var createControls = function createControls() { + this.controls = {}; - function moveSelectionAfterEnter(shiftKey) { - selection.setSelectedHeaders(false, false, false); - var enterMoves = typeof priv.settings.enterMoves === 'function' ? priv.settings.enterMoves(event) : priv.settings.enterMoves; + this.controls.leftButton = document.createElement('DIV'); + this.controls.leftButton.className = 'leftButton'; + this.controls.rightButton = document.createElement('DIV'); + this.controls.rightButton.className = 'rightButton'; + this.controls.upButton = document.createElement('DIV'); + this.controls.upButton.className = 'upButton'; + this.controls.downButton = document.createElement('DIV'); + this.controls.downButton.className = 'downButton'; - if (shiftKey) { - // move selection up - selection.transformStart(-enterMoves.row, -enterMoves.col); - } else { - // move selection down (add a new row if needed) - selection.transformStart(enterMoves.row, enterMoves.col, true); + for (var button in this.controls) { + if (Object.prototype.hasOwnProperty.call(this.controls, button)) { + this.positionControls.appendChild(this.controls[button]); } } +}; - function moveSelectionUp(shiftKey) { - if (shiftKey) { - if (selection.selectedHeader.cols) { - selection.setSelectedHeaders(selection.selectedHeader.rows, false, false); - } - selection.transformEnd(-1, 0); - } else { - selection.setSelectedHeaders(false, false, false); - selection.transformStart(-1, 0); - } - } +MobileTextEditor.prototype.valueChanged = function () { + return this.initValue != this.getValue(); +}; - function moveSelectionDown(shiftKey) { - if (shiftKey) { - // expanding selection down with shift - selection.transformEnd(1, 0); - } else { - selection.setSelectedHeaders(false, false, false); - selection.transformStart(1, 0); - } - } +MobileTextEditor.prototype.init = function () { + var that = this; + this.eventManager = new _eventManager2.default(this.instance); - function moveSelectionRight(shiftKey) { - if (shiftKey) { - selection.transformEnd(0, 1); - } else { - selection.setSelectedHeaders(false, false, false); - selection.transformStart(0, 1); - } + this.createElements(); + this.bindEvents(); + + this.instance.addHook('afterDestroy', function () { + that.destroy(); + }); +}; + +MobileTextEditor.prototype.getValue = function () { + return this.TEXTAREA.value; +}; + +MobileTextEditor.prototype.setValue = function (newValue) { + this.initValue = newValue; + + this.TEXTAREA.value = newValue; +}; + +MobileTextEditor.prototype.createElements = function () { + this.editorContainer = document.createElement('DIV'); + this.editorContainer.className = 'htMobileEditorContainer'; + + this.cellPointer = document.createElement('DIV'); + this.cellPointer.className = 'cellPointer'; + + this.moveHandle = document.createElement('DIV'); + this.moveHandle.className = 'moveHandle'; + + this.inputPane = document.createElement('DIV'); + this.inputPane.className = 'inputs'; + + this.positionControls = document.createElement('DIV'); + this.positionControls.className = 'positionControls'; + + this.TEXTAREA = document.createElement('TEXTAREA'); + (0, _element.addClass)(this.TEXTAREA, 'handsontableInput'); + + this.inputPane.appendChild(this.TEXTAREA); + + this.editorContainer.appendChild(this.cellPointer); + this.editorContainer.appendChild(this.moveHandle); + this.editorContainer.appendChild(this.inputPane); + this.editorContainer.appendChild(this.positionControls); + + createControls.call(this); + + document.body.appendChild(this.editorContainer); +}; + +MobileTextEditor.prototype.onBeforeKeyDown = function (event) { + var instance = this; + var that = instance.getActiveEditor(); + + if (event.target !== that.TEXTAREA || (0, _event.isImmediatePropagationStopped)(event)) { + return; } - function moveSelectionLeft(shiftKey) { - if (shiftKey) { - if (selection.selectedHeader.rows) { - selection.setSelectedHeaders(false, selection.selectedHeader.cols, false); - } - selection.transformEnd(0, -1); - } else { - selection.setSelectedHeaders(false, false, false); - selection.transformStart(0, -1); - } + switch (event.keyCode) { + case _unicode.KEY_CODES.ENTER: + that.close(); + event.preventDefault(); // don't add newline to field + break; + case _unicode.KEY_CODES.BACKSPACE: + (0, _event.stopImmediatePropagation)(event); // backspace, delete, home, end should only work locally when cell is edited (not in table context) + break; + default: + break; } +}; - function onKeyDown(event) { - var ctrlDown, rangeModifier; +MobileTextEditor.prototype.open = function () { + this.instance.addHook('beforeKeyDown', this.onBeforeKeyDown); - if (!instance.isListening()) { - return; - } - instance.runHooks('beforeKeyDown', event); + (0, _element.addClass)(this.editorContainer, 'active'); + (0, _element.removeClass)(this.cellPointer, 'hidden'); - if (destroyed) { - return; - } - if ((0, _event.isImmediatePropagationStopped)(event)) { - return; - } - priv.lastKeyCode = event.keyCode; + this.updateEditorPosition(); +}; - if (!selection.isSelected()) { - return; - } - // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL) - ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; +MobileTextEditor.prototype.focus = function () { + this.TEXTAREA.focus(); + (0, _element.setCaretPosition)(this.TEXTAREA, this.TEXTAREA.value.length); +}; - if (activeEditor && !activeEditor.isWaiting()) { - if (!(0, _unicode.isMetaKey)(event.keyCode) && !(0, _unicode.isCtrlKey)(event.keyCode) && !ctrlDown && !_this.isEditorOpened()) { - _this.openEditor('', event); +MobileTextEditor.prototype.close = function () { + this.TEXTAREA.blur(); + this.instance.removeHook('beforeKeyDown', this.onBeforeKeyDown); - return; - } - } - rangeModifier = event.shiftKey ? selection.setRangeEnd : selection.setRangeStart; + (0, _element.removeClass)(this.editorContainer, 'active'); +}; - switch (event.keyCode) { - case _unicode.KEY_CODES.A: - if (!_this.isEditorOpened() && ctrlDown) { - selection.selectAll(); +MobileTextEditor.prototype.scrollToView = function () { + var coords = this.instance.getSelectedRange().highlight; + this.instance.view.scrollViewport(coords); +}; + +MobileTextEditor.prototype.hideCellPointer = function () { + if (!(0, _element.hasClass)(this.cellPointer, 'hidden')) { + (0, _element.addClass)(this.cellPointer, 'hidden'); + } +}; + +MobileTextEditor.prototype.updateEditorPosition = function (x, y) { + if (x && y) { + x = parseInt(x, 10); + y = parseInt(y, 10); + + this.editorContainer.style.top = y + 'px'; + this.editorContainer.style.left = x + 'px'; + } else { + var selection = this.instance.getSelected(), + selectedCell = this.instance.getCell(selection[0], selection[1]); + + // cache sizes + if (!domDimensionsCache.cellPointer) { + domDimensionsCache.cellPointer = { + height: (0, _element.outerHeight)(this.cellPointer), + width: (0, _element.outerWidth)(this.cellPointer) + }; + } + if (!domDimensionsCache.editorContainer) { + domDimensionsCache.editorContainer = { + width: (0, _element.outerWidth)(this.editorContainer) + }; + } - event.preventDefault(); - (0, _event.stopPropagation)(event); - } - break; + if (selectedCell !== undefined) { + var scrollLeft = this.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollLeft)(this.instance.view.wt.wtOverlays.leftOverlay.holder); + var scrollTop = this.instance.view.wt.wtOverlays.topOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollTop)(this.instance.view.wt.wtOverlays.topOverlay.holder); - case _unicode.KEY_CODES.ARROW_UP: - if (_this.isEditorOpened() && !activeEditor.isWaiting()) { - _this.closeEditorAndSaveChanges(ctrlDown); - } - moveSelectionUp(event.shiftKey); + var selectedCellOffset = (0, _element.offset)(selectedCell), + selectedCellWidth = (0, _element.outerWidth)(selectedCell), + currentScrollPosition = { + x: scrollLeft, + y: scrollTop + }; - event.preventDefault(); - (0, _event.stopPropagation)(event); - break; + this.editorContainer.style.top = parseInt(selectedCellOffset.top + (0, _element.outerHeight)(selectedCell) - currentScrollPosition.y + domDimensionsCache.cellPointer.height, 10) + 'px'; + this.editorContainer.style.left = parseInt(window.innerWidth / 2 - domDimensionsCache.editorContainer.width / 2, 10) + 'px'; - case _unicode.KEY_CODES.ARROW_DOWN: - if (_this.isEditorOpened() && !activeEditor.isWaiting()) { - _this.closeEditorAndSaveChanges(ctrlDown); - } + if (selectedCellOffset.left + selectedCellWidth / 2 > parseInt(this.editorContainer.style.left, 10) + domDimensionsCache.editorContainer.width) { + this.editorContainer.style.left = window.innerWidth - domDimensionsCache.editorContainer.width + 'px'; + } else if (selectedCellOffset.left + selectedCellWidth / 2 < parseInt(this.editorContainer.style.left, 10) + 20) { + this.editorContainer.style.left = 0 + 'px'; + } - moveSelectionDown(event.shiftKey); + this.cellPointer.style.left = parseInt(selectedCellOffset.left - domDimensionsCache.cellPointer.width / 2 - (0, _element.offset)(this.editorContainer).left + selectedCellWidth / 2 - currentScrollPosition.x, 10) + 'px'; + } + } +}; - event.preventDefault(); - (0, _event.stopPropagation)(event); - break; +MobileTextEditor.prototype.updateEditorData = function () { + var selected = this.instance.getSelected(), + selectedValue = this.instance.getDataAtCell(selected[0], selected[1]); - case _unicode.KEY_CODES.ARROW_RIGHT: - if (_this.isEditorOpened() && !activeEditor.isWaiting()) { - _this.closeEditorAndSaveChanges(ctrlDown); - } + this.row = selected[0]; + this.col = selected[1]; + this.setValue(selectedValue); + this.updateEditorPosition(); +}; - moveSelectionRight(event.shiftKey); +MobileTextEditor.prototype.prepareAndSave = function () { + var val; - event.preventDefault(); - (0, _event.stopPropagation)(event); - break; + if (!this.valueChanged()) { + return; + } - case _unicode.KEY_CODES.ARROW_LEFT: - if (_this.isEditorOpened() && !activeEditor.isWaiting()) { - _this.closeEditorAndSaveChanges(ctrlDown); - } + if (this.instance.getSettings().trimWhitespace) { + val = [[String.prototype.trim.call(this.getValue())]]; + } else { + val = [[this.getValue()]]; + } - moveSelectionLeft(event.shiftKey); + this.saveValue(val); +}; - event.preventDefault(); - (0, _event.stopPropagation)(event); - break; +MobileTextEditor.prototype.bindEvents = function () { + var that = this; - case _unicode.KEY_CODES.TAB: - selection.setSelectedHeaders(false, false, false); - var tabMoves = typeof priv.settings.tabMoves === 'function' ? priv.settings.tabMoves(event) : priv.settings.tabMoves; + this.eventManager.addEventListener(this.controls.leftButton, 'touchend', function (event) { + that.prepareAndSave(); + that.instance.selection.transformStart(0, -1, null, true); + that.updateEditorData(); + event.preventDefault(); + }); + this.eventManager.addEventListener(this.controls.rightButton, 'touchend', function (event) { + that.prepareAndSave(); + that.instance.selection.transformStart(0, 1, null, true); + that.updateEditorData(); + event.preventDefault(); + }); + this.eventManager.addEventListener(this.controls.upButton, 'touchend', function (event) { + that.prepareAndSave(); + that.instance.selection.transformStart(-1, 0, null, true); + that.updateEditorData(); + event.preventDefault(); + }); + this.eventManager.addEventListener(this.controls.downButton, 'touchend', function (event) { + that.prepareAndSave(); + that.instance.selection.transformStart(1, 0, null, true); + that.updateEditorData(); + event.preventDefault(); + }); - if (event.shiftKey) { - // move selection left - selection.transformStart(-tabMoves.row, -tabMoves.col); - } else { - // move selection right (add a new column if needed) - selection.transformStart(tabMoves.row, tabMoves.col, true); - } - event.preventDefault(); - (0, _event.stopPropagation)(event); - break; + this.eventManager.addEventListener(this.moveHandle, 'touchstart', function (event) { + if (event.touches.length == 1) { + var touch = event.touches[0]; + var onTouchPosition = { + x: that.editorContainer.offsetLeft, + y: that.editorContainer.offsetTop + }; + var onTouchOffset = { + x: touch.pageX - onTouchPosition.x, + y: touch.pageY - onTouchPosition.y + }; - case _unicode.KEY_CODES.BACKSPACE: - case _unicode.KEY_CODES.DELETE: - selection.empty(event); - _this.prepareEditor(); + that.eventManager.addEventListener(this, 'touchmove', function (event) { + var touch = event.touches[0]; + that.updateEditorPosition(touch.pageX - onTouchOffset.x, touch.pageY - onTouchOffset.y); + that.hideCellPointer(); event.preventDefault(); - break; + }); + } + }); - case _unicode.KEY_CODES.F2: - /* F2 */ - _this.openEditor(null, event); + this.eventManager.addEventListener(document.body, 'touchend', function (event) { + if (!(0, _element.isChildOf)(event.target, that.editorContainer) && !(0, _element.isChildOf)(event.target, that.instance.rootElement)) { + that.close(); + } + }); - if (activeEditor) { - activeEditor.enableFullEditMode(); - } - event.preventDefault(); // prevent Opera from opening 'Go to Page dialog' - break; + this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.leftOverlay.holder, 'scroll', function (event) { + if (that.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer != window) { + that.hideCellPointer(); + } + }); - case _unicode.KEY_CODES.ENTER: - /* return/enter */ - if (_this.isEditorOpened()) { + this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.topOverlay.holder, 'scroll', function (event) { + if (that.instance.view.wt.wtOverlays.topOverlay.trimmingContainer != window) { + that.hideCellPointer(); + } + }); +}; - if (activeEditor && activeEditor.state !== _baseEditor.EditorState.WAITING) { - _this.closeEditorAndSaveChanges(ctrlDown); - } - moveSelectionAfterEnter(event.shiftKey); - } else if (instance.getSettings().enterBeginsEditing) { - _this.openEditor(null, event); +MobileTextEditor.prototype.destroy = function () { + this.eventManager.clear(); - if (activeEditor) { - activeEditor.enableFullEditMode(); - } - } else { - moveSelectionAfterEnter(event.shiftKey); - } - event.preventDefault(); // don't add newline to field - (0, _event.stopImmediatePropagation)(event); // required by HandsontableEditor - break; + this.editorContainer.parentNode.removeChild(this.editorContainer); +}; - case _unicode.KEY_CODES.ESCAPE: - if (_this.isEditorOpened()) { - _this.closeEditorAndRestoreOriginalValue(ctrlDown); - } - event.preventDefault(); - break; +exports.default = MobileTextEditor; - case _unicode.KEY_CODES.HOME: - selection.setSelectedHeaders(false, false, false); - if (event.ctrlKey || event.metaKey) { - rangeModifier(new _src.CellCoords(0, priv.selRange.from.col)); - } else { - rangeModifier(new _src.CellCoords(priv.selRange.from.row, 0)); - } - event.preventDefault(); // don't scroll the window - (0, _event.stopPropagation)(event); - break; +/***/ }), +/* 217 */ +/***/ (function(module, exports, __webpack_require__) { - case _unicode.KEY_CODES.END: - selection.setSelectedHeaders(false, false, false); - if (event.ctrlKey || event.metaKey) { - rangeModifier(new _src.CellCoords(instance.countRows() - 1, priv.selRange.from.col)); - } else { - rangeModifier(new _src.CellCoords(priv.selRange.from.row, instance.countCols() - 1)); - } - event.preventDefault(); // don't scroll the window - (0, _event.stopPropagation)(event); - break; +"use strict"; - case _unicode.KEY_CODES.PAGE_UP: - selection.setSelectedHeaders(false, false, false); - selection.transformStart(-instance.countVisibleRows(), 0); - event.preventDefault(); // don't page up the window - (0, _event.stopPropagation)(event); - break; - case _unicode.KEY_CODES.PAGE_DOWN: - selection.setSelectedHeaders(false, false, false); - selection.transformStart(instance.countVisibleRows(), 0); - event.preventDefault(); // don't page down the window - (0, _event.stopPropagation)(event); - break; - default: - break; - } - } +exports.__esModule = true; - function init() { - instance.addHook('afterDocumentKeyDown', onKeyDown); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - eventManager.addEventListener(document.documentElement, 'keydown', function (event) { - if (!destroyed) { - instance.runHooks('afterDocumentKeyDown', event); - } - }); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - function onDblClick(event, coords, elem) { - // may be TD or TH - if (elem.nodeName == 'TD') { - _this.openEditor(); +var _numbro = __webpack_require__(80); - if (activeEditor) { - activeEditor.enableFullEditMode(); - } - } - } - instance.view.wt.update('onCellDblClick', onDblClick); +var _numbro2 = _interopRequireDefault(_numbro); - instance.addHook('afterDestroy', function () { - destroyed = true; - }); - } +var _textEditor = __webpack_require__(50); - /** - * Destroy current editor, if exists. - * - * @function destroyEditor - * @memberof! Handsontable.EditorManager# - * @param {Boolean} revertOriginal - */ - this.destroyEditor = function (revertOriginal) { - this.closeEditor(revertOriginal); - }; +var _textEditor2 = _interopRequireDefault(_textEditor); - /** - * Get active editor. - * - * @function getActiveEditor - * @memberof! Handsontable.EditorManager# - * @returns {*} - */ - this.getActiveEditor = function () { - return activeEditor; - }; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - /** - * Prepare text input to be displayed at given grid cell. - * - * @function prepareEditor - * @memberof! Handsontable.EditorManager# - */ - this.prepareEditor = function () { - var row, col, prop, td, originalValue, cellProperties, editorClass; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - if (activeEditor && activeEditor.isWaiting()) { - this.closeEditor(false, false, function (dataSaved) { - if (dataSaved) { - _this.prepareEditor(); - } - }); +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - return; - } - row = priv.selRange.highlight.row; - col = priv.selRange.highlight.col; - prop = instance.colToProp(col); - td = instance.getCell(row, col); +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - originalValue = instance.getSourceDataAtCell(instance.runHooks('modifyRow', row), col); - cellProperties = instance.getCellMeta(row, col); - editorClass = instance.getCellEditor(cellProperties); +/** + * @private + * @editor NumericEditor + * @class NumericEditor + * @dependencies TextEditor numbro + */ +var NumericEditor = function (_TextEditor) { + _inherits(NumericEditor, _TextEditor); - if (editorClass) { - activeEditor = (0, _editors.getEditorInstance)(editorClass, instance); - activeEditor.prepare(row, col, prop, td, originalValue, cellProperties); - } else { - activeEditor = void 0; - } - }; + function NumericEditor() { + _classCallCheck(this, NumericEditor); - /** - * Check is editor is opened/showed. - * - * @function isEditorOpened - * @memberof! Handsontable.EditorManager# - * @returns {Boolean} - */ - this.isEditorOpened = function () { - return activeEditor && activeEditor.isOpened(); - }; + return _possibleConstructorReturn(this, (NumericEditor.__proto__ || Object.getPrototypeOf(NumericEditor)).apply(this, arguments)); + } - /** - * Open editor with initial value. - * - * @function openEditor - * @memberof! Handsontable.EditorManager# - * @param {String} initialValue - * @param {DOMEvent} event - */ - this.openEditor = function (initialValue, event) { - if (activeEditor && !activeEditor.cellProperties.readOnly) { - activeEditor.beginEditing(initialValue, event); - } else if (activeEditor && activeEditor.cellProperties.readOnly) { + _createClass(NumericEditor, [{ + key: 'beginEditing', - // move the selection after opening the editor with ENTER key - if (event && event.keyCode === _unicode.KEY_CODES.ENTER) { - moveSelectionAfterEnter(); + /** + * @param {*} initialValue + */ + value: function beginEditing(initialValue) { + if (typeof initialValue === 'undefined' && this.originalValue) { + if (typeof this.cellProperties.language !== 'undefined') { + _numbro2.default.culture(this.cellProperties.language); + } + var decimalDelimiter = _numbro2.default.cultureData().delimiters.decimal; + initialValue = ('' + this.originalValue).replace('.', decimalDelimiter); } + _get(NumericEditor.prototype.__proto__ || Object.getPrototypeOf(NumericEditor.prototype), 'beginEditing', this).call(this, initialValue); } - }; - - /** - * Close editor, finish editing cell. - * - * @function closeEditor - * @memberof! Handsontable.EditorManager# - * @param {Boolean} restoreOriginalValue - * @param {Boolean} [ctrlDown] - * @param {Function} [callback] - */ - this.closeEditor = function (restoreOriginalValue, ctrlDown, callback) { - if (activeEditor) { - activeEditor.finishEditing(restoreOriginalValue, ctrlDown, callback); - } else if (callback) { - callback(false); - } - }; - - /** - * Close editor and save changes. - * - * @function closeEditorAndSaveChanges - * @memberof! Handsontable.EditorManager# - * @param {Boolean} ctrlDown - */ - this.closeEditorAndSaveChanges = function (ctrlDown) { - return this.closeEditor(false, ctrlDown); - }; - - /** - * Close editor and restore original value. - * - * @function closeEditorAndRestoreOriginalValue - * @memberof! Handsontable.EditorManager# - * @param {Boolean} ctrlDown - */ - this.closeEditorAndRestoreOriginalValue = function (ctrlDown) { - return this.closeEditor(true, ctrlDown); - }; + }]); - init(); -} + return NumericEditor; +}(_textEditor2.default); -exports.default = EditorManager; +exports.default = NumericEditor; /***/ }), -/* 202 */ +/* 218 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46496,12 +46358,14 @@ exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _baseEditor = __webpack_require__(36); - -var _baseEditor2 = _interopRequireDefault(_baseEditor); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _element = __webpack_require__(0); +var _textEditor = __webpack_require__(50); + +var _textEditor2 = _interopRequireDefault(_textEditor); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -46512,393 +46376,443 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" /** * @private - * @editor CheckboxEditor - * @class CheckboxEditor + * @editor PasswordEditor + * @class PasswordEditor + * @dependencies TextEditor */ -var CheckboxEditor = function (_BaseEditor) { - _inherits(CheckboxEditor, _BaseEditor); +var PasswordEditor = function (_TextEditor) { + _inherits(PasswordEditor, _TextEditor); - function CheckboxEditor() { - _classCallCheck(this, CheckboxEditor); + function PasswordEditor() { + _classCallCheck(this, PasswordEditor); - return _possibleConstructorReturn(this, (CheckboxEditor.__proto__ || Object.getPrototypeOf(CheckboxEditor)).apply(this, arguments)); + return _possibleConstructorReturn(this, (PasswordEditor.__proto__ || Object.getPrototypeOf(PasswordEditor)).apply(this, arguments)); } - _createClass(CheckboxEditor, [{ - key: 'beginEditing', - value: function beginEditing(initialValue, event) { - // editorManager return double click event as undefined - if (event === void 0) { - var checkbox = this.TD.querySelector('input[type="checkbox"]'); + _createClass(PasswordEditor, [{ + key: 'createElements', + value: function createElements() { + _get(PasswordEditor.prototype.__proto__ || Object.getPrototypeOf(PasswordEditor.prototype), 'createElements', this).call(this); - if (!(0, _element.hasClass)(checkbox, 'htBadValue')) { - checkbox.click(); - } - } + this.TEXTAREA = document.createElement('input'); + this.TEXTAREA.setAttribute('type', 'password'); + this.TEXTAREA.className = 'handsontableInput'; + this.textareaStyle = this.TEXTAREA.style; + this.textareaStyle.width = 0; + this.textareaStyle.height = 0; + + (0, _element.empty)(this.TEXTAREA_PARENT); + this.TEXTAREA_PARENT.appendChild(this.TEXTAREA); } - }, { - key: 'finishEditing', - value: function finishEditing() {} - }, { - key: 'init', - value: function init() {} - }, { - key: 'open', - value: function open() {} - }, { - key: 'close', - value: function close() {} - }, { - key: 'getValue', - value: function getValue() {} - }, { - key: 'setValue', - value: function setValue() {} - }, { - key: 'focus', - value: function focus() {} }]); - return CheckboxEditor; -}(_baseEditor2.default); + return PasswordEditor; +}(_textEditor2.default); -exports.default = CheckboxEditor; +exports.default = PasswordEditor; /***/ }), -/* 203 */ +/* 219 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.__esModule = true; +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _element = __webpack_require__(0); + +var _event = __webpack_require__(8); + +var _unicode = __webpack_require__(17); + +var _baseEditor = __webpack_require__(41); + +var _baseEditor2 = _interopRequireDefault(_baseEditor); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var SelectEditor = _baseEditor2.default.prototype.extend(); + +/** + * @private + * @editor SelectEditor + * @class SelectEditor + */ +SelectEditor.prototype.init = function () { + this.select = document.createElement('SELECT'); + (0, _element.addClass)(this.select, 'htSelectEditor'); + this.select.style.display = 'none'; + this.instance.rootElement.appendChild(this.select); + this.registerHooks(); +}; + +SelectEditor.prototype.registerHooks = function () { + var _this = this; + + this.instance.addHook('afterScrollHorizontally', function () { + return _this.refreshDimensions(); + }); + this.instance.addHook('afterScrollVertically', function () { + return _this.refreshDimensions(); + }); + this.instance.addHook('afterColumnResize', function () { + return _this.refreshDimensions(); + }); + this.instance.addHook('afterRowResize', function () { + return _this.refreshDimensions(); + }); +}; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +SelectEditor.prototype.prepare = function () { + _baseEditor2.default.prototype.prepare.apply(this, arguments); -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + var selectOptions = this.cellProperties.selectOptions; + var options; -var _moment = __webpack_require__(61); + if (typeof selectOptions == 'function') { + options = this.prepareOptions(selectOptions(this.row, this.col, this.prop)); + } else { + options = this.prepareOptions(selectOptions); + } -var _moment2 = _interopRequireDefault(_moment); + (0, _element.empty)(this.select); -var _pikaday = __webpack_require__(304); + for (var option in options) { + if (Object.prototype.hasOwnProperty.call(options, option)) { + var optionElement = document.createElement('OPTION'); + optionElement.value = option; + (0, _element.fastInnerHTML)(optionElement, options[option]); + this.select.appendChild(optionElement); + } + } +}; -var _pikaday2 = _interopRequireDefault(_pikaday); +SelectEditor.prototype.prepareOptions = function (optionsToPrepare) { + var preparedOptions = {}; -__webpack_require__(183); + if (Array.isArray(optionsToPrepare)) { + for (var i = 0, len = optionsToPrepare.length; i < len; i++) { + preparedOptions[optionsToPrepare[i]] = optionsToPrepare[i]; + } + } else if ((typeof optionsToPrepare === 'undefined' ? 'undefined' : _typeof(optionsToPrepare)) == 'object') { + preparedOptions = optionsToPrepare; + } -var _element = __webpack_require__(0); + return preparedOptions; +}; -var _object = __webpack_require__(1); +SelectEditor.prototype.getValue = function () { + return this.select.value; +}; -var _eventManager = __webpack_require__(4); +SelectEditor.prototype.setValue = function (value) { + this.select.value = value; +}; -var _eventManager2 = _interopRequireDefault(_eventManager); +var onBeforeKeyDown = function onBeforeKeyDown(event) { + var instance = this; + var editor = instance.getActiveEditor(); -var _unicode = __webpack_require__(16); + switch (event.keyCode) { + case _unicode.KEY_CODES.ARROW_UP: + var previousOptionIndex = editor.select.selectedIndex - 1; + if (previousOptionIndex >= 0) { + editor.select[previousOptionIndex].selected = true; + } -var _event = __webpack_require__(7); + (0, _event.stopImmediatePropagation)(event); + event.preventDefault(); + break; -var _textEditor = __webpack_require__(43); + case _unicode.KEY_CODES.ARROW_DOWN: + var nextOptionIndex = editor.select.selectedIndex + 1; + if (nextOptionIndex <= editor.select.length - 1) { + editor.select[nextOptionIndex].selected = true; + } -var _textEditor2 = _interopRequireDefault(_textEditor); + (0, _event.stopImmediatePropagation)(event); + event.preventDefault(); + break; + default: + break; + } +}; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +SelectEditor.prototype.open = function () { + this._opened = true; + this.refreshDimensions(); + this.select.style.display = ''; + this.instance.addHook('beforeKeyDown', onBeforeKeyDown); +}; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +SelectEditor.prototype.close = function () { + this._opened = false; + this.select.style.display = 'none'; + this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); +}; -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +SelectEditor.prototype.focus = function () { + this.select.focus(); +}; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +SelectEditor.prototype.refreshValue = function () { + var sourceData = this.instance.getSourceDataAtCell(this.row, this.prop); + this.originalValue = sourceData; -/** - * @private - * @editor DateEditor - * @class DateEditor - * @dependencies TextEditor moment pikaday - */ -var DateEditor = function (_TextEditor) { - _inherits(DateEditor, _TextEditor); + this.setValue(sourceData); + this.refreshDimensions(); +}; - /** - * @param {Core} hotInstance Handsontable instance - * @private - */ - function DateEditor(hotInstance) { - _classCallCheck(this, DateEditor); +SelectEditor.prototype.refreshDimensions = function () { + if (this.state !== _baseEditor.EditorState.EDITING) { + return; + } + this.TD = this.getEditedCell(); - // TODO: Move this option to general settings - var _this = _possibleConstructorReturn(this, (DateEditor.__proto__ || Object.getPrototypeOf(DateEditor)).call(this, hotInstance)); + // TD is outside of the viewport. + if (!this.TD) { + this.close(); - _this.defaultDateFormat = 'DD/MM/YYYY'; - _this.isCellEdited = false; - _this.parentDestroyed = false; - return _this; + return; } + var width = (0, _element.outerWidth)(this.TD) + 1, + height = (0, _element.outerHeight)(this.TD) + 1, + currentOffset = (0, _element.offset)(this.TD), + containerOffset = (0, _element.offset)(this.instance.rootElement), + scrollableContainer = (0, _element.getScrollableElement)(this.TD), + editTop = currentOffset.top - containerOffset.top - 1 - (scrollableContainer.scrollTop || 0), + editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0), + editorSection = this.checkEditorSection(), + cssTransformOffset; - _createClass(DateEditor, [{ - key: 'init', - value: function init() { - var _this2 = this; + var settings = this.instance.getSettings(); + var rowHeadersCount = settings.rowHeaders ? 1 : 0; + var colHeadersCount = settings.colHeaders ? 1 : 0; - if (typeof _moment2.default !== 'function') { - throw new Error('You need to include moment.js to your project.'); - } + switch (editorSection) { + case 'top': + cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.holder.parentNode); + break; + case 'left': + cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.holder.parentNode); + break; + case 'top-left-corner': + cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode); + break; + case 'bottom-left-corner': + cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode); + break; + case 'bottom': + cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode); + break; + default: + break; + } + if (this.instance.getSelected()[0] === 0) { + editTop += 1; + } - if (typeof _pikaday2.default !== 'function') { - throw new Error('You need to include Pikaday to your project.'); - } - _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'init', this).call(this); - this.instance.addHook('afterDestroy', function () { - _this2.parentDestroyed = true; - _this2.destroyElements(); - }); - } + if (this.instance.getSelected()[1] === 0) { + editLeft += 1; + } - /** - * Create data picker instance - */ + var selectStyle = this.select.style; - }, { - key: 'createElements', - value: function createElements() { - _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'createElements', this).call(this); + if (cssTransformOffset && cssTransformOffset != -1) { + selectStyle[cssTransformOffset[0]] = cssTransformOffset[1]; + } else { + (0, _element.resetCssTransform)(this.select); + } + var cellComputedStyle = (0, _element.getComputedStyle)(this.TD); - this.datePicker = document.createElement('DIV'); - this.datePickerStyle = this.datePicker.style; - this.datePickerStyle.position = 'absolute'; - this.datePickerStyle.top = 0; - this.datePickerStyle.left = 0; - this.datePickerStyle.zIndex = 9999; + if (parseInt(cellComputedStyle.borderTopWidth, 10) > 0) { + height -= 1; + } + if (parseInt(cellComputedStyle.borderLeftWidth, 10) > 0) { + width -= 1; + } - (0, _element.addClass)(this.datePicker, 'htDatepickerHolder'); - document.body.appendChild(this.datePicker); + selectStyle.height = height + 'px'; + selectStyle.minWidth = width + 'px'; + selectStyle.top = editTop + 'px'; + selectStyle.left = editLeft + 'px'; + selectStyle.margin = '0px'; +}; - this.$datePicker = new _pikaday2.default(this.getDatePickerConfig()); - var eventManager = new _eventManager2.default(this); +SelectEditor.prototype.getEditedCell = function () { + var editorSection = this.checkEditorSection(), + editedCell; - /** - * Prevent recognizing clicking on datepicker as clicking outside of table - */ - eventManager.addEventListener(this.datePicker, 'mousedown', function (event) { - return (0, _event.stopPropagation)(event); + switch (editorSection) { + case 'top': + editedCell = this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.getCell({ + row: this.row, + col: this.col }); - this.hideDatepicker(); - } - - /** - * Destroy data picker instance - */ - - }, { - key: 'destroyElements', - value: function destroyElements() { - this.$datePicker.destroy(); - } - - /** - * Prepare editor to appear - * - * @param {Number} row Row index - * @param {Number} col Column index - * @param {String} prop Property name (passed when datasource is an array of objects) - * @param {HTMLTableCellElement} td Table cell element - * @param {*} originalValue Original value - * @param {Object} cellProperties Object with cell properties ({@see Core#getCellMeta}) - */ + this.select.style.zIndex = 101; + break; + case 'corner': + editedCell = this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({ + row: this.row, + col: this.col + }); + this.select.style.zIndex = 103; + break; + case 'left': + editedCell = this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.getCell({ + row: this.row, + col: this.col + }); + this.select.style.zIndex = 102; + break; + default: + editedCell = this.instance.getCell(this.row, this.col); + this.select.style.zIndex = ''; + break; + } - }, { - key: 'prepare', - value: function prepare(row, col, prop, td, originalValue, cellProperties) { - this._opened = false; - _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'prepare', this).call(this, row, col, prop, td, originalValue, cellProperties); - } + return editedCell != -1 && editedCell != -2 ? editedCell : void 0; +}; - /** - * Open editor - * - * @param {Event} [event=null] - */ +exports.default = SelectEditor; - }, { - key: 'open', - value: function open() { - var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; +/***/ }), +/* 220 */ +/***/ (function(module, exports, __webpack_require__) { - _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'open', this).call(this); - this.showDatepicker(event); - } +"use strict"; - /** - * Close editor - */ - }, { - key: 'close', - value: function close() { - var _this3 = this; +exports.__esModule = true; - this._opened = false; - this.instance._registerTimeout(setTimeout(function () { - _this3.instance.selection.refreshBorders(); - }, 0)); +var _element = __webpack_require__(0); - _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'close', this).call(this); +function cellDecorator(instance, TD, row, col, prop, value, cellProperties) { + if (cellProperties.className) { + if (TD.className) { + TD.className = TD.className + ' ' + cellProperties.className; + } else { + TD.className = cellProperties.className; } + } - /** - * @param {Boolean} [isCancelled=false] - * @param {Boolean} [ctrlDown=false] - */ - - }, { - key: 'finishEditing', - value: function finishEditing() { - var isCancelled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - var ctrlDown = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (isCancelled) { - // pressed ESC, restore original value - // var value = this.instance.getDataAtCell(this.row, this.col); - var value = this.originalValue; + if (cellProperties.readOnly) { + (0, _element.addClass)(TD, cellProperties.readOnlyCellClassName); + } - if (value !== void 0) { - this.setValue(value); - } - } - this.hideDatepicker(); - _get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'finishEditing', this).call(this, isCancelled, ctrlDown); - } + if (cellProperties.valid === false && cellProperties.invalidCellClassName) { + (0, _element.addClass)(TD, cellProperties.invalidCellClassName); + } else { + (0, _element.removeClass)(TD, cellProperties.invalidCellClassName); + } - /** - * Show data picker - * - * @param {Event} event - */ + if (cellProperties.wordWrap === false && cellProperties.noWordWrapClassName) { + (0, _element.addClass)(TD, cellProperties.noWordWrapClassName); + } - }, { - key: 'showDatepicker', - value: function showDatepicker(event) { - this.$datePicker.config(this.getDatePickerConfig()); + if (!value && cellProperties.placeholder) { + (0, _element.addClass)(TD, cellProperties.placeholderCellClassName); + } +} /** + * Adds appropriate CSS class to table cell, based on cellProperties + */ +exports.default = cellDecorator; - var offset = this.TD.getBoundingClientRect(); - var dateFormat = this.cellProperties.dateFormat || this.defaultDateFormat; - var datePickerConfig = this.$datePicker.config(); - var dateStr = void 0; - var isMouseDown = this.instance.view.isMouseDown(); - var isMeta = event ? (0, _unicode.isMetaKey)(event.keyCode) : false; +/***/ }), +/* 221 */ +/***/ (function(module, exports, __webpack_require__) { - this.datePickerStyle.top = window.pageYOffset + offset.top + (0, _element.outerHeight)(this.TD) + 'px'; - this.datePickerStyle.left = window.pageXOffset + offset.left + 'px'; +"use strict"; - this.$datePicker._onInputFocus = function () {}; - datePickerConfig.format = dateFormat; - if (this.originalValue) { - dateStr = this.originalValue; +exports.__esModule = true; - if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) { - this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true); - } +var _element = __webpack_require__(0); - // workaround for date/time cells - pikaday resets the cell value to 12:00 AM by default, this will overwrite the value. - if (this.getValue() !== this.originalValue) { - this.setValue(this.originalValue); - } +var _eventManager = __webpack_require__(4); - if (!isMeta && !isMouseDown) { - this.setValue(''); - } - } else if (this.cellProperties.defaultDate) { - dateStr = this.cellProperties.defaultDate; +var _eventManager2 = _interopRequireDefault(_eventManager); - datePickerConfig.defaultDate = dateStr; +var _src = __webpack_require__(12); - if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) { - this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true); - } +var _index = __webpack_require__(9); - if (!isMeta && !isMouseDown) { - this.setValue(''); - } - } else { - // if a default date is not defined, set a soft-default-date: display the current day and month in the - // datepicker, but don't fill the editor input - this.$datePicker.gotoToday(); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - this.datePickerStyle.display = 'block'; - this.$datePicker.show(); - } +var clonableWRAPPER = document.createElement('DIV'); +clonableWRAPPER.className = 'htAutocompleteWrapper'; - /** - * Hide data picker - */ +var clonableARROW = document.createElement('DIV'); +clonableARROW.className = 'htAutocompleteArrow'; +// workaround for https://github.com/handsontable/handsontable/issues/1946 +// this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips +clonableARROW.appendChild(document.createTextNode(String.fromCharCode(9660))); - }, { - key: 'hideDatepicker', - value: function hideDatepicker() { - this.datePickerStyle.display = 'none'; - this.$datePicker.hide(); - } +var wrapTdContentWithWrapper = function wrapTdContentWithWrapper(TD, WRAPPER) { + WRAPPER.innerHTML = TD.innerHTML; + (0, _element.empty)(TD); + TD.appendChild(WRAPPER); +}; - /** - * Get date picker options. - * - * @returns {Object} - */ +/** + * Autocomplete renderer + * + * @private + * @renderer AutocompleteRenderer + * @param {Object} instance Handsontable instance + * @param {Element} TD Table cell where to render + * @param {Number} row + * @param {Number} col + * @param {String|Number} prop Row object property name + * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) + * @param {Object} cellProperties Cell properites (shared by cell renderer and editor) + */ +function autocompleteRenderer(instance, TD, row, col, prop, value, cellProperties) { + var WRAPPER = clonableWRAPPER.cloneNode(true); // this is faster than createElement + var ARROW = clonableARROW.cloneNode(true); // this is faster than createElement - }, { - key: 'getDatePickerConfig', - value: function getDatePickerConfig() { - var _this4 = this; + if (cellProperties.allowHtml) { + (0, _index.getRenderer)('html').apply(this, arguments); + } else { + (0, _index.getRenderer)('text').apply(this, arguments); + } - var htInput = this.TEXTAREA; - var options = {}; + TD.appendChild(ARROW); + (0, _element.addClass)(TD, 'htAutocomplete'); - if (this.cellProperties && this.cellProperties.datePickerConfig) { - (0, _object.deepExtend)(options, this.cellProperties.datePickerConfig); - } - var origOnSelect = options.onSelect; - var origOnClose = options.onClose; + if (!TD.firstChild) { + // http://jsperf.com/empty-node-if-needed + // otherwise empty fields appear borderless in demo/renderers.html (IE) + TD.appendChild(document.createTextNode(String.fromCharCode(160))); // workaround for https://github.com/handsontable/handsontable/issues/1946 + // this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips + } - options.field = htInput; - options.trigger = htInput; - options.container = this.datePicker; - options.bound = false; - options.format = options.format || this.defaultDateFormat; - options.reposition = options.reposition || false; - options.onSelect = function (dateStr) { - if (!isNaN(dateStr.getTime())) { - dateStr = (0, _moment2.default)(dateStr).format(_this4.cellProperties.dateFormat || _this4.defaultDateFormat); - } - _this4.setValue(dateStr); - _this4.hideDatepicker(); + if (!instance.acArrowListener) { + var eventManager = new _eventManager2.default(instance); - if (origOnSelect) { - origOnSelect(); - } - }; - options.onClose = function () { - if (!_this4.parentDestroyed) { - _this4.finishEditing(false); - } - if (origOnClose) { - origOnClose(); - } - }; + // not very elegant but easy and fast + instance.acArrowListener = function (event) { + if ((0, _element.hasClass)(event.target, 'htAutocompleteArrow')) { + instance.view.wt.getSetting('onCellDblClick', null, new _src.CellCoords(row, col), TD); + } + }; - return options; - } - }]); + eventManager.addEventListener(instance.rootElement, 'mousedown', instance.acArrowListener); - return DateEditor; -}(_textEditor2.default); + // We need to unbind the listener after the table has been destroyed + instance.addHookOnce('afterDestroy', function () { + eventManager.destroy(); + }); + } +} -exports.default = DateEditor; +exports.default = autocompleteRenderer; /***/ }), -/* 204 */ +/* 222 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46906,381 +46820,398 @@ exports.default = DateEditor; exports.__esModule = true; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _element = __webpack_require__(0); -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; +var _string = __webpack_require__(32); -var _autocompleteEditor = __webpack_require__(149); +var _eventManager = __webpack_require__(4); -var _autocompleteEditor2 = _interopRequireDefault(_autocompleteEditor); +var _eventManager2 = _interopRequireDefault(_eventManager); -var _pluginHooks = __webpack_require__(8); +var _unicode = __webpack_require__(17); -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); +var _function = __webpack_require__(35); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _event = __webpack_require__(8); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var _index = __webpack_require__(9); -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +var isListeningKeyDownEvent = new WeakMap(); +var isCheckboxListenerAdded = new WeakMap(); +var BAD_VALUE_CLASS = 'htBadValue'; /** + * Checkbox renderer + * * @private - * @editor DropdownEditor - * @class DropdownEditor - * @dependencies AutocompleteEditor + * @param {Object} instance Handsontable instance + * @param {Element} TD Table cell where to render + * @param {Number} row + * @param {Number} col + * @param {String|Number} prop Row object property name + * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) + * @param {Object} cellProperties Cell properties (shared by cell renderer and editor) */ -var DropdownEditor = function (_AutocompleteEditor) { - _inherits(DropdownEditor, _AutocompleteEditor); +function checkboxRenderer(instance, TD, row, col, prop, value, cellProperties) { + (0, _index.getRenderer)('base').apply(this, arguments); - function DropdownEditor() { - _classCallCheck(this, DropdownEditor); + var eventManager = registerEvents(instance); + var input = createInput(); + var labelOptions = cellProperties.label; + var badValue = false; - return _possibleConstructorReturn(this, (DropdownEditor.__proto__ || Object.getPrototypeOf(DropdownEditor)).apply(this, arguments)); + if (typeof cellProperties.checkedTemplate === 'undefined') { + cellProperties.checkedTemplate = true; + } + if (typeof cellProperties.uncheckedTemplate === 'undefined') { + cellProperties.uncheckedTemplate = false; } - _createClass(DropdownEditor, [{ - key: 'prepare', - value: function prepare(row, col, prop, td, originalValue, cellProperties) { - _get(DropdownEditor.prototype.__proto__ || Object.getPrototypeOf(DropdownEditor.prototype), 'prepare', this).call(this, row, col, prop, td, originalValue, cellProperties); - this.cellProperties.filter = false; - this.cellProperties.strict = true; - } - }]); + (0, _element.empty)(TD); // TODO identify under what circumstances this line can be removed - return DropdownEditor; -}(_autocompleteEditor2.default); + if (value === cellProperties.checkedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.checkedTemplate)) { + input.checked = true; + } else if (value === cellProperties.uncheckedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.uncheckedTemplate)) { + input.checked = false; + } else if (value === null) { + // default value + (0, _element.addClass)(input, 'noValue'); + } else { + input.style.display = 'none'; + (0, _element.addClass)(input, BAD_VALUE_CLASS); + badValue = true; + } -_pluginHooks2.default.getSingleton().add('beforeValidate', function (value, row, col, source) { - var cellMeta = this.getCellMeta(row, this.propToCol(col)); + input.setAttribute('data-row', row); + input.setAttribute('data-col', col); - if (cellMeta.editor === DropdownEditor) { - if (cellMeta.strict === void 0) { - cellMeta.filter = false; - cellMeta.strict = true; + if (!badValue && labelOptions) { + var labelText = ''; + + if (labelOptions.value) { + labelText = typeof labelOptions.value === 'function' ? labelOptions.value.call(this, row, col, prop, value) : labelOptions.value; + } else if (labelOptions.property) { + labelText = instance.getDataAtRowProp(row, labelOptions.property); } - } -}); + var label = createLabel(labelText); -exports.default = DropdownEditor; + if (labelOptions.position === 'before') { + label.appendChild(input); + } else { + label.insertBefore(input, label.firstChild); + } + input = label; + } -/***/ }), -/* 205 */ -/***/ (function(module, exports, __webpack_require__) { + TD.appendChild(input); -"use strict"; + if (badValue) { + TD.appendChild(document.createTextNode('#bad-value#')); + } + if (!isListeningKeyDownEvent.has(instance)) { + isListeningKeyDownEvent.set(instance, true); + instance.addHook('beforeKeyDown', onBeforeKeyDown); + } -exports.__esModule = true; + /** + * On before key down DOM listener. + * + * @private + * @param {Event} event + */ + function onBeforeKeyDown(event) { + var toggleKeys = 'SPACE|ENTER'; + var switchOffKeys = 'DELETE|BACKSPACE'; + var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode); -var _unicode = __webpack_require__(16); + if (isKeyCode(toggleKeys + '|' + switchOffKeys) && !(0, _event.isImmediatePropagationStopped)(event)) { + eachSelectedCheckboxCell(function () { + (0, _event.stopImmediatePropagation)(event); + event.preventDefault(); + }); + } + if (isKeyCode(toggleKeys)) { + changeSelectedCheckboxesState(); + } + if (isKeyCode(switchOffKeys)) { + changeSelectedCheckboxesState(true); + } + } -var _event = __webpack_require__(7); + /** + * Change checkbox checked property + * + * @private + * @param {Boolean} [uncheckCheckbox=false] + */ + function changeSelectedCheckboxesState() { + var uncheckCheckbox = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; -var _element = __webpack_require__(0); + var selRange = instance.getSelectedRange(); -var _baseEditor = __webpack_require__(36); + if (!selRange) { + return; + } -var _baseEditor2 = _interopRequireDefault(_baseEditor); + var topLeft = selRange.getTopLeftCorner(); + var bottomRight = selRange.getBottomRightCorner(); + var changes = []; -var _eventManager = __webpack_require__(4); + for (var _row = topLeft.row; _row <= bottomRight.row; _row += 1) { + for (var _col = topLeft.col; _col <= bottomRight.col; _col += 1) { + var _cellProperties = instance.getCellMeta(_row, _col); -var _eventManager2 = _interopRequireDefault(_eventManager); + if (_cellProperties.type !== 'checkbox') { + return; + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /* eslint-disable no-continue */ + if (_cellProperties.readOnly === true) { + continue; + } -var MobileTextEditor = _baseEditor2.default.prototype.extend(); -var domDimensionsCache = {}; + if (typeof _cellProperties.checkedTemplate === 'undefined') { + _cellProperties.checkedTemplate = true; + } + if (typeof _cellProperties.uncheckedTemplate === 'undefined') { + _cellProperties.uncheckedTemplate = false; + } -/** - * @private - * @editor MobileTextEditor - * @class MobileTextEditor - */ -var createControls = function createControls() { - this.controls = {}; + var dataAtCell = instance.getDataAtCell(_row, _col); - this.controls.leftButton = document.createElement('DIV'); - this.controls.leftButton.className = 'leftButton'; - this.controls.rightButton = document.createElement('DIV'); - this.controls.rightButton.className = 'rightButton'; - this.controls.upButton = document.createElement('DIV'); - this.controls.upButton.className = 'upButton'; - this.controls.downButton = document.createElement('DIV'); - this.controls.downButton.className = 'downButton'; + if (uncheckCheckbox === false) { + if (dataAtCell === _cellProperties.checkedTemplate) { + changes.push([_row, _col, _cellProperties.uncheckedTemplate]); + } else if ([_cellProperties.uncheckedTemplate, null, void 0].indexOf(dataAtCell) !== -1) { + changes.push([_row, _col, _cellProperties.checkedTemplate]); + } + } else { + changes.push([_row, _col, _cellProperties.uncheckedTemplate]); + } + } + } - for (var button in this.controls) { - if (Object.prototype.hasOwnProperty.call(this.controls, button)) { - this.positionControls.appendChild(this.controls[button]); + if (changes.length > 0) { + instance.setDataAtCell(changes); } } -}; -MobileTextEditor.prototype.valueChanged = function () { - return this.initValue != this.getValue(); -}; + /** + * Call callback for each found selected cell with checkbox type. + * + * @private + * @param {Function} callback + */ + function eachSelectedCheckboxCell(callback) { + var selRange = instance.getSelectedRange(); -MobileTextEditor.prototype.init = function () { - var that = this; - this.eventManager = new _eventManager2.default(this.instance); + if (!selRange) { + return; + } + var topLeft = selRange.getTopLeftCorner(); + var bottomRight = selRange.getBottomRightCorner(); - this.createElements(); - this.bindEvents(); + for (var _row2 = topLeft.row; _row2 <= bottomRight.row; _row2++) { + for (var _col2 = topLeft.col; _col2 <= bottomRight.col; _col2++) { + var _cellProperties2 = instance.getCellMeta(_row2, _col2); - this.instance.addHook('afterDestroy', function () { - that.destroy(); - }); -}; + if (_cellProperties2.type !== 'checkbox') { + return; + } -MobileTextEditor.prototype.getValue = function () { - return this.TEXTAREA.value; -}; + var cell = instance.getCell(_row2, _col2); -MobileTextEditor.prototype.setValue = function (newValue) { - this.initValue = newValue; + if (cell == null) { - this.TEXTAREA.value = newValue; -}; + callback(_row2, _col2, _cellProperties2); + } else { + var checkboxes = cell.querySelectorAll('input[type=checkbox]'); -MobileTextEditor.prototype.createElements = function () { - this.editorContainer = document.createElement('DIV'); - this.editorContainer.className = 'htMobileEditorContainer'; + if (checkboxes.length > 0 && !_cellProperties2.readOnly) { + callback(checkboxes); + } + } + } + } + } +} - this.cellPointer = document.createElement('DIV'); - this.cellPointer.className = 'cellPointer'; +/** + * Register checkbox listeners. + * + * @param {Handsontable} instance Handsontable instance. + * @returns {EventManager} + */ +function registerEvents(instance) { + var eventManager = isCheckboxListenerAdded.get(instance); - this.moveHandle = document.createElement('DIV'); - this.moveHandle.className = 'moveHandle'; + if (!eventManager) { + eventManager = new _eventManager2.default(instance); + eventManager.addEventListener(instance.rootElement, 'click', function (event) { + return onClick(event, instance); + }); + eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) { + return onMouseUp(event, instance); + }); + eventManager.addEventListener(instance.rootElement, 'change', function (event) { + return onChange(event, instance); + }); - this.inputPane = document.createElement('DIV'); - this.inputPane.className = 'inputs'; + isCheckboxListenerAdded.set(instance, eventManager); + } - this.positionControls = document.createElement('DIV'); - this.positionControls.className = 'positionControls'; + return eventManager; +} - this.TEXTAREA = document.createElement('TEXTAREA'); - (0, _element.addClass)(this.TEXTAREA, 'handsontableInput'); +/** + * Create input element. + * + * @returns {Node} + */ +function createInput() { + var input = document.createElement('input'); - this.inputPane.appendChild(this.TEXTAREA); + input.className = 'htCheckboxRendererInput'; + input.type = 'checkbox'; + input.setAttribute('autocomplete', 'off'); + input.setAttribute('tabindex', '-1'); - this.editorContainer.appendChild(this.cellPointer); - this.editorContainer.appendChild(this.moveHandle); - this.editorContainer.appendChild(this.inputPane); - this.editorContainer.appendChild(this.positionControls); + return input.cloneNode(false); +} - createControls.call(this); +/** + * Create label element. + * + * @returns {Node} + */ +function createLabel(text) { + var label = document.createElement('label'); - document.body.appendChild(this.editorContainer); -}; + label.className = 'htCheckboxRendererLabel'; + label.appendChild(document.createTextNode(text)); -MobileTextEditor.prototype.onBeforeKeyDown = function (event) { - var instance = this; - var that = instance.getActiveEditor(); + return label.cloneNode(true); +} - if (event.target !== that.TEXTAREA || (0, _event.isImmediatePropagationStopped)(event)) { +/** + * `mouseup` callback. + * + * @private + * @param {Event} event `mouseup` event. + * @param {Object} instance Handsontable instance. + */ +function onMouseUp(event, instance) { + if (!isCheckboxInput(event.target)) { return; } + setTimeout(instance.listen, 10); +} - switch (event.keyCode) { - case _unicode.KEY_CODES.ENTER: - that.close(); - event.preventDefault(); // don't add newline to field - break; - case _unicode.KEY_CODES.BACKSPACE: - (0, _event.stopImmediatePropagation)(event); // backspace, delete, home, end should only work locally when cell is edited (not in table context) - break; - default: - break; +/** + * `click` callback. + * + * @private + * @param {Event} event `click` event. + * @param {Object} instance Handsontable instance. + */ +function onClick(event, instance) { + if (!isCheckboxInput(event.target)) { + return false; } -}; - -MobileTextEditor.prototype.open = function () { - this.instance.addHook('beforeKeyDown', this.onBeforeKeyDown); - - (0, _element.addClass)(this.editorContainer, 'active'); - (0, _element.removeClass)(this.cellPointer, 'hidden'); - - this.updateEditorPosition(); -}; - -MobileTextEditor.prototype.focus = function () { - this.TEXTAREA.focus(); - (0, _element.setCaretPosition)(this.TEXTAREA, this.TEXTAREA.value.length); -}; - -MobileTextEditor.prototype.close = function () { - this.TEXTAREA.blur(); - this.instance.removeHook('beforeKeyDown', this.onBeforeKeyDown); - (0, _element.removeClass)(this.editorContainer, 'active'); -}; - -MobileTextEditor.prototype.scrollToView = function () { - var coords = this.instance.getSelectedRange().highlight; - this.instance.view.scrollViewport(coords); -}; + var row = parseInt(event.target.getAttribute('data-row'), 10); + var col = parseInt(event.target.getAttribute('data-col'), 10); + var cellProperties = instance.getCellMeta(row, col); -MobileTextEditor.prototype.hideCellPointer = function () { - if (!(0, _element.hasClass)(this.cellPointer, 'hidden')) { - (0, _element.addClass)(this.cellPointer, 'hidden'); + if (cellProperties.readOnly) { + event.preventDefault(); } -}; - -MobileTextEditor.prototype.updateEditorPosition = function (x, y) { - if (x && y) { - x = parseInt(x, 10); - y = parseInt(y, 10); - - this.editorContainer.style.top = y + 'px'; - this.editorContainer.style.left = x + 'px'; - } else { - var selection = this.instance.getSelected(), - selectedCell = this.instance.getCell(selection[0], selection[1]); - - // cache sizes - if (!domDimensionsCache.cellPointer) { - domDimensionsCache.cellPointer = { - height: (0, _element.outerHeight)(this.cellPointer), - width: (0, _element.outerWidth)(this.cellPointer) - }; - } - if (!domDimensionsCache.editorContainer) { - domDimensionsCache.editorContainer = { - width: (0, _element.outerWidth)(this.editorContainer) - }; - } - - if (selectedCell !== undefined) { - var scrollLeft = this.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollLeft)(this.instance.view.wt.wtOverlays.leftOverlay.holder); - var scrollTop = this.instance.view.wt.wtOverlays.topOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollTop)(this.instance.view.wt.wtOverlays.topOverlay.holder); - - var selectedCellOffset = (0, _element.offset)(selectedCell), - selectedCellWidth = (0, _element.outerWidth)(selectedCell), - currentScrollPosition = { - x: scrollLeft, - y: scrollTop - }; - - this.editorContainer.style.top = parseInt(selectedCellOffset.top + (0, _element.outerHeight)(selectedCell) - currentScrollPosition.y + domDimensionsCache.cellPointer.height, 10) + 'px'; - this.editorContainer.style.left = parseInt(window.innerWidth / 2 - domDimensionsCache.editorContainer.width / 2, 10) + 'px'; - - if (selectedCellOffset.left + selectedCellWidth / 2 > parseInt(this.editorContainer.style.left, 10) + domDimensionsCache.editorContainer.width) { - this.editorContainer.style.left = window.innerWidth - domDimensionsCache.editorContainer.width + 'px'; - } else if (selectedCellOffset.left + selectedCellWidth / 2 < parseInt(this.editorContainer.style.left, 10) + 20) { - this.editorContainer.style.left = 0 + 'px'; - } +} - this.cellPointer.style.left = parseInt(selectedCellOffset.left - domDimensionsCache.cellPointer.width / 2 - (0, _element.offset)(this.editorContainer).left + selectedCellWidth / 2 - currentScrollPosition.x, 10) + 'px'; - } +/** + * `change` callback. + * + * @param {Event} event `change` event. + * @param {Object} instance Handsontable instance. + * @param {Object} cellProperties Reference to cell properties. + * @returns {Boolean} + */ +function onChange(event, instance) { + if (!isCheckboxInput(event.target)) { + return false; } -}; - -MobileTextEditor.prototype.updateEditorData = function () { - var selected = this.instance.getSelected(), - selectedValue = this.instance.getDataAtCell(selected[0], selected[1]); - this.row = selected[0]; - this.col = selected[1]; - this.setValue(selectedValue); - this.updateEditorPosition(); -}; + var row = parseInt(event.target.getAttribute('data-row'), 10); + var col = parseInt(event.target.getAttribute('data-col'), 10); + var cellProperties = instance.getCellMeta(row, col); -MobileTextEditor.prototype.prepareAndSave = function () { - var val; + if (!cellProperties.readOnly) { + var newCheckboxValue = null; - if (!this.valueChanged()) { - return; - } + if (event.target.checked) { + newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? true : cellProperties.checkedTemplate; + } else { + newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? false : cellProperties.uncheckedTemplate; + } - if (this.instance.getSettings().trimWhitespace) { - val = [[String.prototype.trim.call(this.getValue())]]; - } else { - val = [[this.getValue()]]; + instance.setDataAtCell(row, col, newCheckboxValue); } +} - this.saveValue(val); -}; +/** + * Check if the provided element is the checkbox input. + * + * @private + * @param {HTMLElement} element The element in question. + * @returns {Boolean} + */ +function isCheckboxInput(element) { + return element.tagName === 'INPUT' && element.getAttribute('type') === 'checkbox'; +} -MobileTextEditor.prototype.bindEvents = function () { - var that = this; +exports.default = checkboxRenderer; - this.eventManager.addEventListener(this.controls.leftButton, 'touchend', function (event) { - that.prepareAndSave(); - that.instance.selection.transformStart(0, -1, null, true); - that.updateEditorData(); - event.preventDefault(); - }); - this.eventManager.addEventListener(this.controls.rightButton, 'touchend', function (event) { - that.prepareAndSave(); - that.instance.selection.transformStart(0, 1, null, true); - that.updateEditorData(); - event.preventDefault(); - }); - this.eventManager.addEventListener(this.controls.upButton, 'touchend', function (event) { - that.prepareAndSave(); - that.instance.selection.transformStart(-1, 0, null, true); - that.updateEditorData(); - event.preventDefault(); - }); - this.eventManager.addEventListener(this.controls.downButton, 'touchend', function (event) { - that.prepareAndSave(); - that.instance.selection.transformStart(1, 0, null, true); - that.updateEditorData(); - event.preventDefault(); - }); +/***/ }), +/* 223 */ +/***/ (function(module, exports, __webpack_require__) { - this.eventManager.addEventListener(this.moveHandle, 'touchstart', function (event) { - if (event.touches.length == 1) { - var touch = event.touches[0]; - var onTouchPosition = { - x: that.editorContainer.offsetLeft, - y: that.editorContainer.offsetTop - }; - var onTouchOffset = { - x: touch.pageX - onTouchPosition.x, - y: touch.pageY - onTouchPosition.y - }; +"use strict"; - that.eventManager.addEventListener(this, 'touchmove', function (event) { - var touch = event.touches[0]; - that.updateEditorPosition(touch.pageX - onTouchOffset.x, touch.pageY - onTouchOffset.y); - that.hideCellPointer(); - event.preventDefault(); - }); - } - }); - this.eventManager.addEventListener(document.body, 'touchend', function (event) { - if (!(0, _element.isChildOf)(event.target, that.editorContainer) && !(0, _element.isChildOf)(event.target, that.instance.rootElement)) { - that.close(); - } - }); +exports.__esModule = true; - this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.leftOverlay.holder, 'scroll', function (event) { - if (that.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer != window) { - that.hideCellPointer(); - } - }); +var _element = __webpack_require__(0); - this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.topOverlay.holder, 'scroll', function (event) { - if (that.instance.view.wt.wtOverlays.topOverlay.trimmingContainer != window) { - that.hideCellPointer(); - } - }); -}; +var _index = __webpack_require__(9); -MobileTextEditor.prototype.destroy = function () { - this.eventManager.clear(); +/** + * @private + * @renderer HtmlRenderer + * @param instance + * @param TD + * @param row + * @param col + * @param prop + * @param value + * @param cellProperties + */ +function htmlRenderer(instance, TD, row, col, prop, value, cellProperties) { + (0, _index.getRenderer)('base').apply(this, arguments); - this.editorContainer.parentNode.removeChild(this.editorContainer); -}; + if (value === null || value === void 0) { + value = ''; + } -exports.default = MobileTextEditor; + (0, _element.fastInnerHTML)(TD, value); +} + +exports.default = htmlRenderer; /***/ }), -/* 206 */ +/* 224 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47288,66 +47219,60 @@ exports.default = MobileTextEditor; exports.__esModule = true; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _numbro = __webpack_require__(87); +var _numbro = __webpack_require__(80); var _numbro2 = _interopRequireDefault(_numbro); -var _textEditor = __webpack_require__(43); +var _index = __webpack_require__(9); -var _textEditor2 = _interopRequireDefault(_textEditor); +var _number = __webpack_require__(6); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - /** + * Numeric cell renderer + * * @private - * @editor NumericEditor - * @class NumericEditor - * @dependencies TextEditor numbro + * @renderer NumericRenderer + * @dependencies numbro + * @param {Object} instance Handsontable instance + * @param {Element} TD Table cell where to render + * @param {Number} row + * @param {Number} col + * @param {String|Number} prop Row object property name + * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) + * @param {Object} cellProperties Cell properties (shared by cell renderer and editor) */ -var NumericEditor = function (_TextEditor) { - _inherits(NumericEditor, _TextEditor); +function numericRenderer(instance, TD, row, col, prop, value, cellProperties) { + if ((0, _number.isNumeric)(value)) { + if (typeof cellProperties.language !== 'undefined') { + _numbro2.default.culture(cellProperties.language); + } - function NumericEditor() { - _classCallCheck(this, NumericEditor); + value = (0, _numbro2.default)(value).format(cellProperties.format || '0'); - return _possibleConstructorReturn(this, (NumericEditor.__proto__ || Object.getPrototypeOf(NumericEditor)).apply(this, arguments)); - } + var className = cellProperties.className || ''; - _createClass(NumericEditor, [{ - key: 'beginEditing', + var classArr = className.length ? className.split(' ') : []; - /** - * @param {*} initialValue - */ - value: function beginEditing(initialValue) { - if (typeof initialValue === 'undefined' && this.originalValue) { - if (typeof this.cellProperties.language !== 'undefined') { - _numbro2.default.culture(this.cellProperties.language); - } - var decimalDelimiter = _numbro2.default.cultureData().delimiters.decimal; - initialValue = ('' + this.originalValue).replace('.', decimalDelimiter); - } - _get(NumericEditor.prototype.__proto__ || Object.getPrototypeOf(NumericEditor.prototype), 'beginEditing', this).call(this, initialValue); + if (classArr.indexOf('htLeft') < 0 && classArr.indexOf('htCenter') < 0 && classArr.indexOf('htRight') < 0 && classArr.indexOf('htJustify') < 0) { + classArr.push('htRight'); } - }]); - return NumericEditor; -}(_textEditor2.default); + if (classArr.indexOf('htNumeric') < 0) { + classArr.push('htNumeric'); + } -exports.default = NumericEditor; + cellProperties.className = classArr.join(' '); + } + + (0, _index.getRenderer)('text')(instance, TD, row, col, prop, value, cellProperties); +} + +exports.default = numericRenderer; /***/ }), -/* 207 */ +/* 225 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47355,63 +47280,43 @@ exports.default = NumericEditor; exports.__esModule = true; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _element = __webpack_require__(0); -var _textEditor = __webpack_require__(43); - -var _textEditor2 = _interopRequireDefault(_textEditor); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +var _index = __webpack_require__(9); -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +var _number = __webpack_require__(6); /** * @private - * @editor PasswordEditor - * @class PasswordEditor - * @dependencies TextEditor + * @renderer PasswordRenderer + * @param instance + * @param TD + * @param row + * @param col + * @param prop + * @param value + * @param cellProperties */ -var PasswordEditor = function (_TextEditor) { - _inherits(PasswordEditor, _TextEditor); - - function PasswordEditor() { - _classCallCheck(this, PasswordEditor); - - return _possibleConstructorReturn(this, (PasswordEditor.__proto__ || Object.getPrototypeOf(PasswordEditor)).apply(this, arguments)); - } +function passwordRenderer(instance, TD, row, col, prop, value, cellProperties) { + (0, _index.getRenderer)('text').apply(this, arguments); - _createClass(PasswordEditor, [{ - key: 'createElements', - value: function createElements() { - _get(PasswordEditor.prototype.__proto__ || Object.getPrototypeOf(PasswordEditor.prototype), 'createElements', this).call(this); + value = TD.innerHTML; - this.TEXTAREA = document.createElement('input'); - this.TEXTAREA.setAttribute('type', 'password'); - this.TEXTAREA.className = 'handsontableInput'; - this.textareaStyle = this.TEXTAREA.style; - this.textareaStyle.width = 0; - this.textareaStyle.height = 0; + var hashLength = cellProperties.hashLength || value.length; + var hashSymbol = cellProperties.hashSymbol || '*'; - (0, _element.empty)(this.TEXTAREA_PARENT); - this.TEXTAREA_PARENT.appendChild(this.TEXTAREA); - } - }]); + var hash = ''; - return PasswordEditor; -}(_textEditor2.default); + (0, _number.rangeEach)(hashLength - 1, function () { + hash += hashSymbol; + }); + (0, _element.fastInnerHTML)(TD, hash); +} -exports.default = PasswordEditor; +exports.default = passwordRenderer; /***/ }), -/* 208 */ +/* 226 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47419,1359 +47324,1579 @@ exports.default = PasswordEditor; exports.__esModule = true; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - var _element = __webpack_require__(0); -var _event = __webpack_require__(7); - -var _unicode = __webpack_require__(16); - -var _baseEditor = __webpack_require__(36); - -var _baseEditor2 = _interopRequireDefault(_baseEditor); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _mixed = __webpack_require__(22); -var SelectEditor = _baseEditor2.default.prototype.extend(); +var _index = __webpack_require__(9); /** + * Default text renderer + * * @private - * @editor SelectEditor - * @class SelectEditor + * @renderer TextRenderer + * @param {Object} instance Handsontable instance + * @param {Element} TD Table cell where to render + * @param {Number} row + * @param {Number} col + * @param {String|Number} prop Row object property name + * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) + * @param {Object} cellProperties Cell properties (shared by cell renderer and editor) */ -SelectEditor.prototype.init = function () { - this.select = document.createElement('SELECT'); - (0, _element.addClass)(this.select, 'htSelectEditor'); - this.select.style.display = 'none'; - this.instance.rootElement.appendChild(this.select); - this.registerHooks(); -}; - -SelectEditor.prototype.registerHooks = function () { - var _this = this; +function textRenderer(instance, TD, row, col, prop, value, cellProperties) { + (0, _index.getRenderer)('base').apply(this, arguments); - this.instance.addHook('afterScrollHorizontally', function () { - return _this.refreshDimensions(); - }); - this.instance.addHook('afterScrollVertically', function () { - return _this.refreshDimensions(); - }); - this.instance.addHook('afterColumnResize', function () { - return _this.refreshDimensions(); - }); - this.instance.addHook('afterRowResize', function () { - return _this.refreshDimensions(); - }); -}; + if (!value && cellProperties.placeholder) { + value = cellProperties.placeholder; + } -SelectEditor.prototype.prepare = function () { - _baseEditor2.default.prototype.prepare.apply(this, arguments); + var escaped = (0, _mixed.stringify)(value); - var selectOptions = this.cellProperties.selectOptions; - var options; + if (!instance.getSettings().trimWhitespace) { + escaped = escaped.replace(/ /g, String.fromCharCode(160)); + } - if (typeof selectOptions == 'function') { - options = this.prepareOptions(selectOptions(this.row, this.col, this.prop)); + if (cellProperties.rendererTemplate) { + (0, _element.empty)(TD); + var TEMPLATE = document.createElement('TEMPLATE'); + TEMPLATE.setAttribute('bind', '{{}}'); + TEMPLATE.innerHTML = cellProperties.rendererTemplate; + HTMLTemplateElement.decorate(TEMPLATE); + TEMPLATE.model = instance.getSourceDataAtRow(row); + TD.appendChild(TEMPLATE); } else { - options = this.prepareOptions(selectOptions); + // this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips + (0, _element.fastInnerText)(TD, escaped); } +} - (0, _element.empty)(this.select); +exports.default = textRenderer; - for (var option in options) { - if (Object.prototype.hasOwnProperty.call(options, option)) { - var optionElement = document.createElement('OPTION'); - optionElement.value = option; - (0, _element.fastInnerHTML)(optionElement, options[option]); - this.select.appendChild(optionElement); - } - } -}; +/***/ }), +/* 227 */ +/***/ (function(module, exports, __webpack_require__) { -SelectEditor.prototype.prepareOptions = function (optionsToPrepare) { - var preparedOptions = {}; +"use strict"; - if (Array.isArray(optionsToPrepare)) { - for (var i = 0, len = optionsToPrepare.length; i < len; i++) { - preparedOptions[optionsToPrepare[i]] = optionsToPrepare[i]; - } - } else if ((typeof optionsToPrepare === 'undefined' ? 'undefined' : _typeof(optionsToPrepare)) == 'object') { - preparedOptions = optionsToPrepare; + +exports.__esModule = true; +exports.default = autocompleteValidator; +/** + * Autocomplete cell validator. + * + * @private + * @validator AutocompleteValidator + * @param {*} value - Value of edited cell + * @param {Function} callback - Callback called with validation result + */ +function autocompleteValidator(value, callback) { + if (value == null) { + value = ''; } - return preparedOptions; -}; + if (this.allowEmpty && value === '') { + callback(true); -SelectEditor.prototype.getValue = function () { - return this.select.value; -}; + return; + } -SelectEditor.prototype.setValue = function (value) { - this.select.value = value; + if (this.strict && this.source) { + if (typeof this.source === 'function') { + this.source(value, process(value, callback)); + } else { + process(value, callback)(this.source); + } + } else { + callback(true); + } }; -var onBeforeKeyDown = function onBeforeKeyDown(event) { - var instance = this; - var editor = instance.getActiveEditor(); +/** + * Function responsible for validation of autocomplete value. + * + * @param {*} value - Value of edited cell + * @param {Function} callback - Callback called with validation result + */ +function process(value, callback) { + var originalVal = value; - switch (event.keyCode) { - case _unicode.KEY_CODES.ARROW_UP: - var previousOptionIndex = editor.select.selectedIndex - 1; - if (previousOptionIndex >= 0) { - editor.select[previousOptionIndex].selected = true; + return function (source) { + var found = false; + + for (var s = 0, slen = source.length; s < slen; s++) { + if (originalVal === source[s]) { + found = true; // perfect match + break; } + } - (0, _event.stopImmediatePropagation)(event); - event.preventDefault(); - break; + callback(found); + }; +} - case _unicode.KEY_CODES.ARROW_DOWN: - var nextOptionIndex = editor.select.selectedIndex + 1; - if (nextOptionIndex <= editor.select.length - 1) { - editor.select[nextOptionIndex].selected = true; - } +/***/ }), +/* 228 */ +/***/ (function(module, exports, __webpack_require__) { - (0, _event.stopImmediatePropagation)(event); - event.preventDefault(); - break; - default: - break; - } -}; +"use strict"; -SelectEditor.prototype.open = function () { - this._opened = true; - this.refreshDimensions(); - this.select.style.display = ''; - this.instance.addHook('beforeKeyDown', onBeforeKeyDown); -}; -SelectEditor.prototype.close = function () { - this._opened = false; - this.select.style.display = 'none'; - this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); -}; +exports.__esModule = true; +exports.default = dateValidator; +exports.correctFormat = correctFormat; -SelectEditor.prototype.focus = function () { - this.select.focus(); -}; +var _moment = __webpack_require__(63); -SelectEditor.prototype.refreshValue = function () { - var sourceData = this.instance.getSourceDataAtCell(this.row, this.prop); - this.originalValue = sourceData; +var _moment2 = _interopRequireDefault(_moment); - this.setValue(sourceData); - this.refreshDimensions(); -}; +var _date = __webpack_require__(170); -SelectEditor.prototype.refreshDimensions = function () { - if (this.state !== _baseEditor.EditorState.EDITING) { - return; - } - this.TD = this.getEditedCell(); +var _editors = __webpack_require__(15); - // TD is outside of the viewport. - if (!this.TD) { - this.close(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return; - } - var width = (0, _element.outerWidth)(this.TD) + 1, - height = (0, _element.outerHeight)(this.TD) + 1, - currentOffset = (0, _element.offset)(this.TD), - containerOffset = (0, _element.offset)(this.instance.rootElement), - scrollableContainer = (0, _element.getScrollableElement)(this.TD), - editTop = currentOffset.top - containerOffset.top - 1 - (scrollableContainer.scrollTop || 0), - editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0), - editorSection = this.checkEditorSection(), - cssTransformOffset; +/** + * Date cell validator + * + * @private + * @validator DateValidator + * @dependencies moment + * @param {*} value - Value of edited cell + * @param {Function} callback - Callback called with validation result + */ +function dateValidator(value, callback) { + var valid = true; + var dateEditor = (0, _editors.getEditorInstance)('date', this.instance); - var settings = this.instance.getSettings(); - var rowHeadersCount = settings.rowHeaders ? 1 : 0; - var colHeadersCount = settings.colHeaders ? 1 : 0; + if (value == null) { + value = ''; + } + var isValidDate = (0, _moment2.default)(new Date(value)).isValid() || (0, _moment2.default)(value, dateEditor.defaultDateFormat).isValid(); + // is it in the specified format + var isValidFormat = (0, _moment2.default)(value, this.dateFormat || dateEditor.defaultDateFormat, true).isValid(); - switch (editorSection) { - case 'top': - cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.holder.parentNode); - break; - case 'left': - cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.holder.parentNode); - break; - case 'top-left-corner': - cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode); - break; - case 'bottom-left-corner': - cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode); - break; - case 'bottom': - cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode); - break; - default: - break; + if (this.allowEmpty && value === '') { + isValidDate = true; + isValidFormat = true; } - if (this.instance.getSelected()[0] === 0) { - editTop += 1; + if (!isValidDate) { + valid = false; } - - if (this.instance.getSelected()[1] === 0) { - editLeft += 1; + if (!isValidDate && isValidFormat) { + valid = true; } - var selectStyle = this.select.style; - - if (cssTransformOffset && cssTransformOffset != -1) { - selectStyle[cssTransformOffset[0]] = cssTransformOffset[1]; - } else { - (0, _element.resetCssTransform)(this.select); - } - var cellComputedStyle = (0, _element.getComputedStyle)(this.TD); + if (isValidDate && !isValidFormat) { + if (this.correctFormat === true) { + // if format correction is enabled + var correctedValue = correctFormat(value, this.dateFormat); + var row = this.instance.runHooks('unmodifyRow', this.row); + var column = this.instance.runHooks('unmodifyCol', this.col); - if (parseInt(cellComputedStyle.borderTopWidth, 10) > 0) { - height -= 1; - } - if (parseInt(cellComputedStyle.borderLeftWidth, 10) > 0) { - width -= 1; + this.instance.setDataAtCell(row, column, correctedValue, 'dateValidator'); + valid = true; + } else { + valid = false; + } } - selectStyle.height = height + 'px'; - selectStyle.minWidth = width + 'px'; - selectStyle.top = editTop + 'px'; - selectStyle.left = editLeft + 'px'; - selectStyle.margin = '0px'; + callback(valid); }; -SelectEditor.prototype.getEditedCell = function () { - var editorSection = this.checkEditorSection(), - editedCell; +/** + * Format the given string using moment.js' format feature + * + * @param {String} value + * @param {String} dateFormat + * @returns {String} + */ +function correctFormat(value, dateFormat) { + var dateFromDate = (0, _moment2.default)((0, _date.getNormalizedDate)(value)); + var dateFromMoment = (0, _moment2.default)(value, dateFormat); + var isAlphanumeric = value.search(/[A-z]/g) > -1; + var date = void 0; - switch (editorSection) { - case 'top': - editedCell = this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.getCell({ - row: this.row, - col: this.col - }); - this.select.style.zIndex = 101; - break; - case 'corner': - editedCell = this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({ - row: this.row, - col: this.col - }); - this.select.style.zIndex = 103; - break; - case 'left': - editedCell = this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.getCell({ - row: this.row, - col: this.col - }); - this.select.style.zIndex = 102; - break; - default: - editedCell = this.instance.getCell(this.row, this.col); - this.select.style.zIndex = ''; - break; + if (dateFromDate.isValid() && dateFromDate.format('x') === dateFromMoment.format('x') || !dateFromMoment.isValid() || isAlphanumeric) { + date = dateFromDate; + } else { + date = dateFromMoment; } - return editedCell != -1 && editedCell != -2 ? editedCell : void 0; + return date.format(dateFormat); }; -exports.default = SelectEditor; - /***/ }), -/* 209 */ +/* 229 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; -exports.toSingleLine = toSingleLine; - -var _array = __webpack_require__(2); - +exports.default = numericValidator; /** - * Tags a multiline string and return new one without line break characters and following spaces. + * Numeric cell validator * - * @param {Array} strings Parts of the entire string without expressions. - * @param {...String} expressions Expressions converted to strings, which are added to the entire string. - * @returns {String} + * @private + * @validator NumericValidator + * @param {*} value - Value of edited cell + * @param {*} callback - Callback called with validation result */ -function toSingleLine(strings) { - for (var _len = arguments.length, expressions = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - expressions[_key - 1] = arguments[_key]; +function numericValidator(value, callback) { + if (value == null) { + value = ''; + } + if (this.allowEmpty && value === '') { + callback(true); + } else if (value === '') { + callback(false); + } else { + callback(/^-?\d*(\.|,)?\d*$/.test(value)); } +}; - var result = (0, _array.arrayReduce)(strings, function (previousValue, currentValue, index) { +/***/ }), +/* 230 */ +/***/ (function(module, exports, __webpack_require__) { - var valueWithoutWhiteSpaces = currentValue.replace(/(?:\r?\n\s+)/g, ''); - var expressionForIndex = expressions[index] ? expressions[index] : ''; +"use strict"; - return previousValue + valueWithoutWhiteSpaces + expressionForIndex; - }, ''); - return result.trim(); -} /* eslint-disable import/prefer-default-export */ +exports.__esModule = true; +exports.default = timeValidator; -/***/ }), -/* 210 */ -/***/ (function(module, exports, __webpack_require__) { +var _moment = __webpack_require__(63); -"use strict"; +var _moment2 = _interopRequireDefault(_moment); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -__webpack_require__(98); +// Formats which are correctly parsed to time (supported by momentjs) +var STRICT_FORMATS = ['YYYY-MM-DDTHH:mm:ss.SSSZ', 'X', // Unix timestamp +'x' // Unix ms timestamp +]; -__webpack_require__(115); +/** + * Time cell validator + * + * @private + * @validator TimeValidator + * @dependencies moment + * @param {*} value - Value of edited cell + * @param {Function} callback - Callback called with validation result + */ +function timeValidator(value, callback) { + var valid = true; + var timeFormat = this.timeFormat || 'h:mm:ss a'; -__webpack_require__(124); + if (value === null) { + value = ''; + } -__webpack_require__(125); + value = /^\d{3,}$/.test(value) ? parseInt(value, 10) : value; -__webpack_require__(109); + var twoDigitValue = /^\d{1,2}$/.test(value); -__webpack_require__(123); + if (twoDigitValue) { + value += ':00'; + } -__webpack_require__(106); + var date = (0, _moment2.default)(value, STRICT_FORMATS, true).isValid() ? (0, _moment2.default)(value) : (0, _moment2.default)(value, timeFormat); + var isValidTime = date.isValid(); -__webpack_require__(107); + // is it in the specified format + var isValidFormat = (0, _moment2.default)(value, timeFormat, true).isValid() && !twoDigitValue; -__webpack_require__(108); + if (this.allowEmpty && value === '') { + isValidTime = true; + isValidFormat = true; + } + if (!isValidTime) { + valid = false; + } + if (!isValidTime && isValidFormat) { + valid = true; + } + if (isValidTime && !isValidFormat) { + if (this.correctFormat === true) { + // if format correction is enabled + var correctedValue = date.format(timeFormat); + var row = this.instance.runHooks('unmodifyRow', this.row); + var column = this.instance.runHooks('unmodifyCol', this.col); -__webpack_require__(97); + this.instance.setDataAtCell(row, column, correctedValue, 'timeValidator'); + valid = true; + } else { + valid = false; + } + } -__webpack_require__(120); + callback(valid); +}; -__webpack_require__(118); +/***/ }), +/* 231 */ +/***/ (function(module, exports, __webpack_require__) { -__webpack_require__(116); +"use strict"; -__webpack_require__(121); -__webpack_require__(122); +exports.__esModule = true; -__webpack_require__(117); +var _editors = __webpack_require__(15); -__webpack_require__(119); +var _renderers = __webpack_require__(9); -__webpack_require__(110); +var _validators = __webpack_require__(27); -__webpack_require__(111); +var CELL_TYPE = 'autocomplete'; + +exports.default = { + editor: (0, _editors.getEditor)(CELL_TYPE), + renderer: (0, _renderers.getRenderer)(CELL_TYPE), + validator: (0, _validators.getValidator)(CELL_TYPE) +}; -__webpack_require__(112); +/***/ }), +/* 232 */ +/***/ (function(module, exports, __webpack_require__) { -__webpack_require__(114); +"use strict"; -__webpack_require__(113); -__webpack_require__(95); +exports.__esModule = true; + +var _editors = __webpack_require__(15); -__webpack_require__(96); +var _renderers = __webpack_require__(9); -__webpack_require__(91); +var CELL_TYPE = 'checkbox'; -__webpack_require__(94); +exports.default = { + editor: (0, _editors.getEditor)(CELL_TYPE), + renderer: (0, _renderers.getRenderer)(CELL_TYPE) +}; -__webpack_require__(93); +/***/ }), +/* 233 */ +/***/ (function(module, exports, __webpack_require__) { -__webpack_require__(92); +"use strict"; -__webpack_require__(67); -__webpack_require__(100); +exports.__esModule = true; -__webpack_require__(101); +var _editors = __webpack_require__(15); -__webpack_require__(103); +var _renderers = __webpack_require__(9); -__webpack_require__(102); +var _validators = __webpack_require__(27); -__webpack_require__(99); +var CELL_TYPE = 'date'; -__webpack_require__(105); +exports.default = { + editor: (0, _editors.getEditor)(CELL_TYPE), + // displays small gray arrow on right side of the cell + renderer: (0, _renderers.getRenderer)('autocomplete'), + validator: (0, _validators.getValidator)(CELL_TYPE) +}; -__webpack_require__(104); +/***/ }), +/* 234 */ +/***/ (function(module, exports, __webpack_require__) { -__webpack_require__(126); +"use strict"; -__webpack_require__(129); -__webpack_require__(127); +exports.__esModule = true; -__webpack_require__(128); +var _editors = __webpack_require__(15); -__webpack_require__(131); +var _renderers = __webpack_require__(9); -__webpack_require__(130); +var _validators = __webpack_require__(27); -__webpack_require__(133); +var CELL_TYPE = 'dropdown'; -__webpack_require__(132); +exports.default = { + editor: (0, _editors.getEditor)(CELL_TYPE), + // displays small gray arrow on right side of the cell + renderer: (0, _renderers.getRenderer)('autocomplete'), + validator: (0, _validators.getValidator)('autocomplete') +}; + +/***/ }), +/* 235 */ +/***/ (function(module, exports, __webpack_require__) { -__webpack_require__(180); +"use strict"; -__webpack_require__(181); -__webpack_require__(182); +exports.__esModule = true; -var _editors = __webpack_require__(14); +var _editors = __webpack_require__(15); var _renderers = __webpack_require__(9); -var _validators = __webpack_require__(26); +var CELL_TYPE = 'handsontable'; -var _cellTypes = __webpack_require__(62); +exports.default = { + editor: (0, _editors.getEditor)(CELL_TYPE), + // displays small gray arrow on right side of the cell + renderer: (0, _renderers.getRenderer)('autocomplete') +}; -var _core = __webpack_require__(63); +/***/ }), +/* 236 */ +/***/ (function(module, exports, __webpack_require__) { -var _core2 = _interopRequireDefault(_core); +"use strict"; -var _jquery = __webpack_require__(178); -var _jquery2 = _interopRequireDefault(_jquery); +exports.__esModule = true; -var _eventManager = __webpack_require__(4); +var _editors = __webpack_require__(15); -var _eventManager2 = _interopRequireDefault(_eventManager); +var _renderers = __webpack_require__(9); -var _pluginHooks = __webpack_require__(8); +var _validators = __webpack_require__(27); -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); +var CELL_TYPE = 'numeric'; -var _ghostTable = __webpack_require__(66); +exports.default = { + editor: (0, _editors.getEditor)(CELL_TYPE), + renderer: (0, _renderers.getRenderer)(CELL_TYPE), + validator: (0, _validators.getValidator)(CELL_TYPE), + dataType: 'number' +}; -var _ghostTable2 = _interopRequireDefault(_ghostTable); +/***/ }), +/* 237 */ +/***/ (function(module, exports, __webpack_require__) { -var _array = __webpack_require__(2); +"use strict"; -var arrayHelpers = _interopRequireWildcard(_array); -var _browser = __webpack_require__(25); +exports.__esModule = true; -var browserHelpers = _interopRequireWildcard(_browser); +var _editors = __webpack_require__(15); -var _data = __webpack_require__(64); +var _renderers = __webpack_require__(9); -var dataHelpers = _interopRequireWildcard(_data); +var _validators = __webpack_require__(27); -var _date = __webpack_require__(89); +var CELL_TYPE = 'password'; -var dateHelpers = _interopRequireWildcard(_date); +exports.default = { + editor: (0, _editors.getEditor)(CELL_TYPE), + renderer: (0, _renderers.getRenderer)(CELL_TYPE), + copyable: false +}; -var _feature = __webpack_require__(34); +/***/ }), +/* 238 */ +/***/ (function(module, exports, __webpack_require__) { -var featureHelpers = _interopRequireWildcard(_feature); +"use strict"; -var _function = __webpack_require__(35); -var functionHelpers = _interopRequireWildcard(_function); +exports.__esModule = true; -var _mixed = __webpack_require__(20); +var _browser = __webpack_require__(26); -var mixedHelpers = _interopRequireWildcard(_mixed); +var _editors = __webpack_require__(15); -var _number = __webpack_require__(6); +var _renderers = __webpack_require__(9); -var numberHelpers = _interopRequireWildcard(_number); +var CELL_TYPE = 'text'; -var _object = __webpack_require__(1); +exports.default = { + editor: (0, _browser.isMobileBrowser)() ? (0, _editors.getEditor)('mobile') : (0, _editors.getEditor)(CELL_TYPE), + renderer: (0, _renderers.getRenderer)(CELL_TYPE) +}; -var objectHelpers = _interopRequireWildcard(_object); +/***/ }), +/* 239 */ +/***/ (function(module, exports, __webpack_require__) { -var _setting = __webpack_require__(65); +"use strict"; -var settingHelpers = _interopRequireWildcard(_setting); -var _string = __webpack_require__(27); +exports.__esModule = true; -var stringHelpers = _interopRequireWildcard(_string); +var _editors = __webpack_require__(15); -var _unicode = __webpack_require__(16); +var _renderers = __webpack_require__(9); -var unicodeHelpers = _interopRequireWildcard(_unicode); +var _validators = __webpack_require__(27); -var _element = __webpack_require__(0); +var CELL_TYPE = 'time'; -var domHelpers = _interopRequireWildcard(_element); +exports.default = { + editor: (0, _editors.getEditor)('text'), + // displays small gray arrow on right side of the cell + renderer: (0, _renderers.getRenderer)('text'), + validator: (0, _validators.getValidator)(CELL_TYPE) +}; -var _event = __webpack_require__(7); +/***/ }), +/* 240 */ +/***/ (function(module, exports, __webpack_require__) { -var domEventHelpers = _interopRequireWildcard(_event); +"use strict"; -var _index = __webpack_require__(179); -var plugins = _interopRequireWildcard(_index); +exports.__esModule = true; -var _plugins = __webpack_require__(5); +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; -var _defaultSettings = __webpack_require__(88); +var _SheetClip = __webpack_require__(171); -var _defaultSettings2 = _interopRequireDefault(_defaultSettings); +var _SheetClip2 = _interopRequireDefault(_SheetClip); -var _rootInstance = __webpack_require__(90); +var _data = __webpack_require__(84); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } +var _setting = __webpack_require__(83); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _object = __webpack_require__(1); -function Handsontable(rootElement, userSettings) { - var instance = new _core2.default(rootElement, userSettings || {}, _rootInstance.rootInstanceSymbol); +var _array = __webpack_require__(2); - instance.init(); +var _interval = __webpack_require__(241); - return instance; -} +var _interval2 = _interopRequireDefault(_interval); -(0, _jquery2.default)(Handsontable); +var _number = __webpack_require__(6); -Handsontable.Core = _core2.default; -Handsontable.DefaultSettings = _defaultSettings2.default; -Handsontable.EventManager = _eventManager2.default; -Handsontable._getListenersCounter = _eventManager.getListenersCounter; // For MemoryLeak tests +var _multiMap = __webpack_require__(242); -Handsontable.buildDate = '05/09/2017 13:02:28'; -Handsontable.packageName = 'handsontable'; -Handsontable.version = '0.34.1'; +var _multiMap2 = _interopRequireDefault(_multiMap); -var baseVersion = ''; +var _pluginHooks = __webpack_require__(7); -if (baseVersion) { - Handsontable.baseVersion = baseVersion; -} +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); -// Export Hooks singleton -Handsontable.hooks = _pluginHooks2.default.getSingleton(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// TODO: Remove this exports after rewrite tests about this module -Handsontable.__GhostTable = _ghostTable2.default; -// +/** + * Utility class that gets and saves data from/to the data source using mapping of columns numbers to object property names + * @todo refactor arguments of methods getRange, getText to be numbers (not objects) + * @todo remove priv, GridSettings from object constructor + * + * @param {Object} instance Instance of Handsontable + * @param {*} priv + * @param {*} GridSettings Grid settings + * @util + * @class DataMap + */ +function DataMap(instance, priv, GridSettings) { + var _this = this; -// Export all helpers to the Handsontable object -var HELPERS = [arrayHelpers, browserHelpers, dataHelpers, dateHelpers, featureHelpers, functionHelpers, mixedHelpers, numberHelpers, objectHelpers, settingHelpers, stringHelpers, unicodeHelpers]; -var DOM = [domHelpers, domEventHelpers]; + this.instance = instance; + this.priv = priv; + this.GridSettings = GridSettings; + this.dataSource = this.instance.getSettings().data; + this.cachedLength = null; + this.skipCache = false; + this.latestSourceRowsCount = 0; -Handsontable.helper = {}; -Handsontable.dom = {}; + if (this.dataSource && this.dataSource[0]) { + this.duckSchema = this.recursiveDuckSchema(this.dataSource[0]); + } else { + this.duckSchema = {}; + } + this.createMap(); + this.interval = _interval2.default.create(function () { + return _this.clearLengthCache(); + }, '15fps'); -// Fill general helpers. -arrayHelpers.arrayEach(HELPERS, function (helper) { - arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) { - if (key.charAt(0) !== '_') { - Handsontable.helper[key] = helper[key]; - } + this.instance.addHook('skipLengthCache', function (delay) { + return _this.onSkipLengthCache(delay); }); -}); + this.onSkipLengthCache(500); +} -// Fill DOM helpers. -arrayHelpers.arrayEach(DOM, function (helper) { - arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) { - if (key.charAt(0) !== '_') { - Handsontable.dom[key] = helper[key]; - } - }); -}); +DataMap.prototype.DESTINATION_RENDERER = 1; +DataMap.prototype.DESTINATION_CLIPBOARD_GENERATOR = 2; -// Export cell types. -Handsontable.cellTypes = {}; +/** + * @param {Object|Array} object + * @returns {Object|Array} + */ +DataMap.prototype.recursiveDuckSchema = function (object) { + return (0, _object.duckSchema)(object); +}; -arrayHelpers.arrayEach((0, _cellTypes.getRegisteredCellTypeNames)(), function (cellTypeName) { - Handsontable.cellTypes[cellTypeName] = (0, _cellTypes.getCellType)(cellTypeName); -}); +/** + * @param {Object} schema + * @param {Number} lastCol + * @param {Number} parent + * @returns {Number} + */ +DataMap.prototype.recursiveDuckColumns = function (schema, lastCol, parent) { + var prop, i; + if (typeof lastCol === 'undefined') { + lastCol = 0; + parent = ''; + } + if ((typeof schema === 'undefined' ? 'undefined' : _typeof(schema)) === 'object' && !Array.isArray(schema)) { + for (i in schema) { + if ((0, _object.hasOwnProperty)(schema, i)) { + if (schema[i] === null) { + prop = parent + i; + this.colToPropCache.push(prop); + this.propToColCache.set(prop, lastCol); -Handsontable.cellTypes.registerCellType = _cellTypes.registerCellType; -Handsontable.cellTypes.getCellType = _cellTypes.getCellType; + lastCol++; + } else { + lastCol = this.recursiveDuckColumns(schema[i], lastCol, i + '.'); + } + } + } + } -// Export all registered editors from the Handsontable. -Handsontable.editors = {}; + return lastCol; +}; -arrayHelpers.arrayEach((0, _editors.getRegisteredEditorNames)(), function (editorName) { - Handsontable.editors[stringHelpers.toUpperCaseFirst(editorName) + 'Editor'] = (0, _editors.getEditor)(editorName); -}); +DataMap.prototype.createMap = function () { + var i = void 0; + var schema = this.getSchema(); -Handsontable.editors.registerEditor = _editors.registerEditor; -Handsontable.editors.getEditor = _editors.getEditor; + if (typeof schema === 'undefined') { + throw new Error('trying to create `columns` definition but you didn\'t provide `schema` nor `data`'); + } -// Export all registered renderers from the Handsontable. -Handsontable.renderers = {}; + this.colToPropCache = []; + this.propToColCache = new _multiMap2.default(); -arrayHelpers.arrayEach((0, _renderers.getRegisteredRendererNames)(), function (rendererName) { - var renderer = (0, _renderers.getRenderer)(rendererName); + var columns = this.instance.getSettings().columns; + + if (columns) { + var maxCols = this.instance.getSettings().maxCols; + var columnsLen = Math.min(maxCols, columns.length); + var filteredIndex = 0; + var columnsAsFunc = false; + var schemaLen = (0, _object.deepObjectSize)(schema); + + if (typeof columns === 'function') { + columnsLen = schemaLen > 0 ? schemaLen : this.instance.countSourceCols(); + columnsAsFunc = true; + } - if (rendererName === 'base') { - Handsontable.renderers.cellDecorator = renderer; - } - Handsontable.renderers[stringHelpers.toUpperCaseFirst(rendererName) + 'Renderer'] = renderer; -}); + for (i = 0; i < columnsLen; i++) { + var column = columnsAsFunc ? columns(i) : columns[i]; -Handsontable.renderers.registerRenderer = _renderers.registerRenderer; -Handsontable.renderers.getRenderer = _renderers.getRenderer; + if ((0, _object.isObject)(column)) { + if (typeof column.data !== 'undefined') { + var index = columnsAsFunc ? filteredIndex : i; + this.colToPropCache[index] = column.data; + this.propToColCache.set(column.data, index); + } -// Export all registered validators from the Handsontable. -Handsontable.validators = {}; + filteredIndex++; + } + } + } else { + this.recursiveDuckColumns(schema); + } +}; -arrayHelpers.arrayEach((0, _validators.getRegisteredValidatorNames)(), function (validatorName) { - Handsontable.validators[stringHelpers.toUpperCaseFirst(validatorName) + 'Validator'] = (0, _validators.getValidator)(validatorName); -}); +/** + * Returns property name that corresponds with the given column index. + * + * @param {Number} col Visual column index. + * @returns {Number} Physical column index. + */ +DataMap.prototype.colToProp = function (col) { + col = this.instance.runHooks('modifyCol', col); -Handsontable.validators.registerValidator = _validators.registerValidator; -Handsontable.validators.getValidator = _validators.getValidator; + if (!isNaN(col) && this.colToPropCache && typeof this.colToPropCache[col] !== 'undefined') { + return this.colToPropCache[col]; + } -// Export all registered plugins from the Handsontable. -Handsontable.plugins = {}; + return col; +}; -arrayHelpers.arrayEach(Object.getOwnPropertyNames(plugins), function (pluginName) { - var plugin = plugins[pluginName]; +/** + * @param {Object} prop + * @fires Hooks#modifyCol + * @returns {*} + */ +DataMap.prototype.propToCol = function (prop) { + var col; - if (pluginName === 'Base') { - Handsontable.plugins[pluginName + 'Plugin'] = plugin; + if (typeof this.propToColCache.get(prop) === 'undefined') { + col = prop; } else { - Handsontable.plugins[pluginName] = plugin; + col = this.propToColCache.get(prop); } -}); + col = this.instance.runHooks('unmodifyCol', col); -Handsontable.plugins.registerPlugin = _plugins.registerPlugin; + return col; +}; -// Export Handsontable -module.exports = Handsontable; +/** + * @returns {Object} + */ +DataMap.prototype.getSchema = function () { + var schema = this.instance.getSettings().dataSchema; -/***/ }), -/* 211 */ -/***/ (function(module, exports, __webpack_require__) { + if (schema) { + if (typeof schema === 'function') { + return schema(); + } + return schema; + } -"use strict"; + return this.duckSchema; +}; +/** + * Creates row at the bottom of the data array. + * + * @param {Number} [index] Physical index of the row before which the new row will be inserted. + * @param {Number} [amount] An amount of rows to add. + * @param {String} [source] Source of method call. + * @fires Hooks#afterCreateRow + * @returns {Number} Returns number of created rows. + */ +DataMap.prototype.createRow = function (index, amount, source) { + var row, + colCount = this.instance.countCols(), + numberOfCreatedRows = 0, + currentIndex; -exports.__esModule = true; + if (!amount) { + amount = 1; + } -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + if (typeof index !== 'number' || index >= this.instance.countSourceRows()) { + index = this.instance.countSourceRows(); + } + this.instance.runHooks('beforeCreateRow', index, amount, source); -function MultiMap() { - var map = { - arrayMap: [], - weakMap: new WeakMap() - }; + currentIndex = index; + var maxRows = this.instance.getSettings().maxRows; - return { - get: function get(key) { - if (canBeAnArrayMapKey(key)) { - return map.arrayMap[key]; - } else if (canBeAWeakMapKey(key)) { - return map.weakMap.get(key); - } - }, - set: function set(key, value) { - if (canBeAnArrayMapKey(key)) { - map.arrayMap[key] = value; - } else if (canBeAWeakMapKey(key)) { - map.weakMap.set(key, value); + while (numberOfCreatedRows < amount && this.instance.countSourceRows() < maxRows) { + if (this.instance.dataType === 'array') { + if (this.instance.getSettings().dataSchema) { + // Clone template array + row = (0, _object.deepClone)(this.getSchema()); } else { - throw new Error('Invalid key type'); - } - }, - delete: function _delete(key) { - if (canBeAnArrayMapKey(key)) { - delete map.arrayMap[key]; - } else if (canBeAWeakMapKey(key)) { - map.weakMap.delete(key); + row = []; + /* eslint-disable no-loop-func */ + (0, _number.rangeEach)(colCount - 1, function () { + return row.push(null); + }); } + } else if (this.instance.dataType === 'function') { + row = this.instance.getSettings().dataSchema(index); + } else { + row = {}; + (0, _object.deepExtend)(row, this.getSchema()); } - }; - function canBeAnArrayMapKey(obj) { - return obj !== null && !isNaNSymbol(obj) && (typeof obj == 'string' || typeof obj == 'number'); + if (index === this.instance.countSourceRows()) { + this.dataSource.push(row); + } else { + this.spliceData(index, 0, row); + } + + numberOfCreatedRows++; + currentIndex++; } - function canBeAWeakMapKey(obj) { - return obj !== null && ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) == 'object' || typeof obj == 'function'); + this.instance.runHooks('afterCreateRow', index, numberOfCreatedRows, source); + this.instance.forceFullRender = true; // used when data was changed + + return numberOfCreatedRows; +}; + +/** + * Creates col at the right of the data array. + * + * @param {Number} [index] Visual index of the column before which the new column will be inserted + * @param {Number} [amount] An amount of columns to add. + * @param {String} [source] Source of method call. + * @fires Hooks#afterCreateCol + * @returns {Number} Returns number of created columns + */ +DataMap.prototype.createCol = function (index, amount, source) { + if (!this.instance.isColumnModificationAllowed()) { + throw new Error('Cannot create new column. When data source in an object, ' + 'you can only have as much columns as defined in first data row, data schema or in the \'columns\' setting.' + 'If you want to be able to add new columns, you have to use array datasource.'); } + var rlen = this.instance.countSourceRows(), + data = this.dataSource, + constructor, + numberOfCreatedCols = 0, + currentIndex; - function isNaNSymbol(obj) { - /* eslint-disable no-self-compare */ - return obj !== obj; // NaN === NaN is always false + if (!amount) { + amount = 1; } -} -exports.default = MultiMap; + if (typeof index !== 'number' || index >= this.instance.countCols()) { + index = this.instance.countCols(); + } + this.instance.runHooks('beforeCreateCol', index, amount, source); -/***/ }), -/* 212 */ -/***/ (function(module, exports, __webpack_require__) { + currentIndex = index; -"use strict"; + var maxCols = this.instance.getSettings().maxCols; + while (numberOfCreatedCols < amount && this.instance.countCols() < maxCols) { + constructor = (0, _setting.columnFactory)(this.GridSettings, this.priv.columnsSettingConflicts); + if (typeof index !== 'number' || index >= this.instance.countCols()) { + if (rlen > 0) { + for (var r = 0; r < rlen; r++) { + if (typeof data[r] === 'undefined') { + data[r] = []; + } + data[r].push(null); + } + } else { + data.push([null]); + } + // Add new column constructor + this.priv.columnSettings.push(constructor); + } else { + for (var _r = 0; _r < rlen; _r++) { + data[_r].splice(currentIndex, 0, null); + } + // Add new column constructor at given index + this.priv.columnSettings.splice(currentIndex, 0, constructor); + } -exports.__esModule = true; + numberOfCreatedCols++; + currentIndex++; + } -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + this.instance.runHooks('afterCreateCol', index, numberOfCreatedCols, source); + this.instance.forceFullRender = true; // used when data was changed -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + return numberOfCreatedCols; +}; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +/** + * Removes row from the data array. + * + * @param {Number} [index] Visual index of the row to be removed. If not provided, the last row will be removed + * @param {Number} [amount] Amount of the rows to be removed. If not provided, one row will be removed + * @param {String} [source] Source of method call. + * @fires Hooks#beforeRemoveRow + * @fires Hooks#afterRemoveRow + */ +DataMap.prototype.removeRow = function (index, amount, source) { + if (!amount) { + amount = 1; + } + if (typeof index !== 'number') { + index = -amount; + } -var _base = __webpack_require__(12); + amount = this.instance.runHooks('modifyRemovedAmount', amount, index); -var _base2 = _interopRequireDefault(_base); + index = (this.instance.countSourceRows() + index) % this.instance.countSourceRows(); -var _array = __webpack_require__(2); + var logicRows = this.visualRowsToPhysical(index, amount); + var actionWasNotCancelled = this.instance.runHooks('beforeRemoveRow', index, amount, logicRows, source); -var _feature = __webpack_require__(34); + if (actionWasNotCancelled === false) { + return; + } -var _element = __webpack_require__(0); + var data = this.dataSource; + var newData = void 0; -var _ghostTable = __webpack_require__(66); + newData = this.filterData(index, amount); -var _ghostTable2 = _interopRequireDefault(_ghostTable); + if (newData) { + data.length = 0; + Array.prototype.push.apply(data, newData); + } -var _object = __webpack_require__(1); + this.instance.runHooks('afterRemoveRow', index, amount, logicRows, source); -var _number = __webpack_require__(6); + this.instance.forceFullRender = true; // used when data was changed +}; -var _plugins = __webpack_require__(5); +/** + * Removes column from the data array. + * + * @param {Number} [index] Visual index of the column to be removed. If not provided, the last column will be removed + * @param {Number} [amount] Amount of the columns to be removed. If not provided, one column will be removed + * @param {String} [source] Source of method call. + * @fires Hooks#beforeRemoveCol + * @fires Hooks#afterRemoveCol + */ +DataMap.prototype.removeCol = function (index, amount, source) { + if (this.instance.dataType === 'object' || this.instance.getSettings().columns) { + throw new Error('cannot remove column with object data source or columns option specified'); + } + if (!amount) { + amount = 1; + } + if (typeof index !== 'number') { + index = -amount; + } -var _samplesGenerator = __webpack_require__(155); + index = (this.instance.countCols() + index) % this.instance.countCols(); -var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator); + var logicColumns = this.visualColumnsToPhysical(index, amount); + var descendingLogicColumns = logicColumns.slice(0).sort(function (a, b) { + return b - a; + }); + var actionWasNotCancelled = this.instance.runHooks('beforeRemoveCol', index, amount, logicColumns, source); -var _string = __webpack_require__(27); + if (actionWasNotCancelled === false) { + return; + } -var _src = __webpack_require__(11); + var isTableUniform = true; + var removedColumnsCount = descendingLogicColumns.length; + var data = this.dataSource; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + for (var c = 0; c < removedColumnsCount; c++) { + if (isTableUniform && logicColumns[0] !== logicColumns[c] - c) { + isTableUniform = false; + } + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + if (isTableUniform) { + for (var r = 0, rlen = this.instance.countSourceRows(); r < rlen; r++) { + data[r].splice(logicColumns[0], amount); + } + } else { + for (var _r2 = 0, _rlen = this.instance.countSourceRows(); _r2 < _rlen; _r2++) { + for (var _c = 0; _c < removedColumnsCount; _c++) { + data[_r2].splice(descendingLogicColumns[_c], 1); + } + } -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + for (var _c2 = 0; _c2 < removedColumnsCount; _c2++) { + this.priv.columnSettings.splice(logicColumns[_c2], 1); + } + } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + this.instance.runHooks('afterRemoveCol', index, amount, logicColumns, source); -var privatePool = new WeakMap(); + this.instance.forceFullRender = true; // used when data was changed +}; /** - * @plugin AutoColumnSize - * - * @description - * This plugin allows to set column widths based on their widest cells. - * - * By default, the plugin is declared as `undefined`, which makes it enabled (same as if it was declared as `true`). - * Enabling this plugin may decrease the overall table performance, as it needs to calculate the widths of all cells to - * resize the columns accordingly. - * If you experience problems with the performance, try turning this feature off and declaring the column widths manually. - * - * Column width calculations are divided into sync and async part. Each of this parts has their own advantages and - * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't - * block the browser UI. - * - * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object: - * ```js - * ... - * // as a number (300 columns in sync, rest async) - * autoColumnSize: {syncLimit: 300}, - * ... - * - * ... - * // as a string (percent) - * autoColumnSize: {syncLimit: '40%'}, - * ... - * ``` - * - * To configure this plugin see {@link Options#autoColumnSize}. - * - * @example - * ```js - * ... - * var hot = new Handsontable(document.getElementById('example'), { - * date: getData(), - * autoColumnSize: true - * }); - * // Access to plugin instance: - * var plugin = hot.getPlugin('autoColumnSize'); - * - * plugin.getColumnWidth(4); + * Add/Removes data from the column. * - * if (plugin.isEnabled()) { - * // code... - * } - * ... - * ``` + * @param {Number} col Physical index of column in which do you want to do splice + * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end + * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed + * @returns {Array} Returns removed portion of columns */ +DataMap.prototype.spliceCol = function (col, index, amount /* , elements... */) { + var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : []; -var AutoColumnSize = function (_BasePlugin) { - _inherits(AutoColumnSize, _BasePlugin); + var colData = this.instance.getDataAtCol(col); + var removed = colData.slice(index, index + amount); + var after = colData.slice(index + amount); - _createClass(AutoColumnSize, null, [{ - key: 'CALCULATION_STEP', - get: function get() { - return 50; - } - }, { - key: 'SYNC_CALCULATION_LIMIT', - get: function get() { - return 50; - } - }]); + (0, _array.extendArray)(elements, after); + var i = 0; + while (i < amount) { + elements.push(null); // add null in place of removed elements + i++; + } + (0, _array.to2dArray)(elements); + this.instance.populateFromArray(index, col, elements, null, null, 'spliceCol'); - function AutoColumnSize(hotInstance) { - _classCallCheck(this, AutoColumnSize); + return removed; +}; - var _this = _possibleConstructorReturn(this, (AutoColumnSize.__proto__ || Object.getPrototypeOf(AutoColumnSize)).call(this, hotInstance)); +/** + * Add/Removes data from the row. + * + * @param {Number} row Physical index of row in which do you want to do splice + * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end. + * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed. + * @returns {Array} Returns removed portion of rows + */ +DataMap.prototype.spliceRow = function (row, index, amount /* , elements... */) { + var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : []; - privatePool.set(_this, { - /** - * Cached column header names. It is used to diff current column headers with previous state and detect which - * columns width should be updated. - * - * @private - * @type {Array} - */ - cachedColumnHeaders: [] - }); - /** - * Cached columns widths. - * - * @type {Array} - */ - _this.widths = []; - /** - * Instance of {@link GhostTable} for rows and columns size calculations. - * - * @type {GhostTable} - */ - _this.ghostTable = new _ghostTable2.default(_this.hot); - /** - * Instance of {@link SamplesGenerator} for generating samples necessary for columns width calculations. - * - * @type {SamplesGenerator} - */ - _this.samplesGenerator = new _samplesGenerator2.default(function (row, col) { - return _this.hot.getDataAtCell(row, col); - }); - /** - * `true` only if the first calculation was performed - * - * @type {Boolean} - */ - _this.firstCalculation = true; - /** - * `true` if the size calculation is in progress. - * - * @type {Boolean} - */ - _this.inProgress = false; + var rowData = this.instance.getSourceDataAtRow(row); + var removed = rowData.slice(index, index + amount); + var after = rowData.slice(index + amount); - // moved to constructor to allow auto-sizing the columns when the plugin is disabled - _this.addHook('beforeColumnResize', function (col, size, isDblClick) { - return _this.onBeforeColumnResize(col, size, isDblClick); - }); - return _this; + (0, _array.extendArray)(elements, after); + var i = 0; + while (i < amount) { + elements.push(null); // add null in place of removed elements + i++; } + this.instance.populateFromArray(row, index, [elements], null, null, 'spliceRow'); - /** - * Check if the plugin is enabled in the handsontable settings. - * - * @returns {Boolean} - */ + return removed; +}; + +/** + * Add/remove row(s) to/from the data source. + * + * @param {Number} index Physical index of the element to remove. + * @param {Number} amount Number of rows to add/remove. + * @param {Object} element Row to add. + */ +DataMap.prototype.spliceData = function (index, amount, element) { + var continueSplicing = this.instance.runHooks('beforeDataSplice', index, amount, element); + + if (continueSplicing !== false) { + this.dataSource.splice(index, amount, element); + } +}; +/** + * Filter unwanted data elements from the data source. + * + * @param {Number} index Visual index of the element to remove. + * @param {Number} amount Number of rows to add/remove. + * @returns {Array} + */ +DataMap.prototype.filterData = function (index, amount) { + var physicalRows = this.visualRowsToPhysical(index, amount); + var continueSplicing = this.instance.runHooks('beforeDataFilter', index, amount, physicalRows); - _createClass(AutoColumnSize, [{ - key: 'isEnabled', - value: function isEnabled() { - return this.hot.getSettings().autoColumnSize !== false && !this.hot.getSettings().colWidths; - } + if (continueSplicing !== false) { + var newData = this.dataSource.filter(function (row, index) { + return physicalRows.indexOf(index) == -1; + }); - /** - * Enable plugin for this Handsontable instance. - */ + return newData; + } +}; - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; +/** + * Returns single value from the data array. + * + * @param {Number} row Visual row index. + * @param {Number} prop + */ +DataMap.prototype.get = function (row, prop) { + row = this.instance.runHooks('modifyRow', row); - if (this.enabled) { - return; - } + var dataRow = this.dataSource[row]; + // TODO: To remove, use 'modifyData' hook instead (see below) + var modifiedRowData = this.instance.runHooks('modifyRowData', row); - var setting = this.hot.getSettings().autoColumnSize; + dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow; + // - if (setting && setting.useHeaders != null) { - this.ghostTable.setSetting('useHeaders', setting.useHeaders); - } + var value = null; - this.addHook('afterLoadData', function () { - return _this2.onAfterLoadData(); - }); - this.addHook('beforeChange', function (changes) { - return _this2.onBeforeChange(changes); - }); + // try to get value under property `prop` (includes dot) + if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) { + value = dataRow[prop]; + } else if (typeof prop === 'string' && prop.indexOf('.') > -1) { + var sliced = prop.split('.'); + var out = dataRow; - this.addHook('beforeRender', function (force) { - return _this2.onBeforeRender(force); - }); - this.addHook('modifyColWidth', function (width, col) { - return _this2.getColumnWidth(col, width); - }); - this.addHook('afterInit', function () { - return _this2.onAfterInit(); - }); - _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'enablePlugin', this).call(this); + if (!out) { + return null; } + for (var i = 0, ilen = sliced.length; i < ilen; i++) { + out = out[sliced[i]]; + if (typeof out === 'undefined') { + return null; + } + } + value = out; + } else if (typeof prop === 'function') { /** - * Update plugin state. + * allows for interacting with complex structures, for example + * d3/jQuery getter/setter properties: + * + * {columns: [{ + * data: function(row, value){ + * if(arguments.length === 1){ + * return row.property(); + * } + * row.property(value); + * } + * }]} */ + value = prop(this.dataSource.slice(row, row + 1)[0]); + } - }, { - key: 'updatePlugin', - value: function updatePlugin() { - var changedColumns = this.findColumnsWhereHeaderWasChanged(); + if (this.instance.hasHook('modifyData')) { + var valueHolder = (0, _object.createObjectPropListener)(value); - if (changedColumns.length) { - this.clearCache(changedColumns); - } - _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'updatePlugin', this).call(this); + this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'get'); + + if (valueHolder.isTouched()) { + value = valueHolder.value; } + } - /** - * Disable plugin for this Handsontable instance. - */ + return value; +}; - }, { - key: 'disablePlugin', - value: function disablePlugin() { - _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'disablePlugin', this).call(this); - } +var copyableLookup = (0, _data.cellMethodLookupFactory)('copyable', false); - /** - * Calculate a columns width. - * - * @param {Number|Object} colRange Column range object. - * @param {Number|Object} rowRange Row range object. - * @param {Boolean} [force=false] If `true` force calculate width even when value was cached earlier. - */ +/** + * Returns single value from the data array (intended for clipboard copy to an external application). + * + * @param {Number} row Physical row index. + * @param {Number} prop + * @returns {String} + */ +DataMap.prototype.getCopyable = function (row, prop) { + if (copyableLookup.call(this.instance, row, this.propToCol(prop))) { + return this.get(row, prop); + } + return ''; +}; - }, { - key: 'calculateColumnsWidth', - value: function calculateColumnsWidth() { - var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countCols() - 1 }; +/** + * Saves single value to the data array. + * + * @param {Number} row Visual row index. + * @param {Number} prop + * @param {String} value + * @param {String} [source] Source of hook runner. + */ +DataMap.prototype.set = function (row, prop, value, source) { + row = this.instance.runHooks('modifyRow', row, source || 'datamapGet'); - var _this3 = this; + var dataRow = this.dataSource[row]; + // TODO: To remove, use 'modifyData' hook instead (see below) + var modifiedRowData = this.instance.runHooks('modifyRowData', row); - var rowRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { from: 0, to: this.hot.countRows() - 1 }; - var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow; + // - if (typeof colRange === 'number') { - colRange = { from: colRange, to: colRange }; - } - if (typeof rowRange === 'number') { - rowRange = { from: rowRange, to: rowRange }; - } + if (this.instance.hasHook('modifyData')) { + var valueHolder = (0, _object.createObjectPropListener)(value); - (0, _number.rangeEach)(colRange.from, colRange.to, function (col) { - if (force || _this3.widths[col] === void 0 && !_this3.hot._getColWidthFromSettings(col)) { - var samples = _this3.samplesGenerator.generateColumnSamples(col, rowRange); + this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'set'); - samples.forEach(function (sample, col) { - return _this3.ghostTable.addColumn(col, sample); - }); - } - }); + if (valueHolder.isTouched()) { + value = valueHolder.value; + } + } - if (this.ghostTable.columns.length) { - this.ghostTable.getWidths(function (col, width) { - _this3.widths[col] = width; - }); - this.ghostTable.clean(); + // try to set value under property `prop` (includes dot) + if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) { + dataRow[prop] = value; + } else if (typeof prop === 'string' && prop.indexOf('.') > -1) { + var sliced = prop.split('.'); + var out = dataRow; + var i = 0; + var ilen = void 0; + + for (i = 0, ilen = sliced.length - 1; i < ilen; i++) { + if (typeof out[sliced[i]] === 'undefined') { + out[sliced[i]] = {}; } + out = out[sliced[i]]; } + out[sliced[i]] = value; + } else if (typeof prop === 'function') { + /* see the `function` handler in `get` */ + prop(this.dataSource.slice(row, row + 1)[0], value); + } else { + dataRow[prop] = value; + } +}; - /** - * Calculate all columns width. - * - * @param {Object|Number} rowRange Row range object. - */ - - }, { - key: 'calculateAllColumnsWidth', - value: function calculateAllColumnsWidth() { - var _this4 = this; +/** + * This ridiculous piece of code maps rows Id that are present in table data to those displayed for user. + * The trick is, the physical row id (stored in settings.data) is not necessary the same + * as the visual (displayed) row id (e.g. when sorting is applied). + * + * @param {Number} index Visual row index. + * @param {Number} amount + * @fires Hooks#modifyRow + * @returns {Number} + */ +DataMap.prototype.visualRowsToPhysical = function (index, amount) { + var totalRows = this.instance.countSourceRows(); + var physicRow = (totalRows + index) % totalRows; + var logicRows = []; + var rowsToRemove = amount; + var row; - var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countRows() - 1 }; + while (physicRow < totalRows && rowsToRemove) { + row = this.instance.runHooks('modifyRow', physicRow); + logicRows.push(row); - var current = 0; - var length = this.hot.countCols() - 1; - var timer = null; + rowsToRemove--; + physicRow++; + } - this.inProgress = true; + return logicRows; +}; - var loop = function loop() { - // When hot was destroyed after calculating finished cancel frame - if (!_this4.hot) { - (0, _feature.cancelAnimationFrame)(timer); - _this4.inProgress = false; +/** + * + * @param index Visual column index. + * @param amount + * @returns {Array} + */ +DataMap.prototype.visualColumnsToPhysical = function (index, amount) { + var totalCols = this.instance.countCols(); + var physicalCol = (totalCols + index) % totalCols; + var visualCols = []; + var colsToRemove = amount; - return; - } + while (physicalCol < totalCols && colsToRemove) { + var col = this.instance.runHooks('modifyCol', physicalCol); - _this4.calculateColumnsWidth({ - from: current, - to: Math.min(current + AutoColumnSize.CALCULATION_STEP, length) - }, rowRange); + visualCols.push(col); - current = current + AutoColumnSize.CALCULATION_STEP + 1; + colsToRemove--; + physicalCol++; + } - if (current < length) { - timer = (0, _feature.requestAnimationFrame)(loop); - } else { - (0, _feature.cancelAnimationFrame)(timer); - _this4.inProgress = false; + return visualCols; +}; - // @TODO Should call once per render cycle, currently fired separately in different plugins - _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); - // tmp - if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) { - _this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw(); - } - } - }; - // sync - if (this.firstCalculation && this.getSyncCalculationLimit()) { - this.calculateColumnsWidth({ from: 0, to: this.getSyncCalculationLimit() }, rowRange); - this.firstCalculation = false; - current = this.getSyncCalculationLimit() + 1; - } - // async - if (current < length) { - loop(); - } else { - this.inProgress = false; - } +/** + * Clears the data array. + */ +DataMap.prototype.clear = function () { + for (var r = 0; r < this.instance.countSourceRows(); r++) { + for (var c = 0; c < this.instance.countCols(); c++) { + this.set(r, this.colToProp(c), ''); } + } +}; - /** - * Set the sampling options. - * - * @private - */ +/** + * Clear cached data length. + */ +DataMap.prototype.clearLengthCache = function () { + this.cachedLength = null; +}; - }, { - key: 'setSamplingOptions', - value: function setSamplingOptions() { - var setting = this.hot.getSettings().autoColumnSize; - var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoColumnSize.samplingRatio : void 0; - var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoColumnSize.allowSampleDuplicates : void 0; +/** + * Get data length. + * + * @returns {Number} + */ +DataMap.prototype.getLength = function () { + var _this2 = this; - if (samplingRatio && !isNaN(samplingRatio)) { - this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10)); - } + var maxRows = void 0, + maxRowsFromSettings = this.instance.getSettings().maxRows; - if (allowSampleDuplicates) { - this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates); - } + if (maxRowsFromSettings < 0 || maxRowsFromSettings === 0) { + maxRows = 0; + } else { + maxRows = maxRowsFromSettings || Infinity; + } + + var length = this.instance.countSourceRows(); + + if (this.instance.hasHook('modifyRow')) { + var reValidate = this.skipCache; + + this.interval.start(); + if (length !== this.latestSourceRowsCount) { + reValidate = true; } - /** - * Recalculate all columns width (overwrite cache values). - */ + this.latestSourceRowsCount = length; + if (this.cachedLength === null || reValidate) { + (0, _number.rangeEach)(length - 1, function (row) { + row = _this2.instance.runHooks('modifyRow', row); - }, { - key: 'recalculateAllColumnsWidth', - value: function recalculateAllColumnsWidth() { - if (this.hot.view && (0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) { - this.clearCache(); - this.calculateAllColumnsWidth(); - } + if (row === null) { + --length; + } + }); + this.cachedLength = length; + } else { + length = this.cachedLength; } + } else { + this.interval.stop(); + } - /** - * Get value which tells how many columns should be calculated synchronously. Rest of the columns will be calculated asynchronously. - * - * @returns {Number} - */ + return Math.min(length, maxRows); +}; - }, { - key: 'getSyncCalculationLimit', - value: function getSyncCalculationLimit() { - /* eslint-disable no-bitwise */ - var limit = AutoColumnSize.SYNC_CALCULATION_LIMIT; - var colsLimit = this.hot.countCols() - 1; +/** + * Returns the data array. + * + * @returns {Array} + */ +DataMap.prototype.getAll = function () { + var start = { + row: 0, + col: 0 + }; - if ((0, _object.isObject)(this.hot.getSettings().autoColumnSize)) { - limit = this.hot.getSettings().autoColumnSize.syncLimit; + var end = { + row: Math.max(this.instance.countSourceRows() - 1, 0), + col: Math.max(this.instance.countCols() - 1, 0) + }; - if ((0, _string.isPercentValue)(limit)) { - limit = (0, _number.valueAccordingPercent)(colsLimit, limit); - } else { - // Force to Number - limit >>= 0; - } - } + if (start.row - end.row === 0 && !this.instance.countSourceRows()) { + return []; + } - return Math.min(limit, colsLimit); - } + return this.getRange(start, end, DataMap.prototype.DESTINATION_RENDERER); +}; - /** - * Get the calculated column width. - * - * @param {Number} col Column index. - * @param {Number} [defaultWidth] Default column width. It will be picked up if no calculated width found. - * @param {Boolean} [keepMinimum=true] If `true` then returned value won't be smaller then 50 (default column width). - * @returns {Number} - */ +/** + * Returns data range as array. + * + * @param {Object} [start] Start selection position. Visual indexes. + * @param {Object} [end] End selection position. Visual indexes. + * @param {Number} destination Destination of datamap.get + * @returns {Array} + */ +DataMap.prototype.getRange = function (start, end, destination) { + var r, + rlen, + c, + clen, + output = [], + row; - }, { - key: 'getColumnWidth', - value: function getColumnWidth(col) { - var defaultWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0; - var keepMinimum = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + var maxRows = this.instance.getSettings().maxRows; + var maxCols = this.instance.getSettings().maxCols; - var width = defaultWidth; + if (maxRows === 0 || maxCols === 0) { + return []; + } - if (width === void 0) { - width = this.widths[col]; + var getFn = destination === this.DESTINATION_CLIPBOARD_GENERATOR ? this.getCopyable : this.get; - if (keepMinimum && typeof width === 'number') { - width = Math.max(width, _src.ViewportColumnsCalculator.DEFAULT_WIDTH); - } - } + rlen = Math.min(Math.max(maxRows - 1, 0), Math.max(start.row, end.row)); + clen = Math.min(Math.max(maxCols - 1, 0), Math.max(start.col, end.col)); - return width; + for (r = Math.min(start.row, end.row); r <= rlen; r++) { + row = []; + var physicalRow = this.instance.runHooks('modifyRow', r); + + for (c = Math.min(start.col, end.col); c <= clen; c++) { + + if (physicalRow === null) { + break; + } + row.push(getFn.call(this, r, this.colToProp(c))); + } + if (physicalRow !== null) { + output.push(row); } + } - /** - * Get the first visible column. - * - * @returns {Number} Returns column index or -1 if table is not rendered. - */ + return output; +}; - }, { - key: 'getFirstVisibleColumn', - value: function getFirstVisibleColumn() { - var wot = this.hot.view.wt; +/** + * Return data as text (tab separated columns). + * + * @param {Object} [start] Start selection position. Visual indexes. + * @param {Object} [end] End selection position. Visual indexes. + * @returns {String} + */ +DataMap.prototype.getText = function (start, end) { + return _SheetClip2.default.stringify(this.getRange(start, end, this.DESTINATION_RENDERER)); +}; + +/** + * Return data as copyable text (tab separated columns intended for clipboard copy to an external application). + * + * @param {Object} [start] Start selection position. Visual indexes. + * @param {Object} [end] End selection position. Visual indexes. + * @returns {String} + */ +DataMap.prototype.getCopyableText = function (start, end) { + return _SheetClip2.default.stringify(this.getRange(start, end, this.DESTINATION_CLIPBOARD_GENERATOR)); +}; + +/** + * `skipLengthCache` callback. + * @private + * @param {Number} delay Time of the delay in milliseconds. + */ +DataMap.prototype.onSkipLengthCache = function (delay) { + var _this3 = this; - if (wot.wtViewport.columnsVisibleCalculator) { - return wot.wtTable.getFirstVisibleColumn(); - } - if (wot.wtViewport.columnsRenderCalculator) { - return wot.wtTable.getFirstRenderedColumn(); - } + this.skipCache = true; + setTimeout(function () { + _this3.skipCache = false; + }, delay); +}; - return -1; - } +/** + * Destroy instance. + */ +DataMap.prototype.destroy = function () { + this.interval.stop(); - /** - * Get the last visible column. - * - * @returns {Number} Returns column index or -1 if table is not rendered. - */ + this.interval = null; + this.instance = null; + this.priv = null; + this.GridSettings = null; + this.dataSource = null; + this.cachedLength = null; + this.duckSchema = null; +}; - }, { - key: 'getLastVisibleColumn', - value: function getLastVisibleColumn() { - var wot = this.hot.view.wt; +exports.default = DataMap; - if (wot.wtViewport.columnsVisibleCalculator) { - return wot.wtTable.getLastVisibleColumn(); - } - if (wot.wtViewport.columnsRenderCalculator) { - return wot.wtTable.getLastRenderedColumn(); - } +/***/ }), +/* 241 */ +/***/ (function(module, exports, __webpack_require__) { - return -1; - } +"use strict"; - /** - * Collects all columns which titles has been changed in comparison to the previous state. - * - * @returns {Array} It returns an array of physical column indexes. - */ - }, { - key: 'findColumnsWhereHeaderWasChanged', - value: function findColumnsWhereHeaderWasChanged() { - var columnHeaders = this.hot.getColHeader(); +exports.__esModule = true; - var _privatePool$get = privatePool.get(this), - cachedColumnHeaders = _privatePool$get.cachedColumnHeaders; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var changedColumns = (0, _array.arrayReduce)(columnHeaders, function (acc, columnTitle, physicalColumn) { - var cachedColumnsLength = cachedColumnHeaders.length; +exports.parseDelay = parseDelay; - if (cachedColumnsLength - 1 < physicalColumn || cachedColumnHeaders[physicalColumn] !== columnTitle) { - acc.push(physicalColumn); - } - if (cachedColumnsLength - 1 < physicalColumn) { - cachedColumnHeaders.push(columnTitle); - } else { - cachedColumnHeaders[physicalColumn] = columnTitle; - } +var _feature = __webpack_require__(34); - return acc; - }, []); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - return changedColumns; +/** + * @class Interval + * @util + */ +var Interval = function () { + _createClass(Interval, null, [{ + key: 'create', + value: function create(func, delay) { + return new Interval(func, delay); } + }]); + + function Interval(func, delay) { + var _this = this; + + _classCallCheck(this, Interval); /** - * Clear cache of calculated column widths. If you want to clear only selected columns pass an array with their indexes. - * Otherwise whole cache will be cleared. + * Animation frame request id. * - * @param {Array} [columns=[]] List of column indexes (physical indexes) to clear. + * @type {Number} */ - - }, { - key: 'clearCache', - value: function clearCache() { - var _this5 = this; - - var columns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; - - if (columns.length) { - (0, _array.arrayEach)(columns, function (physicalIndex) { - _this5.widths[physicalIndex] = void 0; - }); - } else { - this.widths.length = 0; - } - } - + this.timer = null; /** - * Check if all widths were calculated. If not then return `true` (need recalculate). + * Function to invoke repeatedly. * - * @returns {Boolean} + * @type {Function} */ - - }, { - key: 'isNeedRecalculate', - value: function isNeedRecalculate() { - return !!(0, _array.arrayFilter)(this.widths, function (item) { - return item === void 0; - }).length; - } - + this.func = func; /** - * On before render listener. + * Number of milliseconds that function should wait before next call. + */ + this.delay = parseDelay(delay); + /** + * Flag which indicates if interval object was stopped. * - * @private + * @type {Boolean} + * @default true */ - - }, { - key: 'onBeforeRender', - value: function onBeforeRender() { - var force = this.hot.renderCall; - var rowsCount = this.hot.countRows(); - - // Keep last column widths unchanged for situation when all rows was deleted or trimmed (pro #6) - if (!rowsCount) { - return; - } - - this.calculateColumnsWidth({ from: this.getFirstVisibleColumn(), to: this.getLastVisibleColumn() }, void 0, force); - - if (this.isNeedRecalculate() && !this.inProgress) { - this.calculateAllColumnsWidth(); - } - } - + this.stopped = true; /** - * On after load data listener. + * Interval time (in milliseconds) of the last callback call. * * @private + * @type {Number} */ - - }, { - key: 'onAfterLoadData', - value: function onAfterLoadData() { - var _this6 = this; - - if (this.hot.view) { - this.recalculateAllColumnsWidth(); - } else { - // first load - initialization - setTimeout(function () { - if (_this6.hot) { - _this6.recalculateAllColumnsWidth(); - } - }, 0); - } - } - + this._then = null; /** - * On before change listener. + * Bounded function `func`. * * @private - * @param {Array} changes + * @type {Function} */ + this._callback = function () { + return _this.__callback(); + }; + } - }, { - key: 'onBeforeChange', - value: function onBeforeChange(changes) { - var _this7 = this; + /** + * Start loop. + * + * @returns {Interval} + */ - var changedColumns = (0, _array.arrayMap)(changes, function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - row = _ref2[0], - column = _ref2[1]; - return _this7.hot.propToCol(column); - }); + _createClass(Interval, [{ + key: 'start', + value: function start() { + if (this.stopped) { + this._then = Date.now(); + this.stopped = false; + this.timer = (0, _feature.requestAnimationFrame)(this._callback); + } - this.clearCache(changedColumns); + return this; } /** - * On before column resize listener. + * Stop looping. * - * @private - * @param {Number} col - * @param {Number} size - * @param {Boolean} isDblClick - * @returns {Number} + * @returns {Interval} */ }, { - key: 'onBeforeColumnResize', - value: function onBeforeColumnResize(col, size, isDblClick) { - if (isDblClick) { - this.calculateColumnsWidth(col, void 0, true); - size = this.getColumnWidth(col, void 0, false); + key: 'stop', + value: function stop() { + if (!this.stopped) { + this.stopped = true; + (0, _feature.cancelAnimationFrame)(this.timer); + this.timer = null; } - return size; + return this; } /** - * On after Handsontable init fill plugin with all necessary values. + * Loop callback, fired on every animation frame. * * @private */ }, { - key: 'onAfterInit', - value: function onAfterInit() { - privatePool.get(this).cachedColumnHeaders = this.hot.getColHeader(); - } + key: '__callback', + value: function __callback() { + this.timer = (0, _feature.requestAnimationFrame)(this._callback); - /** - * Destroy plugin instance. - */ + if (this.delay) { + var now = Date.now(); + var elapsed = now - this._then; - }, { - key: 'destroy', - value: function destroy() { - this.ghostTable.clean(); - _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'destroy', this).call(this); + if (elapsed > this.delay) { + this._then = now - elapsed % this.delay; + this.func(); + } + } else { + this.func(); + } } }]); - return AutoColumnSize; -}(_base2.default); + return Interval; +}(); -(0, _plugins.registerPlugin)('autoColumnSize', AutoColumnSize); +exports.default = Interval; +function parseDelay(delay) { + if (typeof delay === 'string' && /fps$/.test(delay)) { + delay = 1000 / parseInt(delay.replace('fps', '') || 0, 10); + } -exports.default = AutoColumnSize; + return delay; +} /***/ }), -/* 213 */ +/* 242 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48779,2537 +48904,2422 @@ exports.default = AutoColumnSize; exports.__esModule = true; -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +function MultiMap() { + var map = { + arrayMap: [], + weakMap: new WeakMap() + }; -var _base = __webpack_require__(12); + return { + get: function get(key) { + if (canBeAnArrayMapKey(key)) { + return map.arrayMap[key]; + } else if (canBeAWeakMapKey(key)) { + return map.weakMap.get(key); + } + }, + set: function set(key, value) { + if (canBeAnArrayMapKey(key)) { + map.arrayMap[key] = value; + } else if (canBeAWeakMapKey(key)) { + map.weakMap.set(key, value); + } else { + throw new Error('Invalid key type'); + } + }, + delete: function _delete(key) { + if (canBeAnArrayMapKey(key)) { + delete map.arrayMap[key]; + } else if (canBeAWeakMapKey(key)) { + map.weakMap.delete(key); + } + } + }; -var _base2 = _interopRequireDefault(_base); + function canBeAnArrayMapKey(obj) { + return obj !== null && !isNaNSymbol(obj) && (typeof obj == 'string' || typeof obj == 'number'); + } -var _array = __webpack_require__(2); + function canBeAWeakMapKey(obj) { + return obj !== null && ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) == 'object' || typeof obj == 'function'); + } -var _feature = __webpack_require__(34); + function isNaNSymbol(obj) { + /* eslint-disable no-self-compare */ + return obj !== obj; // NaN === NaN is always false + } +} -var _element = __webpack_require__(0); +exports.default = MultiMap; -var _ghostTable = __webpack_require__(66); +/***/ }), +/* 243 */ +/***/ (function(module, exports, __webpack_require__) { -var _ghostTable2 = _interopRequireDefault(_ghostTable); +"use strict"; -var _object = __webpack_require__(1); -var _number = __webpack_require__(6); +exports.__esModule = true; -var _plugins = __webpack_require__(5); +var _src = __webpack_require__(12); -var _samplesGenerator = __webpack_require__(155); +var _unicode = __webpack_require__(17); -var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator); +var _event = __webpack_require__(8); -var _string = __webpack_require__(27); +var _editors = __webpack_require__(15); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _eventManager = __webpack_require__(4); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var _eventManager2 = _interopRequireDefault(_eventManager); -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +var _baseEditor = __webpack_require__(41); -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -/** - * @plugin AutoRowSize - * - * @description - * This plugin allows to set row heights based on their highest cells. - * - * By default, the plugin is declared as `undefined`, which makes it disabled (same as if it was declared as `false`). - * Enabling this plugin may decrease the overall table performance, as it needs to calculate the heights of all cells to - * resize the rows accordingly. - * If you experience problems with the performance, try turning this feature off and declaring the row heights manually. - * - * Row height calculations are divided into sync and async part. Each of this parts has their own advantages and - * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't - * block the browser UI. - * - * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object: - * ```js - * ... - * // as a number (300 columns in sync, rest async) - * autoRowSize: {syncLimit: 300}, - * ... - * - * ... - * // as a string (percent) - * autoRowSize: {syncLimit: '40%'}, - * ... - * ``` - * - * You can also use the `allowSampleDuplicates` option to allow sampling duplicate values when calculating the row height. Note, that this might have - * a negative impact on performance. - * - * To configure this plugin see {@link Options#autoRowSize}. - * - * @example - * - * ```js - * ... - * var hot = new Handsontable(document.getElementById('example'), { - * date: getData(), - * autoRowSize: true - * }); - * // Access to plugin instance: - * var plugin = hot.getPlugin('autoRowSize'); - * - * plugin.getRowHeight(4); - * - * if (plugin.isEnabled()) { - * // code... - * } - * ... - * ``` - */ -var AutoRowSize = function (_BasePlugin) { - _inherits(AutoRowSize, _BasePlugin); +function EditorManager(instance, priv, selection) { + var _this = this, + destroyed = false, + eventManager, + activeEditor; - _createClass(AutoRowSize, null, [{ - key: 'CALCULATION_STEP', - get: function get() { - return 50; + eventManager = new _eventManager2.default(instance); + + function moveSelectionAfterEnter(shiftKey) { + selection.setSelectedHeaders(false, false, false); + var enterMoves = typeof priv.settings.enterMoves === 'function' ? priv.settings.enterMoves(event) : priv.settings.enterMoves; + + if (shiftKey) { + // move selection up + selection.transformStart(-enterMoves.row, -enterMoves.col); + } else { + // move selection down (add a new row if needed) + selection.transformStart(enterMoves.row, enterMoves.col, true); } - }, { - key: 'SYNC_CALCULATION_LIMIT', - get: function get() { - return 500; + } + + function moveSelectionUp(shiftKey) { + if (shiftKey) { + if (selection.selectedHeader.cols) { + selection.setSelectedHeaders(selection.selectedHeader.rows, false, false); + } + selection.transformEnd(-1, 0); + } else { + selection.setSelectedHeaders(false, false, false); + selection.transformStart(-1, 0); } - }]); + } - function AutoRowSize(hotInstance) { - _classCallCheck(this, AutoRowSize); + function moveSelectionDown(shiftKey) { + if (shiftKey) { + // expanding selection down with shift + selection.transformEnd(1, 0); + } else { + selection.setSelectedHeaders(false, false, false); + selection.transformStart(1, 0); + } + } - /** - * Cached rows heights. - * - * @type {Array} - */ - var _this = _possibleConstructorReturn(this, (AutoRowSize.__proto__ || Object.getPrototypeOf(AutoRowSize)).call(this, hotInstance)); + function moveSelectionRight(shiftKey) { + if (shiftKey) { + selection.transformEnd(0, 1); + } else { + selection.setSelectedHeaders(false, false, false); + selection.transformStart(0, 1); + } + } - _this.heights = []; - /** - * Instance of {@link GhostTable} for rows and columns size calculations. - * - * @type {GhostTable} - */ - _this.ghostTable = new _ghostTable2.default(_this.hot); - /** - * Instance of {@link SamplesGenerator} for generating samples necessary for rows height calculations. - * - * @type {SamplesGenerator} - */ - _this.samplesGenerator = new _samplesGenerator2.default(function (row, col) { - if (row >= 0) { - return _this.hot.getDataAtCell(row, col); - } else if (row === -1) { - return _this.hot.getColHeader(col); + function moveSelectionLeft(shiftKey) { + if (shiftKey) { + if (selection.selectedHeader.rows) { + selection.setSelectedHeaders(false, selection.selectedHeader.cols, false); } - return null; - }); - /** - * `true` if only the first calculation was performed. - * - * @type {Boolean} - */ - _this.firstCalculation = true; - /** - * `true` if the size calculation is in progress. - * - * @type {Boolean} - */ - _this.inProgress = false; - - // moved to constructor to allow auto-sizing the rows when the plugin is disabled - _this.addHook('beforeRowResize', function (row, size, isDblClick) { - return _this.onBeforeRowResize(row, size, isDblClick); - }); - return _this; + selection.transformEnd(0, -1); + } else { + selection.setSelectedHeaders(false, false, false); + selection.transformStart(0, -1); + } } - /** - * Check if the plugin is enabled in the Handsontable settings. - * - * @returns {Boolean} - */ + function onKeyDown(event) { + var ctrlDown, rangeModifier; + if (!instance.isListening()) { + return; + } + instance.runHooks('beforeKeyDown', event); - _createClass(AutoRowSize, [{ - key: 'isEnabled', - value: function isEnabled() { - return this.hot.getSettings().autoRowSize === true || (0, _object.isObject)(this.hot.getSettings().autoRowSize); + if (destroyed) { + return; + } + if ((0, _event.isImmediatePropagationStopped)(event)) { + return; } + priv.lastKeyCode = event.keyCode; - /** - * Enable plugin for this Handsontable instance. - */ + if (!selection.isSelected()) { + return; + } + // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL) + ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + if (activeEditor && !activeEditor.isWaiting()) { + if (!(0, _unicode.isMetaKey)(event.keyCode) && !(0, _unicode.isCtrlKey)(event.keyCode) && !ctrlDown && !_this.isEditorOpened()) { + _this.openEditor('', event); - if (this.enabled) { return; } - - this.setSamplingOptions(); - - this.addHook('afterLoadData', function () { - return _this2.onAfterLoadData(); - }); - this.addHook('beforeChange', function (changes) { - return _this2.onBeforeChange(changes); - }); - this.addHook('beforeColumnMove', function () { - return _this2.recalculateAllRowsHeight(); - }); - this.addHook('beforeColumnResize', function () { - return _this2.recalculateAllRowsHeight(); - }); - this.addHook('beforeColumnSort', function () { - return _this2.clearCache(); - }); - this.addHook('beforeRender', function (force) { - return _this2.onBeforeRender(force); - }); - this.addHook('beforeRowMove', function (rowStart, rowEnd) { - return _this2.onBeforeRowMove(rowStart, rowEnd); - }); - this.addHook('modifyRowHeight', function (height, row) { - return _this2.getRowHeight(row, height); - }); - this.addHook('modifyColumnHeaderHeight', function () { - return _this2.getColumnHeaderHeight(); - }); - _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'enablePlugin', this).call(this); } + rangeModifier = event.shiftKey ? selection.setRangeEnd : selection.setRangeStart; - /** - * Disable plugin for this Handsontable instance. - */ + switch (event.keyCode) { + case _unicode.KEY_CODES.A: + if (!_this.isEditorOpened() && ctrlDown) { + selection.selectAll(); - }, { - key: 'disablePlugin', - value: function disablePlugin() { - _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'disablePlugin', this).call(this); - } + event.preventDefault(); + (0, _event.stopPropagation)(event); + } + break; - /** - * Calculate a given rows height. - * - * @param {Number|Object} rowRange Row range object. - * @param {Number|Object} colRange Column range object. - * @param {Boolean} [force=false] If `true` force calculate height even when value was cached earlier. - */ + case _unicode.KEY_CODES.ARROW_UP: + if (_this.isEditorOpened() && !activeEditor.isWaiting()) { + _this.closeEditorAndSaveChanges(ctrlDown); + } + moveSelectionUp(event.shiftKey); - }, { - key: 'calculateRowsHeight', - value: function calculateRowsHeight() { - var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countRows() - 1 }; + event.preventDefault(); + (0, _event.stopPropagation)(event); + break; - var _this3 = this; + case _unicode.KEY_CODES.ARROW_DOWN: + if (_this.isEditorOpened() && !activeEditor.isWaiting()) { + _this.closeEditorAndSaveChanges(ctrlDown); + } - var colRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { from: 0, to: this.hot.countCols() - 1 }; - var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + moveSelectionDown(event.shiftKey); - if (typeof rowRange === 'number') { - rowRange = { from: rowRange, to: rowRange }; - } - if (typeof colRange === 'number') { - colRange = { from: colRange, to: colRange }; - } + event.preventDefault(); + (0, _event.stopPropagation)(event); + break; - if (this.hot.getColHeader(0) !== null) { - var samples = this.samplesGenerator.generateRowSamples(-1, colRange); + case _unicode.KEY_CODES.ARROW_RIGHT: + if (_this.isEditorOpened() && !activeEditor.isWaiting()) { + _this.closeEditorAndSaveChanges(ctrlDown); + } - this.ghostTable.addColumnHeadersRow(samples.get(-1)); - } + moveSelectionRight(event.shiftKey); - (0, _number.rangeEach)(rowRange.from, rowRange.to, function (row) { - // For rows we must calculate row height even when user had set height value manually. - // We can shrink column but cannot shrink rows! - if (force || _this3.heights[row] === void 0) { - var _samples = _this3.samplesGenerator.generateRowSamples(row, colRange); + event.preventDefault(); + (0, _event.stopPropagation)(event); + break; - _samples.forEach(function (sample, row) { - _this3.ghostTable.addRow(row, sample); - }); + case _unicode.KEY_CODES.ARROW_LEFT: + if (_this.isEditorOpened() && !activeEditor.isWaiting()) { + _this.closeEditorAndSaveChanges(ctrlDown); } - }); - if (this.ghostTable.rows.length) { - this.ghostTable.getHeights(function (row, height) { - _this3.heights[row] = height; - }); - this.ghostTable.clean(); - } - } - /** - * Calculate the height of all the rows. - * - * @param {Object|Number} colRange Column range object. - */ + moveSelectionLeft(event.shiftKey); - }, { - key: 'calculateAllRowsHeight', - value: function calculateAllRowsHeight() { - var _this4 = this; + event.preventDefault(); + (0, _event.stopPropagation)(event); + break; - var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countCols() - 1 }; + case _unicode.KEY_CODES.TAB: + selection.setSelectedHeaders(false, false, false); + var tabMoves = typeof priv.settings.tabMoves === 'function' ? priv.settings.tabMoves(event) : priv.settings.tabMoves; - var current = 0; - var length = this.hot.countRows() - 1; - var timer = null; + if (event.shiftKey) { + // move selection left + selection.transformStart(-tabMoves.row, -tabMoves.col); + } else { + // move selection right (add a new column if needed) + selection.transformStart(tabMoves.row, tabMoves.col, true); + } + event.preventDefault(); + (0, _event.stopPropagation)(event); + break; - this.inProgress = true; + case _unicode.KEY_CODES.BACKSPACE: + case _unicode.KEY_CODES.DELETE: + selection.empty(event); + _this.prepareEditor(); + event.preventDefault(); + break; - var loop = function loop() { - // When hot was destroyed after calculating finished cancel frame - if (!_this4.hot) { - (0, _feature.cancelAnimationFrame)(timer); - _this4.inProgress = false; + case _unicode.KEY_CODES.F2: + /* F2 */ + _this.openEditor(null, event); - return; + if (activeEditor) { + activeEditor.enableFullEditMode(); } - _this4.calculateRowsHeight({ from: current, to: Math.min(current + AutoRowSize.CALCULATION_STEP, length) }, colRange); - current = current + AutoRowSize.CALCULATION_STEP + 1; + event.preventDefault(); // prevent Opera from opening 'Go to Page dialog' + break; - if (current < length) { - timer = (0, _feature.requestAnimationFrame)(loop); - } else { - (0, _feature.cancelAnimationFrame)(timer); - _this4.inProgress = false; + case _unicode.KEY_CODES.ENTER: + /* return/enter */ + if (_this.isEditorOpened()) { - // @TODO Should call once per render cycle, currently fired separately in different plugins - _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); - // tmp - if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) { - _this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw(); + if (activeEditor && activeEditor.state !== _baseEditor.EditorState.WAITING) { + _this.closeEditorAndSaveChanges(ctrlDown); } - } - }; - // sync - if (this.firstCalculation && this.getSyncCalculationLimit()) { - this.calculateRowsHeight({ from: 0, to: this.getSyncCalculationLimit() }, colRange); - this.firstCalculation = false; - current = this.getSyncCalculationLimit() + 1; - } - // async - if (current < length) { - loop(); - } else { - this.inProgress = false; - this.hot.view.wt.wtOverlays.adjustElementsSize(false); - } - } + moveSelectionAfterEnter(event.shiftKey); + } else if (instance.getSettings().enterBeginsEditing) { + _this.openEditor(null, event); - /** - * Set the sampling options. - * - * @private - */ + if (activeEditor) { + activeEditor.enableFullEditMode(); + } + } else { + moveSelectionAfterEnter(event.shiftKey); + } + event.preventDefault(); // don't add newline to field + (0, _event.stopImmediatePropagation)(event); // required by HandsontableEditor + break; - }, { - key: 'setSamplingOptions', - value: function setSamplingOptions() { - var setting = this.hot.getSettings().autoRowSize; - var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoRowSize.samplingRatio : void 0; - var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoRowSize.allowSampleDuplicates : void 0; + case _unicode.KEY_CODES.ESCAPE: + if (_this.isEditorOpened()) { + _this.closeEditorAndRestoreOriginalValue(ctrlDown); + } + event.preventDefault(); + break; - if (samplingRatio && !isNaN(samplingRatio)) { - this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10)); - } + case _unicode.KEY_CODES.HOME: + selection.setSelectedHeaders(false, false, false); + if (event.ctrlKey || event.metaKey) { + rangeModifier(new _src.CellCoords(0, priv.selRange.from.col)); + } else { + rangeModifier(new _src.CellCoords(priv.selRange.from.row, 0)); + } + event.preventDefault(); // don't scroll the window + (0, _event.stopPropagation)(event); + break; - if (allowSampleDuplicates) { - this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates); - } - } + case _unicode.KEY_CODES.END: + selection.setSelectedHeaders(false, false, false); + if (event.ctrlKey || event.metaKey) { + rangeModifier(new _src.CellCoords(instance.countRows() - 1, priv.selRange.from.col)); + } else { + rangeModifier(new _src.CellCoords(priv.selRange.from.row, instance.countCols() - 1)); + } + event.preventDefault(); // don't scroll the window + (0, _event.stopPropagation)(event); + break; - /** - * Recalculate all rows height (overwrite cache values). - */ + case _unicode.KEY_CODES.PAGE_UP: + selection.setSelectedHeaders(false, false, false); + selection.transformStart(-instance.countVisibleRows(), 0); + event.preventDefault(); // don't page up the window + (0, _event.stopPropagation)(event); + break; - }, { - key: 'recalculateAllRowsHeight', - value: function recalculateAllRowsHeight() { - if ((0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) { - this.clearCache(); - this.calculateAllRowsHeight(); - } + case _unicode.KEY_CODES.PAGE_DOWN: + selection.setSelectedHeaders(false, false, false); + selection.transformStart(instance.countVisibleRows(), 0); + event.preventDefault(); // don't page down the window + (0, _event.stopPropagation)(event); + break; + default: + break; } + } - /** - * Get value which tells how much rows will be calculated synchronously. Rest rows will be calculated asynchronously. - * - * @returns {Number} - */ + function init() { + instance.addHook('afterDocumentKeyDown', onKeyDown); - }, { - key: 'getSyncCalculationLimit', - value: function getSyncCalculationLimit() { - /* eslint-disable no-bitwise */ - var limit = AutoRowSize.SYNC_CALCULATION_LIMIT; - var rowsLimit = this.hot.countRows() - 1; + eventManager.addEventListener(document.documentElement, 'keydown', function (event) { + if (!destroyed) { + instance.runHooks('afterDocumentKeyDown', event); + } + }); - if ((0, _object.isObject)(this.hot.getSettings().autoRowSize)) { - limit = this.hot.getSettings().autoRowSize.syncLimit; + function onDblClick(event, coords, elem) { + // may be TD or TH + if (elem.nodeName == 'TD') { + _this.openEditor(); - if ((0, _string.isPercentValue)(limit)) { - limit = (0, _number.valueAccordingPercent)(rowsLimit, limit); - } else { - // Force to Number - limit >>= 0; + if (activeEditor) { + activeEditor.enableFullEditMode(); } } - - return Math.min(limit, rowsLimit); } + instance.view.wt.update('onCellDblClick', onDblClick); - /** - * Get the calculated row height. - * - * @param {Number} row Visual row index. - * @param {Number} [defaultHeight] Default row height. It will be pick up if no calculated height found. - * @returns {Number} - */ - - }, { - key: 'getRowHeight', - value: function getRowHeight(row) { - var defaultHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0; + instance.addHook('afterDestroy', function () { + destroyed = true; + }); + } - var height = defaultHeight; + /** + * Destroy current editor, if exists. + * + * @function destroyEditor + * @memberof! Handsontable.EditorManager# + * @param {Boolean} revertOriginal + */ + this.destroyEditor = function (revertOriginal) { + this.closeEditor(revertOriginal); + }; - if (this.heights[row] !== void 0 && this.heights[row] > (defaultHeight || 0)) { - height = this.heights[row]; - } + /** + * Get active editor. + * + * @function getActiveEditor + * @memberof! Handsontable.EditorManager# + * @returns {*} + */ + this.getActiveEditor = function () { + return activeEditor; + }; - return height; - } + /** + * Prepare text input to be displayed at given grid cell. + * + * @function prepareEditor + * @memberof! Handsontable.EditorManager# + */ + this.prepareEditor = function () { + var row, col, prop, td, originalValue, cellProperties, editorClass; - /** - * Get the calculated column header height. - * - * @returns {Number|undefined} - */ + if (activeEditor && activeEditor.isWaiting()) { + this.closeEditor(false, false, function (dataSaved) { + if (dataSaved) { + _this.prepareEditor(); + } + }); - }, { - key: 'getColumnHeaderHeight', - value: function getColumnHeaderHeight() { - return this.heights[-1]; + return; } + row = priv.selRange.highlight.row; + col = priv.selRange.highlight.col; + prop = instance.colToProp(col); + td = instance.getCell(row, col); - /** - * Get the first visible row. - * - * @returns {Number} Returns row index or -1 if table is not rendered. - */ - - }, { - key: 'getFirstVisibleRow', - value: function getFirstVisibleRow() { - var wot = this.hot.view.wt; - - if (wot.wtViewport.rowsVisibleCalculator) { - return wot.wtTable.getFirstVisibleRow(); - } - if (wot.wtViewport.rowsRenderCalculator) { - return wot.wtTable.getFirstRenderedRow(); - } + originalValue = instance.getSourceDataAtCell(instance.runHooks('modifyRow', row), col); + cellProperties = instance.getCellMeta(row, col); + editorClass = instance.getCellEditor(cellProperties); - return -1; + if (editorClass) { + activeEditor = (0, _editors.getEditorInstance)(editorClass, instance); + activeEditor.prepare(row, col, prop, td, originalValue, cellProperties); + } else { + activeEditor = void 0; } + }; - /** - * Get the last visible row. - * - * @returns {Number} Returns row index or -1 if table is not rendered. - */ + /** + * Check is editor is opened/showed. + * + * @function isEditorOpened + * @memberof! Handsontable.EditorManager# + * @returns {Boolean} + */ + this.isEditorOpened = function () { + return activeEditor && activeEditor.isOpened(); + }; - }, { - key: 'getLastVisibleRow', - value: function getLastVisibleRow() { - var wot = this.hot.view.wt; + /** + * Open editor with initial value. + * + * @function openEditor + * @memberof! Handsontable.EditorManager# + * @param {String} initialValue + * @param {DOMEvent} event + */ + this.openEditor = function (initialValue, event) { + if (activeEditor && !activeEditor.cellProperties.readOnly) { + activeEditor.beginEditing(initialValue, event); + } else if (activeEditor && activeEditor.cellProperties.readOnly) { - if (wot.wtViewport.rowsVisibleCalculator) { - return wot.wtTable.getLastVisibleRow(); - } - if (wot.wtViewport.rowsRenderCalculator) { - return wot.wtTable.getLastRenderedRow(); + // move the selection after opening the editor with ENTER key + if (event && event.keyCode === _unicode.KEY_CODES.ENTER) { + moveSelectionAfterEnter(); } + } + }; - return -1; + /** + * Close editor, finish editing cell. + * + * @function closeEditor + * @memberof! Handsontable.EditorManager# + * @param {Boolean} restoreOriginalValue + * @param {Boolean} [ctrlDown] + * @param {Function} [callback] + */ + this.closeEditor = function (restoreOriginalValue, ctrlDown, callback) { + if (activeEditor) { + activeEditor.finishEditing(restoreOriginalValue, ctrlDown, callback); + } else if (callback) { + callback(false); } + }; + + /** + * Close editor and save changes. + * + * @function closeEditorAndSaveChanges + * @memberof! Handsontable.EditorManager# + * @param {Boolean} ctrlDown + */ + this.closeEditorAndSaveChanges = function (ctrlDown) { + return this.closeEditor(false, ctrlDown); + }; - /** - * Clear cached heights. - */ + /** + * Close editor and restore original value. + * + * @function closeEditorAndRestoreOriginalValue + * @memberof! Handsontable.EditorManager# + * @param {Boolean} ctrlDown + */ + this.closeEditorAndRestoreOriginalValue = function (ctrlDown) { + return this.closeEditor(true, ctrlDown); + }; - }, { - key: 'clearCache', - value: function clearCache() { - this.heights.length = 0; - this.heights[-1] = void 0; - } + init(); +} - /** - * Clear cache by range. - * - * @param {Object|Number} range Row range object. - */ +exports.default = EditorManager; - }, { - key: 'clearCacheByRange', - value: function clearCacheByRange(range) { - var _this5 = this; +/***/ }), +/* 244 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof range === 'number') { - range = { from: range, to: range }; - } - (0, _number.rangeEach)(Math.min(range.from, range.to), Math.max(range.from, range.to), function (row) { - _this5.heights[row] = void 0; - }); - } +"use strict"; - /** - * @returns {Boolean} - */ - }, { - key: 'isNeedRecalculate', - value: function isNeedRecalculate() { - return !!(0, _array.arrayFilter)(this.heights, function (item) { - return item === void 0; - }).length; - } +exports.__esModule = true; - /** - * On before render listener. - * - * @private - */ +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - }, { - key: 'onBeforeRender', - value: function onBeforeRender() { - var force = this.hot.renderCall; - this.calculateRowsHeight({ from: this.getFirstVisibleRow(), to: this.getLastVisibleRow() }, void 0, force); +var _element = __webpack_require__(0); - var fixedRowsBottom = this.hot.getSettings().fixedRowsBottom; +var _browser = __webpack_require__(26); - // Calculate rows height synchronously for bottom overlay - if (fixedRowsBottom) { - var totalRows = this.hot.countRows() - 1; - this.calculateRowsHeight({ from: totalRows - fixedRowsBottom, to: totalRows }); - } +var _eventManager = __webpack_require__(4); - if (this.isNeedRecalculate() && !this.inProgress) { - this.calculateAllRowsHeight(); - } - } +var _eventManager2 = _interopRequireDefault(_eventManager); - /** - * On before row move listener. - * - * @private - * @param {Number} from Row index where was grabbed. - * @param {Number} to Destination row index. - */ +var _event = __webpack_require__(8); - }, { - key: 'onBeforeRowMove', - value: function onBeforeRowMove(from, to) { - this.clearCacheByRange({ from: from, to: to }); - this.calculateAllRowsHeight(); - } +var _src = __webpack_require__(12); - /** - * On before row resize listener. - * - * @private - * @param {Number} row - * @param {Number} size - * @param {Boolean} isDblClick - * @returns {Number} - */ +var _src2 = _interopRequireDefault(_src); - }, { - key: 'onBeforeRowResize', - value: function onBeforeRowResize(row, size, isDblClick) { - if (isDblClick) { - this.calculateRowsHeight(row, void 0, true); - size = this.getRowHeight(row); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return size; - } +/** + * Handsontable TableView constructor + * @param {Object} instance + */ +function TableView(instance) { + var _this = this; - /** - * On after load data listener. - * - * @private - */ + var that = this; - }, { - key: 'onAfterLoadData', - value: function onAfterLoadData() { - var _this6 = this; + this.eventManager = new _eventManager2.default(instance); + this.instance = instance; + this.settings = instance.getSettings(); + this.selectionMouseDown = false; - if (this.hot.view) { - this.recalculateAllRowsHeight(); - } else { - // first load - initialization - setTimeout(function () { - if (_this6.hot) { - _this6.recalculateAllRowsHeight(); - } - }, 0); - } - } + var originalStyle = instance.rootElement.getAttribute('style'); - /** - * On before change listener. - * - * @private - * @param {Array} changes - */ + if (originalStyle) { + instance.rootElement.setAttribute('data-originalstyle', originalStyle); // needed to retrieve original style in jsFiddle link generator in HT examples. may be removed in future versions + } - }, { - key: 'onBeforeChange', - value: function onBeforeChange(changes) { - var range = null; + (0, _element.addClass)(instance.rootElement, 'handsontable'); - if (changes.length === 1) { - range = changes[0][0]; - } else if (changes.length > 1) { - range = { - from: changes[0][0], - to: changes[changes.length - 1][0] - }; - } - if (range !== null) { - this.clearCacheByRange(range); - } - } + var table = document.createElement('TABLE'); + (0, _element.addClass)(table, 'htCore'); - /** - * Destroy plugin instance. - */ + if (instance.getSettings().tableClassName) { + (0, _element.addClass)(table, instance.getSettings().tableClassName); + } + this.THEAD = document.createElement('THEAD'); + table.appendChild(this.THEAD); + this.TBODY = document.createElement('TBODY'); + table.appendChild(this.TBODY); - }, { - key: 'destroy', - value: function destroy() { - this.ghostTable.clean(); - _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'destroy', this).call(this); - } - }]); + instance.table = table; - return AutoRowSize; -}(_base2.default); + instance.container.insertBefore(table, instance.container.firstChild); -(0, _plugins.registerPlugin)('autoRowSize', AutoRowSize); + this.eventManager.addEventListener(instance.rootElement, 'mousedown', function (event) { + this.selectionMouseDown = true; -exports.default = AutoRowSize; + if (!that.isTextSelectionAllowed(event.target)) { + clearTextSelection(); + event.preventDefault(); + window.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe. + } + }); + this.eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) { + this.selectionMouseDown = false; + }); + this.eventManager.addEventListener(instance.rootElement, 'mousemove', function (event) { + if (this.selectionMouseDown && !that.isTextSelectionAllowed(event.target)) { + clearTextSelection(); + event.preventDefault(); + } + }); -/***/ }), -/* 214 */ -/***/ (function(module, exports, __webpack_require__) { + this.eventManager.addEventListener(document.documentElement, 'keyup', function (event) { + if (instance.selection.isInProgress() && !event.shiftKey) { + instance.selection.finish(); + } + }); -"use strict"; + var isMouseDown; + this.isMouseDown = function () { + return isMouseDown; + }; + this.eventManager.addEventListener(document.documentElement, 'mouseup', function (event) { + if (instance.selection.isInProgress() && event.which === 1) { + // is left mouse button + instance.selection.finish(); + } -exports.__esModule = true; + isMouseDown = false; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + if ((0, _element.isOutsideInput)(document.activeElement) || !instance.selection.isSelected()) { + instance.unlisten(); + } + }); -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + this.eventManager.addEventListener(document.documentElement, 'mousedown', function (event) { + var originalTarget = event.target; + var next = event.target; + var eventX = event.x || event.clientX; + var eventY = event.y || event.clientY; -var _base = __webpack_require__(12); + if (isMouseDown || !instance.rootElement) { + return; // it must have been started in a cell + } -var _base2 = _interopRequireDefault(_base); + // immediate click on "holder" means click on the right side of vertical scrollbar + if (next === instance.view.wt.wtTable.holder) { + var scrollbarWidth = (0, _element.getScrollbarWidth)(); -var _pluginHooks = __webpack_require__(8); + if (document.elementFromPoint(eventX + scrollbarWidth, eventY) !== instance.view.wt.wtTable.holder || document.elementFromPoint(eventX, eventY + scrollbarWidth) !== instance.view.wt.wtTable.holder) { + return; + } + } else { + while (next !== document.documentElement) { + if (next === null) { + if (event.isTargetWebComponent) { + break; + } + // click on something that was a row but now is detached (possibly because your click triggered a rerender) + return; + } + if (next === instance.rootElement) { + // click inside container + return; + } + next = next.parentNode; + } + } -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + // function did not return until here, we have an outside click! -var _element = __webpack_require__(0); + var outsideClickDeselects = typeof that.settings.outsideClickDeselects === 'function' ? that.settings.outsideClickDeselects(originalTarget) : that.settings.outsideClickDeselects; -var _eventManager = __webpack_require__(4); + if (outsideClickDeselects) { + instance.deselectCell(); + } else { + instance.destroyEditor(); + } + }); -var _eventManager2 = _interopRequireDefault(_eventManager); + this.eventManager.addEventListener(table, 'selectstart', function (event) { + if (that.settings.fragmentSelection || (0, _element.isInput)(event.target)) { + return; + } + // https://github.com/handsontable/handsontable/issues/160 + // Prevent text from being selected when performing drag down. + event.preventDefault(); + }); -var _plugins = __webpack_require__(5); + var clearTextSelection = function clearTextSelection() { + // http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript + if (window.getSelection) { + if (window.getSelection().empty) { + // Chrome + window.getSelection().empty(); + } else if (window.getSelection().removeAllRanges) { + // Firefox + window.getSelection().removeAllRanges(); + } + } else if (document.selection) { + // IE? + document.selection.empty(); + } + }; -var _src = __webpack_require__(11); + var selections = [new _src.Selection({ + className: 'current', + border: { + width: 2, + color: '#5292F7', + // style: 'solid', // not used + cornerVisible: function cornerVisible() { + return that.settings.fillHandle && !that.isCellEdited() && !instance.selection.isMultiple(); + }, + multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() { + return !that.isCellEdited() && !instance.selection.isMultiple(); + } + } + }), new _src.Selection({ + className: 'area', + border: { + width: 1, + color: '#89AFF9', + // style: 'solid', // not used + cornerVisible: function cornerVisible() { + return that.settings.fillHandle && !that.isCellEdited() && instance.selection.isMultiple(); + }, + multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() { + return !that.isCellEdited() && instance.selection.isMultiple(); + } + } + }), new _src.Selection({ + className: 'highlight', + highlightHeaderClassName: that.settings.currentHeaderClassName, + highlightRowClassName: that.settings.currentRowClassName, + highlightColumnClassName: that.settings.currentColClassName + }), new _src.Selection({ + className: 'fill', + border: { + width: 1, + color: 'red' + // style: 'solid' // not used + } + })]; + selections.current = selections[0]; + selections.area = selections[1]; + selections.highlight = selections[2]; + selections.fill = selections[3]; -var _utils = __webpack_require__(215); + var walkontableConfig = { + debug: function debug() { + return that.settings.debug; + }, + externalRowCalculator: this.instance.getPlugin('autoRowSize') && this.instance.getPlugin('autoRowSize').isEnabled(), + table: table, + preventOverflow: function preventOverflow() { + return _this.settings.preventOverflow; + }, + stretchH: function stretchH() { + return that.settings.stretchH; + }, + data: instance.getDataAtCell, + totalRows: function totalRows() { + return instance.countRows(); + }, + totalColumns: function totalColumns() { + return instance.countCols(); + }, + fixedColumnsLeft: function fixedColumnsLeft() { + return that.settings.fixedColumnsLeft; + }, + fixedRowsTop: function fixedRowsTop() { + return that.settings.fixedRowsTop; + }, + fixedRowsBottom: function fixedRowsBottom() { + return that.settings.fixedRowsBottom; + }, + minSpareRows: function minSpareRows() { + return that.settings.minSpareRows; + }, + renderAllRows: that.settings.renderAllRows, + rowHeaders: function rowHeaders() { + var headerRenderers = []; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (instance.hasRowHeaders()) { + headerRenderers.push(function (row, TH) { + that.appendRowHeader(row, TH); + }); + } + instance.runHooks('afterGetRowHeaderRenderers', headerRenderers); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + return headerRenderers; + }, + columnHeaders: function columnHeaders() { + var headerRenderers = []; -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + if (instance.hasColHeaders()) { + headerRenderers.push(function (column, TH) { + that.appendColHeader(column, TH); + }); + } + instance.runHooks('afterGetColumnHeaderRenderers', headerRenderers); -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + return headerRenderers; + }, + columnWidth: instance.getColWidth, + rowHeight: instance.getRowHeight, + cellRenderer: function cellRenderer(row, col, TD) { + var cellProperties = that.instance.getCellMeta(row, col); + var prop = that.instance.colToProp(col); + var value = that.instance.getDataAtRowProp(row, prop); -_pluginHooks2.default.getSingleton().register('modifyAutofillRange'); -_pluginHooks2.default.getSingleton().register('beforeAutofill'); + if (that.instance.hasHook('beforeValueRender')) { + value = that.instance.runHooks('beforeValueRender', value); + } -var INSERT_ROW_ALTER_ACTION_NAME = 'insert_row'; -var INTERVAL_FOR_ADDING_ROW = 200; + that.instance.runHooks('beforeRenderer', TD, row, col, prop, value, cellProperties); + that.instance.getCellRenderer(cellProperties)(that.instance, TD, row, col, prop, value, cellProperties); + that.instance.runHooks('afterRenderer', TD, row, col, prop, value, cellProperties); + }, + selections: selections, + hideBorderOnMouseDownOver: function hideBorderOnMouseDownOver() { + return that.settings.fragmentSelection; + }, + onCellMouseDown: function onCellMouseDown(event, coords, TD, wt) { + var blockCalculations = { + row: false, + column: false, + cells: false + }; -/** - * This plugin provides "drag-down" and "copy-down" functionalities, both operated - * using the small square in the right bottom of the cell selection. - * - * "Drag-down" expands the value of the selected cells to the neighbouring - * cells when you drag the small square in the corner. - * - * "Copy-down" copies the value of the selection to all empty cells - * below when you double click the small square. - * - * @class Autofill - * @plugin Autofill - */ + instance.listen(); -var Autofill = function (_BasePlugin) { - _inherits(Autofill, _BasePlugin); + that.activeWt = wt; + isMouseDown = true; - function Autofill(hotInstance) { - _classCallCheck(this, Autofill); + instance.runHooks('beforeOnCellMouseDown', event, coords, TD, blockCalculations); - /** - * Event manager - * - * @type {EventManager} - */ - var _this = _possibleConstructorReturn(this, (Autofill.__proto__ || Object.getPrototypeOf(Autofill)).call(this, hotInstance)); + if ((0, _event.isImmediatePropagationStopped)(event)) { + return; + } - _this.eventManager = new _eventManager2.default(_this); - /** - * Specifies if adding new row started. - * - * @type {Boolean} - */ - _this.addingStarted = false; - /** - * Specifies if there was mouse down on the cell corner. - * - * @type {Boolean} - */ - _this.mouseDownOnCellCorner = false; - /** - * Specifies if mouse was dragged outside Handsontable. - * - * @type {Boolean} - */ - _this.mouseDragOutside = false; - /** - * Specifies how many cell levels were dragged using the handle. - * - * @type {Boolean} - */ - _this.handleDraggedCells = 0; - /** - * Specifies allowed directions of drag. - * - * @type {Array} - */ - _this.directions = []; - /** - * Specifies if can insert new rows if needed. - * - * @type {Boolean} - */ - _this.autoInsertRow = false; - return _this; - } + var actualSelection = instance.getSelectedRange(); + var selection = instance.selection; + var selectedHeader = selection.selectedHeader; - /** - * Check if the plugin is enabled in the Handsontable settings. - * - * @returns {Boolean} - */ + if (event.shiftKey && actualSelection) { + if (coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) { + selection.setSelectedHeaders(false, false); + selection.setRangeEnd(coords); + } else if ((selectedHeader.cols || selectedHeader.rows) && coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) { + selection.setSelectedHeaders(false, false); + selection.setRangeEnd(new _src.CellCoords(coords.row, coords.col)); + } else if (selectedHeader.cols && coords.row < 0 && !blockCalculations.column) { + selection.setRangeEnd(new _src.CellCoords(actualSelection.to.row, coords.col)); + } else if (selectedHeader.rows && coords.col < 0 && !blockCalculations.row) { + selection.setRangeEnd(new _src.CellCoords(coords.row, actualSelection.to.col)); + } else if ((!selectedHeader.cols && !selectedHeader.rows && coords.col < 0 || selectedHeader.cols && coords.col < 0) && !blockCalculations.row) { + selection.setSelectedHeaders(true, false); + selection.setRangeStartOnly(new _src.CellCoords(actualSelection.from.row, 0)); + selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1)); + } else if ((!selectedHeader.cols && !selectedHeader.rows && coords.row < 0 || selectedHeader.rows && coords.row < 0) && !blockCalculations.column) { + selection.setSelectedHeaders(false, true); + selection.setRangeStartOnly(new _src.CellCoords(0, actualSelection.from.col)); + selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col)); + } + } else { + var doNewSelection = true; + if (actualSelection) { + var from = actualSelection.from, + to = actualSelection.to; - _createClass(Autofill, [{ - key: 'isEnabled', - value: function isEnabled() { - return this.hot.getSettings().fillHandle; - } + var coordsNotInSelection = !selection.inInSelection(coords); - /** - * Enable plugin for this Handsontable instance. - */ + if (coords.row < 0 && selectedHeader.cols) { + var start = Math.min(from.col, to.col); + var end = Math.max(from.col, to.col); - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + doNewSelection = coords.col < start || coords.col > end; + } else if (coords.col < 0 && selectedHeader.rows) { + var _start = Math.min(from.row, to.row); + var _end = Math.max(from.row, to.row); - if (this.enabled) { - return; - } + doNewSelection = coords.row < _start || coords.row > _end; + } else { + doNewSelection = coordsNotInSelection; + } + } - this.mapSettings(); - this.registerEvents(); + var rightClick = (0, _event.isRightClick)(event); + var leftClick = (0, _event.isLeftClick)(event) || event.type === 'touchstart'; - this.addHook('afterOnCellCornerMouseDown', function (event) { - return _this2.onAfterCellCornerMouseDown(event); - }); - this.addHook('afterOnCellCornerDblClick', function (event) { - return _this2.onCellCornerDblClick(event); - }); - this.addHook('beforeOnCellMouseOver', function (event, coords, TD) { - return _this2.onBeforeCellMouseOver(coords); - }); + // clicked row header and when some column was selected + if (coords.row < 0 && coords.col >= 0 && !blockCalculations.column) { + selection.setSelectedHeaders(false, true); - _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'enablePlugin', this).call(this); - } + if (leftClick || rightClick && doNewSelection) { + selection.setRangeStartOnly(new _src.CellCoords(0, coords.col)); + selection.setRangeEnd(new _src.CellCoords(Math.max(instance.countRows() - 1, 0), coords.col), false); + } - /** - * Update plugin for this Handsontable instance. - */ + // clicked column header and when some row was selected + } else if (coords.col < 0 && coords.row >= 0 && !blockCalculations.row) { + selection.setSelectedHeaders(true, false); - }, { - key: 'updatePlugin', - value: function updatePlugin() { - this.disablePlugin(); - this.enablePlugin(); - _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'updatePlugin', this).call(this); - } + if (leftClick || rightClick && doNewSelection) { + selection.setRangeStartOnly(new _src.CellCoords(coords.row, 0)); + selection.setRangeEnd(new _src.CellCoords(coords.row, Math.max(instance.countCols() - 1, 0)), false); + } + } else if (coords.col >= 0 && coords.row >= 0 && !blockCalculations.cells) { + if (leftClick || rightClick && doNewSelection) { + selection.setSelectedHeaders(false, false); + selection.setRangeStart(coords); + } + } else if (coords.col < 0 && coords.row < 0) { + coords.row = 0; + coords.col = 0; - /** - * Disable plugin for this Handsontable instance. - */ + selection.setSelectedHeaders(false, false, true); + selection.setRangeStart(coords); + } + } - }, { - key: 'disablePlugin', - value: function disablePlugin() { - this.clearMappedSettings(); - _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'disablePlugin', this).call(this); - } + instance.runHooks('afterOnCellMouseDown', event, coords, TD); + that.activeWt = that.wt; + }, + onCellMouseOut: function onCellMouseOut(event, coords, TD, wt) { + that.activeWt = wt; + instance.runHooks('beforeOnCellMouseOut', event, coords, TD); - /** - * Get selection data - * - * @private - * @returns {Array} Array with the data. - */ + if ((0, _event.isImmediatePropagationStopped)(event)) { + return; + } - }, { - key: 'getSelectionData', - value: function getSelectionData() { - var selRange = { - from: this.hot.getSelectedRange().from, - to: this.hot.getSelectedRange().to + instance.runHooks('afterOnCellMouseOut', event, coords, TD); + that.activeWt = that.wt; + }, + onCellMouseOver: function onCellMouseOver(event, coords, TD, wt) { + var blockCalculations = { + row: false, + column: false, + cell: false }; - return this.hot.getData(selRange.from.row, selRange.from.col, selRange.to.row, selRange.to.col); - } + that.activeWt = wt; + instance.runHooks('beforeOnCellMouseOver', event, coords, TD, blockCalculations); - /** - * Try to apply fill values to the area in fill border, omitting the selection border. - * - * @private - * @returns {Boolean} reports if fill was applied. - */ + if ((0, _event.isImmediatePropagationStopped)(event)) { + return; + } - }, { - key: 'fillIn', - value: function fillIn() { - if (this.hot.view.wt.selections.fill.isEmpty()) { - return false; + if (event.button === 0 && isMouseDown) { + if (coords.row >= 0 && coords.col >= 0) { + // is not a header + if (instance.selection.selectedHeader.cols && !blockCalculations.column) { + instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false); + } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) { + instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false); + } else if (!blockCalculations.cell) { + instance.selection.setRangeEnd(coords); + } + } else { + /* eslint-disable no-lonely-if */ + if (instance.selection.selectedHeader.cols && !blockCalculations.column) { + instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false); + } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) { + instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false); + } else if (!blockCalculations.cell) { + instance.selection.setRangeEnd(coords); + } + } } - var cornersOfSelectionAndDragAreas = this.hot.view.wt.selections.fill.getCorners(); + instance.runHooks('afterOnCellMouseOver', event, coords, TD); + that.activeWt = that.wt; + }, + onCellMouseUp: function onCellMouseUp(event, coords, TD, wt) { + that.activeWt = wt; + instance.runHooks('beforeOnCellMouseUp', event, coords, TD); - this.resetSelectionOfDraggedArea(); + instance.runHooks('afterOnCellMouseUp', event, coords, TD); + that.activeWt = that.wt; + }, + onCellCornerMouseDown: function onCellCornerMouseDown(event) { + event.preventDefault(); + instance.runHooks('afterOnCellCornerMouseDown', event); + }, + onCellCornerDblClick: function onCellCornerDblClick(event) { + event.preventDefault(); + instance.runHooks('afterOnCellCornerDblClick', event); + }, + beforeDraw: function beforeDraw(force, skipRender) { + that.beforeRender(force, skipRender); + }, + onDraw: function onDraw(force) { + that.onDraw(force); + }, + onScrollVertically: function onScrollVertically() { + instance.runHooks('afterScrollVertically'); + }, + onScrollHorizontally: function onScrollHorizontally() { + instance.runHooks('afterScrollHorizontally'); + }, + onBeforeDrawBorders: function onBeforeDrawBorders(corners, borderClassName) { + instance.runHooks('beforeDrawBorders', corners, borderClassName); + }, + onBeforeTouchScroll: function onBeforeTouchScroll() { + instance.runHooks('beforeTouchScroll'); + }, + onAfterMomentumScroll: function onAfterMomentumScroll() { + instance.runHooks('afterMomentumScroll'); + }, + onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(stretchedWidth, column) { + return instance.runHooks('beforeStretchingColumnWidth', stretchedWidth, column); + }, + onModifyRowHeaderWidth: function onModifyRowHeaderWidth(rowHeaderWidth) { + return instance.runHooks('modifyRowHeaderWidth', rowHeaderWidth); + }, + viewportRowCalculatorOverride: function viewportRowCalculatorOverride(calc) { + var rows = instance.countRows(); + var viewportOffset = that.settings.viewportRowRenderingOffset; - var cornersOfSelectedCells = this.getCornersOfSelectedCells(); + if (viewportOffset === 'auto' && that.settings.fixedRowsTop) { + viewportOffset = 10; + } + if (typeof viewportOffset === 'number') { + calc.startRow = Math.max(calc.startRow - viewportOffset, 0); + calc.endRow = Math.min(calc.endRow + viewportOffset, rows - 1); + } + if (viewportOffset === 'auto') { + var center = calc.startRow + calc.endRow - calc.startRow; + var offset = Math.ceil(center / rows * 12); - var _getDragDirectionAndR = (0, _utils.getDragDirectionAndRange)(cornersOfSelectedCells, cornersOfSelectionAndDragAreas), - directionOfDrag = _getDragDirectionAndR.directionOfDrag, - startOfDragCoords = _getDragDirectionAndR.startOfDragCoords, - endOfDragCoords = _getDragDirectionAndR.endOfDragCoords; + calc.startRow = Math.max(calc.startRow - offset, 0); + calc.endRow = Math.min(calc.endRow + offset, rows - 1); + } + instance.runHooks('afterViewportRowCalculatorOverride', calc); + }, + viewportColumnCalculatorOverride: function viewportColumnCalculatorOverride(calc) { + var cols = instance.countCols(); + var viewportOffset = that.settings.viewportColumnRenderingOffset; - this.hot.runHooks('modifyAutofillRange', cornersOfSelectedCells, cornersOfSelectionAndDragAreas); + if (viewportOffset === 'auto' && that.settings.fixedColumnsLeft) { + viewportOffset = 10; + } + if (typeof viewportOffset === 'number') { + calc.startColumn = Math.max(calc.startColumn - viewportOffset, 0); + calc.endColumn = Math.min(calc.endColumn + viewportOffset, cols - 1); + } + if (viewportOffset === 'auto') { + var center = calc.startColumn + calc.endColumn - calc.startColumn; + var offset = Math.ceil(center / cols * 12); - if (startOfDragCoords && startOfDragCoords.row > -1 && startOfDragCoords.col > -1) { - var selectionData = this.getSelectionData(); - var deltas = (0, _utils.getDeltas)(startOfDragCoords, endOfDragCoords, selectionData, directionOfDrag); - var fillData = selectionData; + calc.startRow = Math.max(calc.startColumn - offset, 0); + calc.endColumn = Math.min(calc.endColumn + offset, cols - 1); + } + instance.runHooks('afterViewportColumnCalculatorOverride', calc); + }, + rowHeaderWidth: function rowHeaderWidth() { + return that.settings.rowHeaderWidth; + }, + columnHeaderHeight: function columnHeaderHeight() { + var columnHeaderHeight = instance.runHooks('modifyColumnHeaderHeight'); + return that.settings.columnHeaderHeight || columnHeaderHeight; + } + }; - this.hot.runHooks('beforeAutofill', startOfDragCoords, endOfDragCoords, selectionData); + instance.runHooks('beforeInitWalkontable', walkontableConfig); - if (['up', 'left'].indexOf(directionOfDrag) > -1) { - fillData = []; + this.wt = new _src2.default(walkontableConfig); + this.activeWt = this.wt; - var dragLength = null; - var fillOffset = null; + if (!(0, _browser.isChrome)() && !(0, _browser.isSafari)()) { + this.eventManager.addEventListener(instance.rootElement, 'wheel', function (event) { + event.preventDefault(); - if (directionOfDrag === 'up') { - dragLength = endOfDragCoords.row - startOfDragCoords.row + 1; - fillOffset = dragLength % selectionData.length; + var lineHeight = parseInt((0, _element.getComputedStyle)(document.body)['font-size'], 10); + var holder = that.wt.wtOverlays.scrollableElement; - for (var i = 0; i < dragLength; i++) { - fillData.push(selectionData[(i + (selectionData.length - fillOffset)) % selectionData.length]); - } - } else { - dragLength = endOfDragCoords.col - startOfDragCoords.col + 1; - fillOffset = dragLength % selectionData[0].length; + var deltaY = event.wheelDeltaY || event.deltaY; + var deltaX = event.wheelDeltaX || event.deltaX; - for (var _i = 0; _i < selectionData.length; _i++) { - fillData.push([]); - for (var j = 0; j < dragLength; j++) { - fillData[_i].push(selectionData[_i][(j + (selectionData[_i].length - fillOffset)) % selectionData[_i].length]); - } - } - } - } + switch (event.deltaMode) { + case 0: + holder.scrollLeft += deltaX; + holder.scrollTop += deltaY; + break; - this.hot.populateFromArray(startOfDragCoords.row, startOfDragCoords.col, fillData, endOfDragCoords.row, endOfDragCoords.col, this.pluginName + '.fill', null, directionOfDrag, deltas); + case 1: + holder.scrollLeft += deltaX * lineHeight; + holder.scrollTop += deltaY * lineHeight; + break; - this.setSelection(cornersOfSelectionAndDragAreas); - } else { - // reset to avoid some range bug - this.hot.selection.refreshBorders(); + default: + break; } + }); + } - return true; + this.eventManager.addEventListener(that.wt.wtTable.spreader, 'mousedown', function (event) { + // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar + if (event.target === that.wt.wtTable.spreader && event.which === 3) { + (0, _event.stopPropagation)(event); } + }); - /** - * Reduce the selection area if the handle was dragged outside of the table or on headers. - * - * @private - * @param {CellCoords} coords indexes of selection corners. - * @returns {CellCoords} - */ - - }, { - key: 'reduceSelectionAreaIfNeeded', - value: function reduceSelectionAreaIfNeeded(coords) { - if (coords.row < 0) { - coords.row = 0; - } + this.eventManager.addEventListener(that.wt.wtTable.spreader, 'contextmenu', function (event) { + // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar + if (event.target === that.wt.wtTable.spreader && event.which === 3) { + (0, _event.stopPropagation)(event); + } + }); - if (coords.col < 0) { - coords.col = 0; + this.eventManager.addEventListener(document.documentElement, 'click', function () { + if (that.settings.observeDOMVisibility) { + if (that.wt.drawInterrupted) { + that.instance.forceFullRender = true; + that.render(); } - return coords; } + }); +} - /** - * Get the coordinates of the drag & drop borders. - * - * @private - * @param {CellCoords} coordsOfSelection `CellCoords` coord object. - * @returns {Array} - */ +TableView.prototype.isTextSelectionAllowed = function (el) { + if ((0, _element.isInput)(el)) { + return true; + } + var isChildOfTableBody = (0, _element.isChildOf)(el, this.instance.view.wt.wtTable.spreader); - }, { - key: 'getCoordsOfDragAndDropBorders', - value: function getCoordsOfDragAndDropBorders(coordsOfSelection) { - var topLeftCorner = this.hot.getSelectedRange().getTopLeftCorner(); - var bottomRightCorner = this.hot.getSelectedRange().getBottomRightCorner(); - var coords = void 0; + if (this.settings.fragmentSelection === true && isChildOfTableBody) { + return true; + } + if (this.settings.fragmentSelection === 'cell' && this.isSelectedOnlyCell() && isChildOfTableBody) { + return true; + } + if (!this.settings.fragmentSelection && this.isCellEdited() && this.isSelectedOnlyCell()) { + return true; + } - if (this.directions.includes(_utils.DIRECTIONS.vertical) && (bottomRightCorner.row < coordsOfSelection.row || topLeftCorner.row > coordsOfSelection.row)) { - coords = new _src.CellCoords(coordsOfSelection.row, bottomRightCorner.col); - } else if (this.directions.includes(_utils.DIRECTIONS.horizontal)) { - coords = new _src.CellCoords(bottomRightCorner.row, coordsOfSelection.col); - } else { - // wrong direction - return; - } + return false; +}; - return this.reduceSelectionAreaIfNeeded(coords); - } +/** + * Check if selected only one cell. + * + * @returns {Boolean} + */ +TableView.prototype.isSelectedOnlyCell = function () { + var _ref = this.instance.getSelected() || [], + _ref2 = _slicedToArray(_ref, 4), + row = _ref2[0], + col = _ref2[1], + rowEnd = _ref2[2], + colEnd = _ref2[3]; - /** - * Show the fill border. - * - * @private - * @param {CellCoords} coordsOfSelection `CellCoords` coord object. - */ + return row !== void 0 && row === rowEnd && col === colEnd; +}; - }, { - key: 'showBorder', - value: function showBorder(coordsOfSelection) { - var coordsOfDragAndDropBorders = this.getCoordsOfDragAndDropBorders(coordsOfSelection); +TableView.prototype.isCellEdited = function () { + var activeEditor = this.instance.getActiveEditor(); - if (coordsOfDragAndDropBorders) { - this.redrawBorders(coordsOfDragAndDropBorders); - } - } + return activeEditor && activeEditor.isOpened(); +}; - /** - * Add new row - * - * @private - */ +TableView.prototype.beforeRender = function (force, skipRender) { + if (force) { + // this.instance.forceFullRender = did Handsontable request full render? + this.instance.runHooks('beforeRender', this.instance.forceFullRender, skipRender); + } +}; - }, { - key: 'addRow', - value: function addRow() { - var _this3 = this; +TableView.prototype.onDraw = function (force) { + if (force) { + // this.instance.forceFullRender = did Handsontable request full render? + this.instance.runHooks('afterRender', this.instance.forceFullRender); + } +}; - this.hot._registerTimeout(setTimeout(function () { - _this3.hot.alter(INSERT_ROW_ALTER_ACTION_NAME, void 0, 1, _this3.pluginName + '.fill'); +TableView.prototype.render = function () { + this.wt.draw(!this.instance.forceFullRender); + this.instance.forceFullRender = false; + this.instance.renderCall = false; +}; - _this3.addingStarted = false; - }, INTERVAL_FOR_ADDING_ROW)); - } +/** + * Returns td object given coordinates + * + * @param {CellCoords} coords + * @param {Boolean} topmost + */ +TableView.prototype.getCellAtCoords = function (coords, topmost) { + var td = this.wt.getCell(coords, topmost); - /** - * Add new rows if they are needed to continue auto-filling values. - * - * @private - */ + if (td < 0) { + // there was an exit code (cell is out of bounds) + return null; + } - }, { - key: 'addNewRowIfNeeded', - value: function addNewRowIfNeeded() { - if (this.hot.view.wt.selections.fill.cellRange && this.addingStarted === false && this.autoInsertRow) { - var cornersOfSelectedCells = this.hot.getSelected(); - var cornersOfSelectedDragArea = this.hot.view.wt.selections.fill.getCorners(); - var nrOfTableRows = this.hot.countRows(); + return td; +}; - if (cornersOfSelectedCells[2] < nrOfTableRows - 1 && cornersOfSelectedDragArea[2] === nrOfTableRows - 1) { - this.addingStarted = true; +/** + * Scroll viewport to selection. + * + * @param {CellCoords} coords + */ +TableView.prototype.scrollViewport = function (coords) { + this.wt.scrollViewport(coords); +}; + +/** + * Append row header to a TH element + * @param row + * @param TH + */ +TableView.prototype.appendRowHeader = function (row, TH) { + if (TH.firstChild) { + var container = TH.firstChild; + + if (!(0, _element.hasClass)(container, 'relative')) { + (0, _element.empty)(TH); + this.appendRowHeader(row, TH); - this.addRow(); - } - } + return; } + this.updateCellHeader(container.querySelector('.rowHeader'), row, this.instance.getRowHeader); + } else { + var div = document.createElement('div'); + var span = document.createElement('span'); - /** - * Get corners of selected cells. - * - * @private - * @returns {Array} - */ + div.className = 'relative'; + span.className = 'rowHeader'; + this.updateCellHeader(span, row, this.instance.getRowHeader); - }, { - key: 'getCornersOfSelectedCells', - value: function getCornersOfSelectedCells() { - if (this.hot.selection.isMultiple()) { - return this.hot.view.wt.selections.area.getCorners(); - } - return this.hot.view.wt.selections.current.getCorners(); - } + div.appendChild(span); + TH.appendChild(div); + } - /** - * Get index of last adjacent filled in row - * - * @private - * @param {Array} cornersOfSelectedCells indexes of selection corners. - * @returns {Number} gives number greater than or equal to zero when selection adjacent can be applied. - * or -1 when selection adjacent can't be applied - */ + this.instance.runHooks('afterGetRowHeader', row, TH); +}; - }, { - key: 'getIndexOfLastAdjacentFilledInRow', - value: function getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells) { - var data = this.hot.getData(); - var nrOfTableRows = this.hot.countRows(); - var lastFilledInRowIndex = void 0; +/** + * Append column header to a TH element + * @param col + * @param TH + */ +TableView.prototype.appendColHeader = function (col, TH) { + if (TH.firstChild) { + var container = TH.firstChild; - for (var rowIndex = cornersOfSelectedCells[2] + 1; rowIndex < nrOfTableRows; rowIndex++) { - for (var columnIndex = cornersOfSelectedCells[1]; columnIndex <= cornersOfSelectedCells[3]; columnIndex++) { - var dataInCell = data[rowIndex][columnIndex]; + if ((0, _element.hasClass)(container, 'relative')) { + this.updateCellHeader(container.querySelector('.colHeader'), col, this.instance.getColHeader); + } else { + (0, _element.empty)(TH); + this.appendColHeader(col, TH); + } + } else { + var div = document.createElement('div'); + var span = document.createElement('span'); - if (dataInCell) { - return -1; - } - } + div.className = 'relative'; + span.className = 'colHeader'; + this.updateCellHeader(span, col, this.instance.getColHeader); - var dataInNextLeftCell = data[rowIndex][cornersOfSelectedCells[1] - 1]; - var dataInNextRightCell = data[rowIndex][cornersOfSelectedCells[3] + 1]; + div.appendChild(span); + TH.appendChild(div); + } - if (!!dataInNextLeftCell || !!dataInNextRightCell) { - lastFilledInRowIndex = rowIndex; - } - } - return lastFilledInRowIndex; - } + this.instance.runHooks('afterGetColHeader', col, TH); +}; - /** - * Add a selection from the start area to the specific row index. - * - * @private - * @param {Array} selectStartArea selection area from which we start to create more comprehensive selection. - * @param {Number} rowIndex - */ +/** + * Update header cell content + * + * @since 0.15.0-beta4 + * @param {HTMLElement} element Element to update + * @param {Number} index Row index or column index + * @param {Function} content Function which should be returns content for this cell + */ +TableView.prototype.updateCellHeader = function (element, index, content) { + var renderedIndex = index; + var parentOverlay = this.wt.wtOverlays.getParentOverlay(element) || this.wt; - }, { - key: 'addSelectionFromStartAreaToSpecificRowIndex', - value: function addSelectionFromStartAreaToSpecificRowIndex(selectStartArea, rowIndex) { - this.hot.view.wt.selections.fill.clear(); - this.hot.view.wt.selections.fill.add(new _src.CellCoords(selectStartArea[0], selectStartArea[1])); - this.hot.view.wt.selections.fill.add(new _src.CellCoords(rowIndex, selectStartArea[3])); + // prevent wrong calculations from SampleGenerator + if (element.parentNode) { + if ((0, _element.hasClass)(element, 'colHeader')) { + renderedIndex = parentOverlay.wtTable.columnFilter.sourceToRendered(index); + } else if ((0, _element.hasClass)(element, 'rowHeader')) { + renderedIndex = parentOverlay.wtTable.rowFilter.sourceToRendered(index); } + } - /** - * Set selection based on passed corners. - * - * @private - * @param {Array} cornersOfArea - */ + if (renderedIndex > -1) { + (0, _element.fastInnerHTML)(element, content(index)); + } else { + // workaround for https://github.com/handsontable/handsontable/issues/1946 + (0, _element.fastInnerText)(element, String.fromCharCode(160)); + (0, _element.addClass)(element, 'cornerHeader'); + } +}; - }, { - key: 'setSelection', - value: function setSelection(cornersOfArea) { - this.hot.selection.setRangeStart(new _src.CellCoords(cornersOfArea[0], cornersOfArea[1])); - this.hot.selection.setRangeEnd(new _src.CellCoords(cornersOfArea[2], cornersOfArea[3])); - } +/** + * Given a element's left position relative to the viewport, returns maximum element width until the right + * edge of the viewport (before scrollbar) + * + * @param {Number} leftOffset + * @return {Number} + */ +TableView.prototype.maximumVisibleElementWidth = function (leftOffset) { + var workspaceWidth = this.wt.wtViewport.getWorkspaceWidth(); + var maxWidth = workspaceWidth - leftOffset; + return maxWidth > 0 ? maxWidth : 0; +}; - /** - * Try to select cells down to the last row in the left column and then returns if selection was applied. - * - * @private - * @returns {Boolean} - */ +/** + * Given a element's top position relative to the viewport, returns maximum element height until the bottom + * edge of the viewport (before scrollbar) + * + * @param {Number} topOffset + * @return {Number} + */ +TableView.prototype.maximumVisibleElementHeight = function (topOffset) { + var workspaceHeight = this.wt.wtViewport.getWorkspaceHeight(); + var maxHeight = workspaceHeight - topOffset; + return maxHeight > 0 ? maxHeight : 0; +}; - }, { - key: 'selectAdjacent', - value: function selectAdjacent() { - var cornersOfSelectedCells = this.getCornersOfSelectedCells(); - var lastFilledInRowIndex = this.getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells); +TableView.prototype.mainViewIsActive = function () { + return this.wt === this.activeWt; +}; - if (lastFilledInRowIndex === -1) { - return false; - } - this.addSelectionFromStartAreaToSpecificRowIndex(cornersOfSelectedCells, lastFilledInRowIndex); +TableView.prototype.destroy = function () { + this.wt.destroy(); + this.eventManager.destroy(); +}; - return true; - } +exports.default = TableView; - /** - * Reset selection of dragged area. - * - * @private - */ +/***/ }), +/* 245 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'resetSelectionOfDraggedArea', - value: function resetSelectionOfDraggedArea() { - this.handleDraggedCells = 0; +"use strict"; - this.hot.view.wt.selections.fill.clear(); - } - /** - * Redraw borders. - * - * @private - * @param {CellCoords} coords `CellCoords` coord object. - */ +exports.__esModule = true; - }, { - key: 'redrawBorders', - value: function redrawBorders(coords) { - this.hot.view.wt.selections.fill.clear(); - this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().from); - this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().to); - this.hot.view.wt.selections.fill.add(coords); - this.hot.view.render(); - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - /** - * Get if mouse was dragged outside. - * - * @private - * @param {MouseEvent} event `mousemove` event properties. - * @returns {Boolean} - */ +var _object = __webpack_require__(1); - }, { - key: 'getIfMouseWasDraggedOutside', - value: function getIfMouseWasDraggedOutside(event) { - var tableBottom = (0, _element.offset)(this.hot.table).top - (window.pageYOffset || document.documentElement.scrollTop) + (0, _element.outerHeight)(this.hot.table); - var tableRight = (0, _element.offset)(this.hot.table).left - (window.pageXOffset || document.documentElement.scrollLeft) + (0, _element.outerWidth)(this.hot.table); +var _array = __webpack_require__(2); - return event.clientY > tableBottom && event.clientX <= tableRight; - } +var _number = __webpack_require__(6); - /** - * Bind the events used by the plugin. - * - * @private - */ +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - }, { - key: 'registerEvents', - value: function registerEvents() { - var _this4 = this; +/** + * @class DataSource + * @private + */ +var DataSource = function () { + function DataSource(hotInstance) { + var dataSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - this.eventManager.addEventListener(document.documentElement, 'mouseup', function () { - return _this4.onMouseUp(); - }); - this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) { - return _this4.onMouseMove(event); - }); - } + _classCallCheck(this, DataSource); /** - * On cell corner double click callback. + * Instance of Handsontable. * - * @private + * @type {Handsontable} */ - - }, { - key: 'onCellCornerDblClick', - value: function onCellCornerDblClick() { - var selectionApplied = this.selectAdjacent(); - - if (selectionApplied) { - this.fillIn(); - } - } - + this.hot = hotInstance; /** - * On after cell corner mouse down listener. + * Data source * - * @private + * @type {Array} */ - - }, { - key: 'onAfterCellCornerMouseDown', - value: function onAfterCellCornerMouseDown() { - this.handleDraggedCells = 1; - this.mouseDownOnCellCorner = true; - } - + this.data = dataSource; /** - * On before cell mouse over listener. + * Type of data source. * - * @private - * @param {CellCoords} coords `CellCoords` coord object. + * @type {String} + * @default 'array' */ + this.dataType = 'array'; - }, { - key: 'onBeforeCellMouseOver', - value: function onBeforeCellMouseOver(coords) { - if (this.mouseDownOnCellCorner && !this.hot.view.isMouseDown() && this.handleDraggedCells) { - this.handleDraggedCells++; + this.colToProp = function () {}; + this.propToCol = function () {}; + } - this.showBorder(coords); - this.addNewRowIfNeeded(); + /** + * Get all data. + * + * @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided + * in another format. + * @returns {Array} + */ + + + _createClass(DataSource, [{ + key: 'getData', + value: function getData() { + var toArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + var result = this.data; + + if (toArray) { + result = this.getByRange({ row: 0, col: 0 }, { row: Math.max(this.countRows() - 1, 0), col: Math.max(this.countColumns() - 1, 0) }, true); } + + return result; } /** - * On mouse up listener. + * Set new data source. * - * @private + * @param data {Array} */ }, { - key: 'onMouseUp', - value: function onMouseUp() { - if (this.handleDraggedCells) { - if (this.handleDraggedCells > 1) { - this.fillIn(); - } - - this.handleDraggedCells = 0; - this.mouseDownOnCellCorner = false; - } + key: 'setData', + value: function setData(data) { + this.data = data; } /** - * On mouse move listener. + * Returns array of column values from the data source. `column` is the index of the row in the data source. * - * @private - * @param {MouseEvent} event `mousemove` event properties. + * @param {Number} column Visual column index. + * @returns {Array} */ }, { - key: 'onMouseMove', - value: function onMouseMove(event) { - var mouseWasDraggedOutside = this.getIfMouseWasDraggedOutside(event); + key: 'getAtColumn', + value: function getAtColumn(column) { + var _this = this; - if (this.addingStarted === false && this.handleDraggedCells > 0 && mouseWasDraggedOutside) { - this.mouseDragOutside = true; - this.addingStarted = true; - } else { - this.mouseDragOutside = false; - } + var result = []; - if (this.mouseDragOutside && this.autoInsertRow) { - this.addRow(); - } - } + (0, _array.arrayEach)(this.data, function (row) { + var property = _this.colToProp(column); - /** - * Clear mapped settings. - * - * @private - */ + if (typeof property === 'string') { + row = (0, _object.getProperty)(row, property); + } else { + row = row[property]; + } + result.push(row); + }); - }, { - key: 'clearMappedSettings', - value: function clearMappedSettings() { - this.directions.length = 0; - this.autoInsertRow = false; + return result; } /** - * Map settings. + * Returns a single row of the data (array or object, depending on what you have). `row` is the index of the row in the data source. * - * @private + * @param {Number} row Physical row index. + * @returns {Array|Object} */ }, { - key: 'mapSettings', - value: function mapSettings() { - var mappedSettings = (0, _utils.getMappedFillHandleSetting)(this.hot.getSettings().fillHandle); - this.directions = mappedSettings.directions; - this.autoInsertRow = mappedSettings.autoInsertRow; + key: 'getAtRow', + value: function getAtRow(row) { + return this.data[row]; } /** - * Destroy plugin instance. + * Returns a single value from the data. + * + * @param {Number} row Physical row index. + * @param {Number} column Visual column index. + * @returns {*} */ }, { - key: 'destroy', - value: function destroy() { - _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'destroy', this).call(this); - } - }]); - - return Autofill; -}(_base2.default); - -(0, _plugins.registerPlugin)('autofill', Autofill); - -exports.default = Autofill; - -/***/ }), -/* 215 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.DIRECTIONS = undefined; -exports.getDeltas = getDeltas; -exports.getDragDirectionAndRange = getDragDirectionAndRange; -exports.getMappedFillHandleSetting = getMappedFillHandleSetting; - -var _object = __webpack_require__(1); - -var _mixed = __webpack_require__(20); - -var _src = __webpack_require__(11); - -var DIRECTIONS = exports.DIRECTIONS = { - horizontal: 'horizontal', - vertical: 'vertical' -}; - -/** - * Get deltas array. - * - * @param {CellCoords} start - * @param {CellCoords} end - * @param {Array} data - * @param {String} direction - * @returns {Array} - */ -function getDeltas(start, end, data, direction) { - var rowsLength = data.length; - var columnsLength = data ? data[0].length : 0; - var deltas = []; - var diffRow = end.row - start.row; - var diffCol = end.col - start.col; - - if (['down', 'up'].indexOf(direction) !== -1) { - var arr = []; - - for (var col = 0; col <= diffCol; col++) { - var startValue = parseInt(data[0][col], 10); - var endValue = parseInt(data[rowsLength - 1][col], 10); - var delta = (direction === 'down' ? endValue - startValue : startValue - endValue) / (rowsLength - 1) || 0; - - arr.push(delta); - } - - deltas.push(arr); - } - - if (['right', 'left'].indexOf(direction) !== -1) { - for (var row = 0; row <= diffRow; row++) { - var _startValue = parseInt(data[row][0], 10); - var _endValue = parseInt(data[row][columnsLength - 1], 10); - var _delta = (direction === 'right' ? _endValue - _startValue : _startValue - _endValue) / (columnsLength - 1) || 0; + key: 'getAtCell', + value: function getAtCell(row, column) { + var result = null; - deltas.push([_delta]); - } - } + var modifyRowData = this.hot.runHooks('modifyRowData', row); - return deltas; -} + var dataRow = isNaN(modifyRowData) ? modifyRowData : this.data[row]; -/** - * Get direction between positions and cords of selections difference (drag area) - * - * @param {Array} startSelection - * @param {Array} endSelection - * @returns {{direction: String, start: CellCoords, end: CellCoords}} - */ -function getDragDirectionAndRange(startSelection, endSelection) { - var startOfDragCoords = void 0, - endOfDragCoords = void 0, - directionOfDrag = void 0; + if (dataRow) { + var prop = this.colToProp(column); - if (endSelection[0] === startSelection[0] && endSelection[1] < startSelection[1]) { - directionOfDrag = 'left'; + if (typeof prop === 'string') { + result = (0, _object.getProperty)(dataRow, prop); + } else if (typeof prop === 'function') { + result = prop(this.data.slice(row, row + 1)[0]); + } else { + result = dataRow[prop]; + } + } - startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]); - endOfDragCoords = new _src.CellCoords(endSelection[2], startSelection[1] - 1); - } else if (endSelection[0] === startSelection[0] && endSelection[3] > startSelection[3]) { - directionOfDrag = 'right'; + return result; + } - startOfDragCoords = new _src.CellCoords(endSelection[0], startSelection[3] + 1); - endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]); - } else if (endSelection[0] < startSelection[0] && endSelection[1] === startSelection[1]) { - directionOfDrag = 'up'; + /** + * Returns source data by passed range. + * + * @param {Object} start Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects). + * @param {Object} end Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects). + * @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided + * in another format. + * @returns {Array} + */ - startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]); - endOfDragCoords = new _src.CellCoords(startSelection[0] - 1, endSelection[3]); - } else if (endSelection[2] > startSelection[2] && endSelection[1] === startSelection[1]) { - directionOfDrag = 'down'; + }, { + key: 'getByRange', + value: function getByRange(start, end) { + var _this2 = this; - startOfDragCoords = new _src.CellCoords(startSelection[2] + 1, endSelection[1]); - endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]); - } + var toArray = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - return { - directionOfDrag: directionOfDrag, - startOfDragCoords: startOfDragCoords, - endOfDragCoords: endOfDragCoords - }; -} + var startRow = Math.min(start.row, end.row); + var startCol = Math.min(start.col, end.col); + var endRow = Math.max(start.row, end.row); + var endCol = Math.max(start.col, end.col); + var result = []; -/** - * Get mapped FillHandle setting containing information about - * allowed FillHandle directions and if allowed is automatic insertion of rows on drag - * - * @param {Boolean|Object} fillHandle property of Handsontable settings - * @returns {{directions: Array, autoInsertRow: Boolean}} object allowing access to information - * about FillHandle in more useful way - */ -function getMappedFillHandleSetting(fillHandle) { - var mappedSettings = {}; + (0, _number.rangeEach)(startRow, endRow, function (currentRow) { + var row = _this2.getAtRow(currentRow); + var newRow = void 0; - if (fillHandle === true) { - mappedSettings.directions = Object.keys(DIRECTIONS); - mappedSettings.autoInsertRow = true; - } else if ((0, _object.isObject)(fillHandle)) { - if ((0, _mixed.isDefined)(fillHandle.autoInsertRow)) { + if (_this2.dataType === 'array') { + newRow = row.slice(startCol, endCol + 1); + } else if (_this2.dataType === 'object') { + newRow = toArray ? [] : {}; - // autoInsertRow for horizontal direction will be always false + (0, _number.rangeEach)(startCol, endCol, function (column) { + var prop = _this2.colToProp(column); - if (fillHandle.direction === DIRECTIONS.horizontal) { - mappedSettings.autoInsertRow = false; - } else { - mappedSettings.autoInsertRow = fillHandle.autoInsertRow; - } - } else { - mappedSettings.autoInsertRow = false; - } + if (toArray) { + newRow.push(row[prop]); + } else { + newRow[prop] = row[prop]; + } + }); + } - if ((0, _mixed.isDefined)(fillHandle.direction)) { - mappedSettings.directions = [fillHandle.direction]; - } else { - mappedSettings.directions = Object.keys(DIRECTIONS); + result.push(newRow); + }); + + return result; } - } else if (typeof fillHandle === 'string') { - mappedSettings.directions = [fillHandle]; - mappedSettings.autoInsertRow = true; - } else { - mappedSettings.directions = []; - mappedSettings.autoInsertRow = false; - } - return mappedSettings; -} + /** + * Count number of rows. + * + * @returns {Number} + */ -/***/ }), -/* 216 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: 'countRows', + value: function countRows() { + return Array.isArray(this.data) ? this.data.length : 0; + } -"use strict"; + /** + * Count number of columns. + * + * @returns {Number} + */ + }, { + key: 'countColumns', + value: function countColumns() { + var result = 0; -exports.__esModule = true; + if (Array.isArray(this.data)) { + if (this.dataType === 'array') { + result = this.data[0].length; + } else if (this.dataType === 'object') { + result = Object.keys(this.data[0]).length; + } + } -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + return result; + } -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + /** + * Destroy instance. + */ -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + }, { + key: 'destroy', + value: function destroy() { + this.data = null; + this.hot = null; + } + }]); -var _moment = __webpack_require__(61); + return DataSource; +}(); -var _moment2 = _interopRequireDefault(_moment); +exports.default = DataSource; -var _element = __webpack_require__(0); +/***/ }), +/* 246 */ +/***/ (function(module, exports, __webpack_require__) { -var _array = __webpack_require__(2); +"use strict"; -var _mixed = __webpack_require__(20); -var _object = __webpack_require__(1); +exports.__esModule = true; +exports.default = jQueryWrapper; +function jQueryWrapper(Handsontable) { + var jQuery = typeof window === 'undefined' ? false : window.jQuery; -var _base = __webpack_require__(12); + if (!jQuery) { + return; + } -var _base2 = _interopRequireDefault(_base); + jQuery.fn.handsontable = function (action) { + var $this = this.first(); // Use only first element from list + var instance = $this.data('handsontable'); -var _plugins = __webpack_require__(5); + // Init case + if (typeof action !== 'string') { + var userSettings = action || {}; -var _mergeSort = __webpack_require__(274); + if (instance) { + instance.updateSettings(userSettings); + } else { + instance = new Handsontable.Core($this[0], userSettings); + $this.data('handsontable', instance); + instance.init(); + } -var _mergeSort2 = _interopRequireDefault(_mergeSort); + return $this; + } -var _pluginHooks = __webpack_require__(8); + // Action case + var args = []; + var output = void 0; -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + if (arguments.length > 1) { + for (var i = 1, ilen = arguments.length; i < ilen; i++) { + args.push(arguments[i]); + } + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (instance) { + if (typeof instance[action] !== 'undefined') { + output = instance[action].apply(instance, args); -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + if (action === 'destroy') { + $this.removeData(); + } + } else { + throw new Error('Handsontable do not provide action: ' + action); + } + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + return output; + }; +}; -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +/***/ }), +/* 247 */ +/***/ (function(module, exports, __webpack_require__) { -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +"use strict"; -_pluginHooks2.default.getSingleton().register('beforeColumnSort'); -_pluginHooks2.default.getSingleton().register('afterColumnSort'); -// TODO: Implement mixin arrayMapper to ColumnSorting plugin. +exports.__esModule = true; +exports.Base = exports.UndoRedo = exports.TouchScroll = exports.Search = exports.PersistentState = exports.ObserveChanges = exports.MultipleSelectionHandles = exports.MergeCells = exports.ManualRowResize = exports.ManualRowMove = exports.ManualColumnResize = exports.ManualColumnMove = exports.ManualColumnFreeze = exports.DragToScroll = exports.CustomBorders = exports.CopyPaste = exports.ContextMenu = exports.Comments = exports.ColumnSorting = exports.AutoRowSize = exports.AutoFill = exports.AutoColumnSize = undefined; -/** - * @plugin ColumnSorting - * - * @description - * This plugin sorts the view by a column (but does not sort the data source!). - * To enable the plugin, set the `columnSorting` property to either: - * * a boolean value (`true`/`false`), - * * an object defining the initial sorting order (see the example below). - * - * @example - * ```js - * ... - * // as boolean - * columnSorting: true - * ... - * // as a object with initial order (sort ascending column at index 2) - * columnSorting: { - * column: 2, - * sortOrder: true, // true = ascending, false = descending, undefined = original order - * sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table - * } - * ... - * ``` - * @dependencies ObserveChanges - */ +var _autoColumnSize = __webpack_require__(248); -var ColumnSorting = function (_BasePlugin) { - _inherits(ColumnSorting, _BasePlugin); +var _autoColumnSize2 = _interopRequireDefault(_autoColumnSize); - function ColumnSorting(hotInstance) { - _classCallCheck(this, ColumnSorting); +var _autofill = __webpack_require__(249); - var _this2 = _possibleConstructorReturn(this, (ColumnSorting.__proto__ || Object.getPrototypeOf(ColumnSorting)).call(this, hotInstance)); +var _autofill2 = _interopRequireDefault(_autofill); - _this2.sortIndicators = []; - _this2.lastSortedColumn = null; - _this2.sortEmptyCells = false; - return _this2; - } +var _autoRowSize = __webpack_require__(251); - /** - * Check if the plugin is enabled in the handsontable settings. - * - * @returns {Boolean} - */ +var _autoRowSize2 = _interopRequireDefault(_autoRowSize); +var _columnSorting = __webpack_require__(252); - _createClass(ColumnSorting, [{ - key: 'isEnabled', - value: function isEnabled() { - return !!this.hot.getSettings().columnSorting; - } +var _columnSorting2 = _interopRequireDefault(_columnSorting); - /** - * Enable plugin for this Handsontable instance. - */ +var _comments = __webpack_require__(255); - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this3 = this; +var _comments2 = _interopRequireDefault(_comments); - if (this.enabled) { - return; - } +var _contextMenu = __webpack_require__(259); - this.setPluginOptions(); +var _contextMenu2 = _interopRequireDefault(_contextMenu); - var _this = this; - this.hot.sortIndex = []; +var _copyPaste = __webpack_require__(276); - this.hot.sort = function () { - var args = Array.prototype.slice.call(arguments); +var _copyPaste2 = _interopRequireDefault(_copyPaste); - return _this.sortByColumn.apply(_this, _toConsumableArray(args)); - }; +var _customBorders = __webpack_require__(281); - if (typeof this.hot.getSettings().observeChanges === 'undefined') { - this.enableObserveChangesPlugin(); - } +var _customBorders2 = _interopRequireDefault(_customBorders); - this.addHook('afterTrimRow', function (row) { - return _this3.sort(); - }); - this.addHook('afterUntrimRow', function (row) { - return _this3.sort(); - }); - this.addHook('modifyRow', function (row) { - return _this3.translateRow(row); - }); - this.addHook('unmodifyRow', function (row) { - return _this3.untranslateRow(row); - }); - this.addHook('afterUpdateSettings', function () { - return _this3.onAfterUpdateSettings(); - }); - this.addHook('afterGetColHeader', function (col, TH) { - return _this3.getColHeader(col, TH); - }); - this.addHook('afterOnCellMouseDown', function (event, target) { - return _this3.onAfterOnCellMouseDown(event, target); - }); - this.addHook('afterCreateRow', function () { - _this.afterCreateRow.apply(_this, arguments); - }); - this.addHook('afterRemoveRow', function () { - _this.afterRemoveRow.apply(_this, arguments); - }); - this.addHook('afterInit', function () { - return _this3.sortBySettings(); - }); - this.addHook('afterLoadData', function () { - _this3.hot.sortIndex = []; +var _dragToScroll = __webpack_require__(282); - if (_this3.hot.view) { - _this3.sortBySettings(); - } - }); - if (this.hot.view) { - this.sortBySettings(); - } - _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'enablePlugin', this).call(this); - } +var _dragToScroll2 = _interopRequireDefault(_dragToScroll); - /** - * Disable plugin for this Handsontable instance. - */ +var _manualColumnFreeze = __webpack_require__(283); - }, { - key: 'disablePlugin', - value: function disablePlugin() { - this.hot.sort = void 0; - _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'disablePlugin', this).call(this); - } +var _manualColumnFreeze2 = _interopRequireDefault(_manualColumnFreeze); - /** - * afterUpdateSettings callback. - * - * @private - */ +var _manualColumnMove = __webpack_require__(287); - }, { - key: 'onAfterUpdateSettings', - value: function onAfterUpdateSettings() { - this.sortBySettings(); - } - }, { - key: 'sortBySettings', - value: function sortBySettings() { - var sortingSettings = this.hot.getSettings().columnSorting; - var loadedSortingState = this.loadSortingState(); - var sortingColumn = void 0; - var sortingOrder = void 0; +var _manualColumnMove2 = _interopRequireDefault(_manualColumnMove); - if (typeof loadedSortingState === 'undefined') { - sortingColumn = sortingSettings.column; - sortingOrder = sortingSettings.sortOrder; - } else { - sortingColumn = loadedSortingState.sortColumn; - sortingOrder = loadedSortingState.sortOrder; - } - if (typeof sortingColumn === 'number') { - this.lastSortedColumn = sortingColumn; - this.sortByColumn(sortingColumn, sortingOrder); - } - } +var _manualColumnResize = __webpack_require__(292); - /** - * Set sorted column and order info - * - * @param {number} col Sorted visual column index. - * @param {boolean|undefined} order Sorting order (`true` for ascending, `false` for descending). - */ +var _manualColumnResize2 = _interopRequireDefault(_manualColumnResize); - }, { - key: 'setSortingColumn', - value: function setSortingColumn(col, order) { - if (typeof col == 'undefined') { - this.hot.sortColumn = void 0; - this.hot.sortOrder = void 0; +var _manualRowMove = __webpack_require__(293); - return; - } else if (this.hot.sortColumn === col && typeof order == 'undefined') { - if (this.hot.sortOrder === false) { - this.hot.sortOrder = void 0; - } else { - this.hot.sortOrder = !this.hot.sortOrder; - } - } else { - this.hot.sortOrder = typeof order === 'undefined' ? true : order; - } +var _manualRowMove2 = _interopRequireDefault(_manualRowMove); - this.hot.sortColumn = col; - } - }, { - key: 'sortByColumn', - value: function sortByColumn(col, order) { - this.setSortingColumn(col, order); +var _manualRowResize = __webpack_require__(298); - if (typeof this.hot.sortColumn == 'undefined') { - return; - } +var _manualRowResize2 = _interopRequireDefault(_manualRowResize); - var allowSorting = this.hot.runHooks('beforeColumnSort', this.hot.sortColumn, this.hot.sortOrder); +var _mergeCells = __webpack_require__(299); - if (allowSorting !== false) { - this.sort(); - } - this.updateOrderClass(); - this.updateSortIndicator(); +var _mergeCells2 = _interopRequireDefault(_mergeCells); - this.hot.runHooks('afterColumnSort', this.hot.sortColumn, this.hot.sortOrder); +var _multipleSelectionHandles = __webpack_require__(300); - this.hot.render(); - this.saveSortingState(); - } +var _multipleSelectionHandles2 = _interopRequireDefault(_multipleSelectionHandles); - /** - * Save the sorting state - */ +var _observeChanges = __webpack_require__(301); - }, { - key: 'saveSortingState', - value: function saveSortingState() { - var sortingState = {}; +var _observeChanges2 = _interopRequireDefault(_observeChanges); - if (typeof this.hot.sortColumn != 'undefined') { - sortingState.sortColumn = this.hot.sortColumn; - } +var _persistentState = __webpack_require__(304); - if (typeof this.hot.sortOrder != 'undefined') { - sortingState.sortOrder = this.hot.sortOrder; - } +var _persistentState2 = _interopRequireDefault(_persistentState); - if ((0, _object.hasOwnProperty)(sortingState, 'sortColumn') || (0, _object.hasOwnProperty)(sortingState, 'sortOrder')) { - this.hot.runHooks('persistentStateSave', 'columnSorting', sortingState); - } - } +var _search = __webpack_require__(305); - /** - * Load the sorting state. - * - * @returns {*} Previously saved sorting state. - */ +var _search2 = _interopRequireDefault(_search); - }, { - key: 'loadSortingState', - value: function loadSortingState() { - var storedState = {}; - this.hot.runHooks('persistentStateLoad', 'columnSorting', storedState); +var _touchScroll = __webpack_require__(306); - return storedState.value; - } +var _touchScroll2 = _interopRequireDefault(_touchScroll); - /** - * Update sorting class name state. - */ +var _undoRedo = __webpack_require__(307); - }, { - key: 'updateOrderClass', - value: function updateOrderClass() { - var orderClass = void 0; +var _undoRedo2 = _interopRequireDefault(_undoRedo); - if (this.hot.sortOrder === true) { - orderClass = 'ascending'; - } else if (this.hot.sortOrder === false) { - orderClass = 'descending'; - } - this.sortOrderClass = orderClass; - } - }, { - key: 'enableObserveChangesPlugin', - value: function enableObserveChangesPlugin() { - var _this = this; +var _base = __webpack_require__(13); - this.hot._registerTimeout(setTimeout(function () { - _this.hot.updateSettings({ - observeChanges: true - }); - }, 0)); - } +var _base2 = _interopRequireDefault(_base); - /** - * Default sorting algorithm. - * - * @param {Boolean} sortOrder Sorting order - `true` for ascending, `false` for descending. - * @param {Object} columnMeta Column meta object. - * @returns {Function} The comparing function. - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - }, { - key: 'defaultSort', - value: function defaultSort(sortOrder, columnMeta) { - return function (a, b) { - if (typeof a[1] == 'string') { - a[1] = a[1].toLowerCase(); - } - if (typeof b[1] == 'string') { - b[1] = b[1].toLowerCase(); - } +exports.AutoColumnSize = _autoColumnSize2.default; +exports.AutoFill = _autofill2.default; +exports.AutoRowSize = _autoRowSize2.default; +exports.ColumnSorting = _columnSorting2.default; +exports.Comments = _comments2.default; +exports.ContextMenu = _contextMenu2.default; +exports.CopyPaste = _copyPaste2.default; +exports.CustomBorders = _customBorders2.default; +exports.DragToScroll = _dragToScroll2.default; +exports.ManualColumnFreeze = _manualColumnFreeze2.default; +exports.ManualColumnMove = _manualColumnMove2.default; +exports.ManualColumnResize = _manualColumnResize2.default; +exports.ManualRowMove = _manualRowMove2.default; +exports.ManualRowResize = _manualRowResize2.default; +exports.MergeCells = _mergeCells2.default; +exports.MultipleSelectionHandles = _multipleSelectionHandles2.default; +exports.ObserveChanges = _observeChanges2.default; +exports.PersistentState = _persistentState2.default; +exports.Search = _search2.default; +exports.TouchScroll = _touchScroll2.default; +exports.UndoRedo = _undoRedo2.default; +exports.Base = _base2.default; - if (a[1] === b[1]) { - return 0; - } +/***/ }), +/* 248 */ +/***/ (function(module, exports, __webpack_require__) { - if ((0, _mixed.isEmpty)(a[1])) { - if ((0, _mixed.isEmpty)(b[1])) { - return 0; - } +"use strict"; - if (columnMeta.columnSorting.sortEmptyCells) { - return sortOrder ? -1 : 1; - } - return 1; - } - if ((0, _mixed.isEmpty)(b[1])) { - if ((0, _mixed.isEmpty)(a[1])) { - return 0; - } +exports.__esModule = true; - if (columnMeta.columnSorting.sortEmptyCells) { - return sortOrder ? 1 : -1; - } +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - return -1; - } +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - if (isNaN(a[1]) && !isNaN(b[1])) { - return sortOrder ? 1 : -1; - } else if (!isNaN(a[1]) && isNaN(b[1])) { - return sortOrder ? -1 : 1; - } else if (!(isNaN(a[1]) || isNaN(b[1]))) { - a[1] = parseFloat(a[1]); - b[1] = parseFloat(b[1]); - } - if (a[1] < b[1]) { - return sortOrder ? -1 : 1; - } - if (a[1] > b[1]) { - return sortOrder ? 1 : -1; - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - return 0; - }; - } +var _base = __webpack_require__(13); - /** - * Date sorting algorithm - * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending). - * @param {Object} columnMeta Column meta object. - * @returns {Function} The compare function. - */ +var _base2 = _interopRequireDefault(_base); - }, { - key: 'dateSort', - value: function dateSort(sortOrder, columnMeta) { - return function (a, b) { - if (a[1] === b[1]) { - return 0; - } +var _array = __webpack_require__(2); - if ((0, _mixed.isEmpty)(a[1])) { - if ((0, _mixed.isEmpty)(b[1])) { - return 0; - } +var _feature = __webpack_require__(34); - if (columnMeta.columnSorting.sortEmptyCells) { - return sortOrder ? -1 : 1; - } +var _element = __webpack_require__(0); - return 1; - } +var _ghostTable = __webpack_require__(85); - if ((0, _mixed.isEmpty)(b[1])) { - if ((0, _mixed.isEmpty)(a[1])) { - return 0; - } +var _ghostTable2 = _interopRequireDefault(_ghostTable); - if (columnMeta.columnSorting.sortEmptyCells) { - return sortOrder ? 1 : -1; - } +var _object = __webpack_require__(1); - return -1; - } +var _number = __webpack_require__(6); - var aDate = (0, _moment2.default)(a[1], columnMeta.dateFormat); - var bDate = (0, _moment2.default)(b[1], columnMeta.dateFormat); +var _plugins = __webpack_require__(5); - if (!aDate.isValid()) { - return 1; - } - if (!bDate.isValid()) { - return -1; - } +var _samplesGenerator = __webpack_require__(175); - if (bDate.isAfter(aDate)) { - return sortOrder ? -1 : 1; - } - if (bDate.isBefore(aDate)) { - return sortOrder ? 1 : -1; - } +var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator); - return 0; - }; - } +var _string = __webpack_require__(32); - /** - * Numeric sorting algorithm. - * - * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending). - * @param {Object} columnMeta Column meta object. - * @returns {Function} The compare function. - */ +var _src = __webpack_require__(12); - }, { - key: 'numericSort', - value: function numericSort(sortOrder, columnMeta) { - return function (a, b) { - var parsedA = parseFloat(a[1]); - var parsedB = parseFloat(b[1]); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // Watch out when changing this part of code! - // Check below returns 0 (as expected) when comparing empty string, null, undefined - if (parsedA === parsedB || isNaN(parsedA) && isNaN(parsedB)) { - return 0; - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - if (columnMeta.columnSorting.sortEmptyCells) { - if ((0, _mixed.isEmpty)(a[1])) { - return sortOrder ? -1 : 1; - } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - if ((0, _mixed.isEmpty)(b[1])) { - return sortOrder ? 1 : -1; - } - } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - if (isNaN(parsedA)) { - return 1; - } +var privatePool = new WeakMap(); - if (isNaN(parsedB)) { - return -1; - } +/** + * @plugin AutoColumnSize + * + * @description + * This plugin allows to set column widths based on their widest cells. + * + * By default, the plugin is declared as `undefined`, which makes it enabled (same as if it was declared as `true`). + * Enabling this plugin may decrease the overall table performance, as it needs to calculate the widths of all cells to + * resize the columns accordingly. + * If you experience problems with the performance, try turning this feature off and declaring the column widths manually. + * + * Column width calculations are divided into sync and async part. Each of this parts has their own advantages and + * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't + * block the browser UI. + * + * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object: + * ```js + * ... + * // as a number (300 columns in sync, rest async) + * autoColumnSize: {syncLimit: 300}, + * ... + * + * ... + * // as a string (percent) + * autoColumnSize: {syncLimit: '40%'}, + * ... + * ``` + * + * To configure this plugin see {@link Options#autoColumnSize}. + * + * @example + * ```js + * ... + * var hot = new Handsontable(document.getElementById('example'), { + * date: getData(), + * autoColumnSize: true + * }); + * // Access to plugin instance: + * var plugin = hot.getPlugin('autoColumnSize'); + * + * plugin.getColumnWidth(4); + * + * if (plugin.isEnabled()) { + * // code... + * } + * ... + * ``` + */ - if (parsedA < parsedB) { - return sortOrder ? -1 : 1; - } else if (parsedA > parsedB) { - return sortOrder ? 1 : -1; - } +var AutoColumnSize = function (_BasePlugin) { + _inherits(AutoColumnSize, _BasePlugin); - return 0; - }; + _createClass(AutoColumnSize, null, [{ + key: 'CALCULATION_STEP', + get: function get() { + return 50; } - - /** - * Perform the sorting. - */ - }, { - key: 'sort', - value: function sort() { - if (typeof this.hot.sortOrder == 'undefined') { - this.hot.sortIndex.length = 0; - - return; - } - - var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn); - var emptyRows = this.hot.countEmptyRows(); - var sortFunction = void 0; - var nrOfRows = void 0; - - this.hot.sortingEnabled = false; // this is required by translateRow plugin hook - this.hot.sortIndex.length = 0; + key: 'SYNC_CALCULATION_LIMIT', + get: function get() { + return 50; + } + }]); - if (typeof colMeta.columnSorting.sortEmptyCells === 'undefined') { - colMeta.columnSorting = { sortEmptyCells: this.sortEmptyCells }; - } + function AutoColumnSize(hotInstance) { + _classCallCheck(this, AutoColumnSize); - if (this.hot.getSettings().maxRows === Number.POSITIVE_INFINITY) { - nrOfRows = this.hot.countRows() - this.hot.getSettings().minSpareRows; - } else { - nrOfRows = this.hot.countRows() - emptyRows; - } + var _this = _possibleConstructorReturn(this, (AutoColumnSize.__proto__ || Object.getPrototypeOf(AutoColumnSize)).call(this, hotInstance)); - for (var i = 0, ilen = nrOfRows; i < ilen; i++) { - this.hot.sortIndex.push([i, this.hot.getDataAtCell(i, this.hot.sortColumn)]); - } + privatePool.set(_this, { + /** + * Cached column header names. It is used to diff current column headers with previous state and detect which + * columns width should be updated. + * + * @private + * @type {Array} + */ + cachedColumnHeaders: [] + }); + /** + * Cached columns widths. + * + * @type {Array} + */ + _this.widths = []; + /** + * Instance of {@link GhostTable} for rows and columns size calculations. + * + * @type {GhostTable} + */ + _this.ghostTable = new _ghostTable2.default(_this.hot); + /** + * Instance of {@link SamplesGenerator} for generating samples necessary for columns width calculations. + * + * @type {SamplesGenerator} + */ + _this.samplesGenerator = new _samplesGenerator2.default(function (row, col) { + return _this.hot.getDataAtCell(row, col); + }); + /** + * `true` only if the first calculation was performed + * + * @type {Boolean} + */ + _this.firstCalculation = true; + /** + * `true` if the size calculation is in progress. + * + * @type {Boolean} + */ + _this.inProgress = false; - if (colMeta.sortFunction) { - sortFunction = colMeta.sortFunction; - } else { - switch (colMeta.type) { - case 'date': - sortFunction = this.dateSort; - break; - case 'numeric': - sortFunction = this.numericSort; - break; - default: - sortFunction = this.defaultSort; - } - } + // moved to constructor to allow auto-sizing the columns when the plugin is disabled + _this.addHook('beforeColumnResize', function (col, size, isDblClick) { + return _this.onBeforeColumnResize(col, size, isDblClick); + }); + return _this; + } - (0, _mergeSort2.default)(this.hot.sortIndex, sortFunction(this.hot.sortOrder, colMeta)); + /** + * Check if the plugin is enabled in the handsontable settings. + * + * @returns {Boolean} + */ - // Append spareRows - for (var _i = this.hot.sortIndex.length; _i < this.hot.countRows(); _i++) { - this.hot.sortIndex.push([_i, this.hot.getDataAtCell(_i, this.hot.sortColumn)]); - } - this.hot.sortingEnabled = true; // this is required by translateRow plugin hook + _createClass(AutoColumnSize, [{ + key: 'isEnabled', + value: function isEnabled() { + return this.hot.getSettings().autoColumnSize !== false && !this.hot.getSettings().colWidths; } /** - * Update indicator states. + * Enable plugin for this Handsontable instance. */ }, { - key: 'updateSortIndicator', - value: function updateSortIndicator() { - if (typeof this.hot.sortOrder == 'undefined') { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; + + if (this.enabled) { return; } - var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn); - this.sortIndicators[this.hot.sortColumn] = colMeta.sortIndicator; + var setting = this.hot.getSettings().autoColumnSize; + + if (setting && setting.useHeaders != null) { + this.ghostTable.setSetting('useHeaders', setting.useHeaders); + } + + this.addHook('afterLoadData', function () { + return _this2.onAfterLoadData(); + }); + this.addHook('beforeChange', function (changes) { + return _this2.onBeforeChange(changes); + }); + + this.addHook('beforeRender', function (force) { + return _this2.onBeforeRender(force); + }); + this.addHook('modifyColWidth', function (width, col) { + return _this2.getColumnWidth(col, width); + }); + this.addHook('afterInit', function () { + return _this2.onAfterInit(); + }); + _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'enablePlugin', this).call(this); } /** - * `modifyRow` hook callback. Translates physical row index to the sorted row index. - * - * @param {Number} row Row index. - * @returns {Number} Sorted row index. + * Update plugin state. */ }, { - key: 'translateRow', - value: function translateRow(row) { - if (this.hot.sortingEnabled && typeof this.hot.sortOrder !== 'undefined' && this.hot.sortIndex && this.hot.sortIndex.length && this.hot.sortIndex[row]) { - return this.hot.sortIndex[row][0]; - } + key: 'updatePlugin', + value: function updatePlugin() { + var changedColumns = this.findColumnsWhereHeaderWasChanged(); - return row; + if (changedColumns.length) { + this.clearCache(changedColumns); + } + _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'updatePlugin', this).call(this); } /** - * Translates sorted row index to physical row index. - * - * @param {Number} row Sorted (visual) row index. - * @returns {number} Physical row index. + * Disable plugin for this Handsontable instance. */ }, { - key: 'untranslateRow', - value: function untranslateRow(row) { - if (this.hot.sortingEnabled && this.hot.sortIndex && this.hot.sortIndex.length) { - for (var i = 0; i < this.hot.sortIndex.length; i++) { - if (this.hot.sortIndex[i][0] == row) { - return i; - } - } - } + key: 'disablePlugin', + value: function disablePlugin() { + _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'disablePlugin', this).call(this); } /** - * `afterGetColHeader` callback. Adds column sorting css classes to clickable headers. + * Calculate a columns width. * - * @private - * @param {Number} col Visual column index. - * @param {Element} TH TH HTML element. + * @param {Number|Object} colRange Column range object. + * @param {Number|Object} rowRange Row range object. + * @param {Boolean} [force=false] If `true` force calculate width even when value was cached earlier. */ }, { - key: 'getColHeader', - value: function getColHeader(col, TH) { - if (col < 0 || !TH.parentNode) { - return false; - } + key: 'calculateColumnsWidth', + value: function calculateColumnsWidth() { + var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countCols() - 1 }; - var headerLink = TH.querySelector('.colHeader'); - var colspan = TH.getAttribute('colspan'); - var TRs = TH.parentNode.parentNode.childNodes; - var headerLevel = Array.prototype.indexOf.call(TRs, TH.parentNode); - headerLevel -= TRs.length; + var _this3 = this; - if (!headerLink) { - return; - } + var rowRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { from: 0, to: this.hot.countRows() - 1 }; + var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - if (this.hot.getSettings().columnSorting && col >= 0 && headerLevel === -1) { - (0, _element.addClass)(headerLink, 'columnSorting'); + if (typeof colRange === 'number') { + colRange = { from: colRange, to: colRange }; + } + if (typeof rowRange === 'number') { + rowRange = { from: rowRange, to: rowRange }; } - (0, _element.removeClass)(headerLink, 'descending'); - (0, _element.removeClass)(headerLink, 'ascending'); - if (this.sortIndicators[col]) { - if (col === this.hot.sortColumn) { - if (this.sortOrderClass === 'ascending') { - (0, _element.addClass)(headerLink, 'ascending'); - } else if (this.sortOrderClass === 'descending') { - (0, _element.addClass)(headerLink, 'descending'); - } + (0, _number.rangeEach)(colRange.from, colRange.to, function (col) { + if (force || _this3.widths[col] === void 0 && !_this3.hot._getColWidthFromSettings(col)) { + var samples = _this3.samplesGenerator.generateColumnSamples(col, rowRange); + + samples.forEach(function (sample, col) { + return _this3.ghostTable.addColumn(col, sample); + }); } + }); + + if (this.ghostTable.columns.length) { + this.ghostTable.getWidths(function (col, width) { + _this3.widths[col] = width; + }); + this.ghostTable.clean(); } } /** - * Check if any column is in a sorted state. + * Calculate all columns width. * - * @returns {Boolean} + * @param {Object|Number} rowRange Row range object. */ }, { - key: 'isSorted', - value: function isSorted() { - return typeof this.hot.sortColumn != 'undefined'; - } + key: 'calculateAllColumnsWidth', + value: function calculateAllColumnsWidth() { + var _this4 = this; - /** - * `afterCreateRow` callback. Updates the sorting state after a row have been created. - * - * @private - * @param {Number} index Visual row index. - * @param {Number} amount - */ + var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countRows() - 1 }; - }, { - key: 'afterCreateRow', - value: function afterCreateRow(index, amount) { - if (!this.isSorted()) { - return; - } + var current = 0; + var length = this.hot.countCols() - 1; + var timer = null; - for (var i = 0; i < this.hot.sortIndex.length; i++) { - if (this.hot.sortIndex[i][0] >= index) { - this.hot.sortIndex[i][0] += amount; + this.inProgress = true; + + var loop = function loop() { + // When hot was destroyed after calculating finished cancel frame + if (!_this4.hot) { + (0, _feature.cancelAnimationFrame)(timer); + _this4.inProgress = false; + + return; + } + + _this4.calculateColumnsWidth({ + from: current, + to: Math.min(current + AutoColumnSize.CALCULATION_STEP, length) + }, rowRange); + + current = current + AutoColumnSize.CALCULATION_STEP + 1; + + if (current < length) { + timer = (0, _feature.requestAnimationFrame)(loop); + } else { + (0, _feature.cancelAnimationFrame)(timer); + _this4.inProgress = false; + + // @TODO Should call once per render cycle, currently fired separately in different plugins + _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); + // tmp + if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) { + _this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw(); + } } + }; + // sync + if (this.firstCalculation && this.getSyncCalculationLimit()) { + this.calculateColumnsWidth({ from: 0, to: this.getSyncCalculationLimit() }, rowRange); + this.firstCalculation = false; + current = this.getSyncCalculationLimit() + 1; } - - for (var _i2 = 0; _i2 < amount; _i2++) { - this.hot.sortIndex.splice(index + _i2, 0, [index + _i2, this.hot.getSourceData()[index + _i2][this.hot.sortColumn + this.hot.colOffset()]]); + // async + if (current < length) { + loop(); + } else { + this.inProgress = false; } - - this.saveSortingState(); } /** - * `afterRemoveRow` hook callback. + * Set the sampling options. * * @private - * @param {Number} index Visual row index. - * @param {Number} amount */ }, { - key: 'afterRemoveRow', - value: function afterRemoveRow(index, amount) { - if (!this.isSorted()) { - return; - } - var removedRows = this.hot.sortIndex.splice(index, amount); - - removedRows = (0, _array.arrayMap)(removedRows, function (row) { - return row[0]; - }); - - function countRowShift(logicalRow) { - // Todo: compare perf between reduce vs sort->each->brake - return (0, _array.arrayReduce)(removedRows, function (count, removedLogicalRow) { - if (logicalRow > removedLogicalRow) { - count++; - } + key: 'setSamplingOptions', + value: function setSamplingOptions() { + var setting = this.hot.getSettings().autoColumnSize; + var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoColumnSize.samplingRatio : void 0; + var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoColumnSize.allowSampleDuplicates : void 0; - return count; - }, 0); + if (samplingRatio && !isNaN(samplingRatio)) { + this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10)); } - this.hot.sortIndex = (0, _array.arrayMap)(this.hot.sortIndex, function (logicalRow, physicalRow) { - var rowShift = countRowShift(logicalRow[0]); - - if (rowShift) { - logicalRow[0] -= rowShift; - } - - return logicalRow; - }); - - this.saveSortingState(); + if (allowSampleDuplicates) { + this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates); + } } /** - * Set options by passed settings - * - * @private + * Recalculate all columns width (overwrite cache values). */ }, { - key: 'setPluginOptions', - value: function setPluginOptions() { - var columnSorting = this.hot.getSettings().columnSorting; - - if ((typeof columnSorting === 'undefined' ? 'undefined' : _typeof(columnSorting)) === 'object') { - this.sortEmptyCells = columnSorting.sortEmptyCells || false; - } else { - this.sortEmptyCells = false; + key: 'recalculateAllColumnsWidth', + value: function recalculateAllColumnsWidth() { + if (this.hot.view && (0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) { + this.clearCache(); + this.calculateAllColumnsWidth(); } } /** - * `onAfterOnCellMouseDown` hook callback. + * Get value which tells how many columns should be calculated synchronously. Rest of the columns will be calculated asynchronously. * - * @private - * @param {Event} event Event which are provided by hook. - * @param {CellCoords} coords Visual coords of the selected cell. + * @returns {Number} */ }, { - key: 'onAfterOnCellMouseDown', - value: function onAfterOnCellMouseDown(event, coords) { - if (coords.row > -1) { - return; - } - - if ((0, _element.hasClass)(event.realTarget, 'columnSorting')) { - // reset order state on every new column header click - if (coords.col !== this.lastSortedColumn) { - this.hot.sortOrder = true; - } + key: 'getSyncCalculationLimit', + value: function getSyncCalculationLimit() { + /* eslint-disable no-bitwise */ + var limit = AutoColumnSize.SYNC_CALCULATION_LIMIT; + var colsLimit = this.hot.countCols() - 1; - this.lastSortedColumn = coords.col; + if ((0, _object.isObject)(this.hot.getSettings().autoColumnSize)) { + limit = this.hot.getSettings().autoColumnSize.syncLimit; - this.sortByColumn(coords.col); + if ((0, _string.isPercentValue)(limit)) { + limit = (0, _number.valueAccordingPercent)(colsLimit, limit); + } else { + // Force to Number + limit >>= 0; + } } - } - }]); - - return ColumnSorting; -}(_base2.default); - -(0, _plugins.registerPlugin)('columnSorting', ColumnSorting); - -exports.default = ColumnSorting; -/***/ }), -/* 217 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _element = __webpack_require__(0); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * Comment editor for the Comments plugin. - * - * @class CommentEditor - * @plugin Comments - */ -var CommentEditor = function () { - _createClass(CommentEditor, null, [{ - key: 'CLASS_EDITOR_CONTAINER', - get: function get() { - return 'htCommentsContainer'; - } - }, { - key: 'CLASS_EDITOR', - get: function get() { - return 'htComments'; - } - }, { - key: 'CLASS_INPUT', - get: function get() { - return 'htCommentTextArea'; - } - }, { - key: 'CLASS_CELL', - get: function get() { - return 'htCommentCell'; + return Math.min(limit, colsLimit); } - }]); - - function CommentEditor() { - _classCallCheck(this, CommentEditor); - this.editor = this.createEditor(); - this.editorStyle = this.editor.style; + /** + * Get the calculated column width. + * + * @param {Number} col Column index. + * @param {Number} [defaultWidth] Default column width. It will be picked up if no calculated width found. + * @param {Boolean} [keepMinimum=true] If `true` then returned value won't be smaller then 50 (default column width). + * @returns {Number} + */ - this.hidden = true; + }, { + key: 'getColumnWidth', + value: function getColumnWidth(col) { + var defaultWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0; + var keepMinimum = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; - this.hide(); - } + var width = defaultWidth; - /** - * Set position of the comments editor according to the provided x and y coordinates. - * - * @param {Number} x X position (in pixels). - * @param {Number} y Y position (in pixels). - */ + if (width === void 0) { + width = this.widths[col]; + if (keepMinimum && typeof width === 'number') { + width = Math.max(width, _src.ViewportColumnsCalculator.DEFAULT_WIDTH); + } + } - _createClass(CommentEditor, [{ - key: 'setPosition', - value: function setPosition(x, y) { - this.editorStyle.left = x + 'px'; - this.editorStyle.top = y + 'px'; + return width; } /** - * Set the editor size according to the provided arguments. + * Get the first visible column. * - * @param {Number} width Width in pixels. - * @param {Number} height Height in pixels. + * @returns {Number} Returns column index or -1 if table is not rendered. */ }, { - key: 'setSize', - value: function setSize(width, height) { - if (width && height) { - var input = this.getInputElement(); + key: 'getFirstVisibleColumn', + value: function getFirstVisibleColumn() { + var wot = this.hot.view.wt; - input.style.width = width + 'px'; - input.style.height = height + 'px'; + if (wot.wtViewport.columnsVisibleCalculator) { + return wot.wtTable.getFirstVisibleColumn(); + } + if (wot.wtViewport.columnsRenderCalculator) { + return wot.wtTable.getFirstRenderedColumn(); } + + return -1; } /** - * Reset the editor size to its initial state. + * Get the last visible column. + * + * @returns {Number} Returns column index or -1 if table is not rendered. */ }, { - key: 'resetSize', - value: function resetSize() { - var input = this.getInputElement(); + key: 'getLastVisibleColumn', + value: function getLastVisibleColumn() { + var wot = this.hot.view.wt; - input.style.width = ''; - input.style.height = ''; + if (wot.wtViewport.columnsVisibleCalculator) { + return wot.wtTable.getLastVisibleColumn(); + } + if (wot.wtViewport.columnsRenderCalculator) { + return wot.wtTable.getLastRenderedColumn(); + } + + return -1; } /** - * Set the read-only state for the comments editor. + * Collects all columns which titles has been changed in comparison to the previous state. * - * @param {Boolean} state The new read only state. + * @returns {Array} It returns an array of physical column indexes. */ }, { - key: 'setReadOnlyState', - value: function setReadOnlyState(state) { - var input = this.getInputElement(); + key: 'findColumnsWhereHeaderWasChanged', + value: function findColumnsWhereHeaderWasChanged() { + var columnHeaders = this.hot.getColHeader(); - input.readOnly = state; - } + var _privatePool$get = privatePool.get(this), + cachedColumnHeaders = _privatePool$get.cachedColumnHeaders; - /** - * Show the comments editor. - */ + var changedColumns = (0, _array.arrayReduce)(columnHeaders, function (acc, columnTitle, physicalColumn) { + var cachedColumnsLength = cachedColumnHeaders.length; - }, { - key: 'show', - value: function show() { - this.editorStyle.display = 'block'; - this.hidden = false; + if (cachedColumnsLength - 1 < physicalColumn || cachedColumnHeaders[physicalColumn] !== columnTitle) { + acc.push(physicalColumn); + } + if (cachedColumnsLength - 1 < physicalColumn) { + cachedColumnHeaders.push(columnTitle); + } else { + cachedColumnHeaders[physicalColumn] = columnTitle; + } + + return acc; + }, []); + + return changedColumns; } /** - * Hide the comments editor. + * Clear cache of calculated column widths. If you want to clear only selected columns pass an array with their indexes. + * Otherwise whole cache will be cleared. + * + * @param {Array} [columns=[]] List of column indexes (physical indexes) to clear. */ }, { - key: 'hide', - value: function hide() { - this.editorStyle.display = 'none'; - this.hidden = true; + key: 'clearCache', + value: function clearCache() { + var _this5 = this; + + var columns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + if (columns.length) { + (0, _array.arrayEach)(columns, function (physicalIndex) { + _this5.widths[physicalIndex] = void 0; + }); + } else { + this.widths.length = 0; + } } /** - * Checks if the editor is visible. + * Check if all widths were calculated. If not then return `true` (need recalculate). * * @returns {Boolean} */ }, { - key: 'isVisible', - value: function isVisible() { - return this.editorStyle.display === 'block'; + key: 'isNeedRecalculate', + value: function isNeedRecalculate() { + return !!(0, _array.arrayFilter)(this.widths, function (item) { + return item === void 0; + }).length; } /** - * Set the comment value. + * On before render listener. * - * @param {String} [value] The value to use. + * @private */ }, { - key: 'setValue', - value: function setValue() { - var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + key: 'onBeforeRender', + value: function onBeforeRender() { + var force = this.hot.renderCall; + var rowsCount = this.hot.countRows(); - value = value || ''; - this.getInputElement().value = value; + // Keep last column widths unchanged for situation when all rows was deleted or trimmed (pro #6) + if (!rowsCount) { + return; + } + + this.calculateColumnsWidth({ from: this.getFirstVisibleColumn(), to: this.getLastVisibleColumn() }, void 0, force); + + if (this.isNeedRecalculate() && !this.inProgress) { + this.calculateAllColumnsWidth(); + } } /** - * Get the comment value. + * On after load data listener. * - * @returns {String} + * @private */ }, { - key: 'getValue', - value: function getValue() { - return this.getInputElement().value; + key: 'onAfterLoadData', + value: function onAfterLoadData() { + var _this6 = this; + + if (this.hot.view) { + this.recalculateAllColumnsWidth(); + } else { + // first load - initialization + setTimeout(function () { + if (_this6.hot) { + _this6.recalculateAllColumnsWidth(); + } + }, 0); + } } /** - * Checks if the comment input element is focused. + * On before change listener. * - * @returns {Boolean} + * @private + * @param {Array} changes */ }, { - key: 'isFocused', - value: function isFocused() { - return document.activeElement === this.getInputElement(); - } + key: 'onBeforeChange', + value: function onBeforeChange(changes) { + var _this7 = this; - /** - * Focus the comments input element. - */ + var changedColumns = (0, _array.arrayMap)(changes, function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + row = _ref2[0], + column = _ref2[1]; - }, { - key: 'focus', - value: function focus() { - this.getInputElement().focus(); + return _this7.hot.propToCol(column); + }); + + this.clearCache(changedColumns); } /** - * Create the `textarea` to be used as a comments editor. + * On before column resize listener. * - * @returns {HTMLElement} + * @private + * @param {Number} col + * @param {Number} size + * @param {Boolean} isDblClick + * @returns {Number} */ }, { - key: 'createEditor', - value: function createEditor() { - var container = document.querySelector('.' + CommentEditor.CLASS_EDITOR_CONTAINER); - var editor = void 0; - var textArea = void 0; - - if (!container) { - container = document.createElement('div'); - (0, _element.addClass)(container, CommentEditor.CLASS_EDITOR_CONTAINER); - document.body.appendChild(container); + key: 'onBeforeColumnResize', + value: function onBeforeColumnResize(col, size, isDblClick) { + if (isDblClick) { + this.calculateColumnsWidth(col, void 0, true); + size = this.getColumnWidth(col, void 0, false); } - editor = document.createElement('div'); - (0, _element.addClass)(editor, CommentEditor.CLASS_EDITOR); - - textArea = document.createElement('textarea'); - (0, _element.addClass)(textArea, CommentEditor.CLASS_INPUT); - editor.appendChild(textArea); - container.appendChild(editor); - - return editor; + return size; } /** - * Get the input element. + * On after Handsontable init fill plugin with all necessary values. * - * @returns {HTMLElement} + * @private */ }, { - key: 'getInputElement', - value: function getInputElement() { - return this.editor.querySelector('.' + CommentEditor.CLASS_INPUT); + key: 'onAfterInit', + value: function onAfterInit() { + privatePool.get(this).cachedColumnHeaders = this.hot.getColHeader(); } /** - * Destroy the comments editor. + * Destroy plugin instance. */ }, { key: 'destroy', value: function destroy() { - this.editor.parentNode.removeChild(this.editor); - this.editor = null; - this.editorStyle = null; + this.ghostTable.clean(); + _get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'destroy', this).call(this); } }]); - return CommentEditor; -}(); + return AutoColumnSize; +}(_base2.default); -exports.default = CommentEditor; +(0, _plugins.registerPlugin)('autoColumnSize', AutoColumnSize); + +exports.default = AutoColumnSize; /***/ }), -/* 218 */ +/* 249 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -51321,158 +51331,104 @@ var _createClass = function () { function defineProperties(target, props) { for var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var _element = __webpack_require__(0); - -var _object = __webpack_require__(1); - -var _eventManager = __webpack_require__(4); - -var _eventManager2 = _interopRequireDefault(_eventManager); - -var _src = __webpack_require__(11); +var _base = __webpack_require__(13); -var _plugins = __webpack_require__(5); +var _base2 = _interopRequireDefault(_base); -var _base = __webpack_require__(12); +var _pluginHooks = __webpack_require__(7); -var _base2 = _interopRequireDefault(_base); +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); -var _commentEditor = __webpack_require__(217); +var _element = __webpack_require__(0); -var _commentEditor2 = _interopRequireDefault(_commentEditor); +var _eventManager = __webpack_require__(4); -var _utils = __webpack_require__(17); +var _eventManager2 = _interopRequireDefault(_eventManager); -var _displaySwitch = __webpack_require__(219); +var _plugins = __webpack_require__(5); -var _displaySwitch2 = _interopRequireDefault(_displaySwitch); +var _src = __webpack_require__(12); -__webpack_require__(298); +var _utils = __webpack_require__(250); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var privatePool = new WeakMap(); -var META_COMMENT = 'comment'; -var META_COMMENT_VALUE = 'value'; -var META_STYLE = 'style'; -var META_READONLY = 'readOnly'; +_pluginHooks2.default.getSingleton().register('modifyAutofillRange'); +_pluginHooks2.default.getSingleton().register('beforeAutofill'); + +var INSERT_ROW_ALTER_ACTION_NAME = 'insert_row'; +var INTERVAL_FOR_ADDING_ROW = 200; /** - * @plugin Comments - * - * @description - * This plugin allows setting and managing cell comments by either an option in the context menu or with the use of the API. - * - * To enable the plugin, you'll need to set the comments property of the config object to `true`: - * ```js - * ... - * comments: true - * ... - * ``` - * - * or object with extra predefined plugin config: - * - * ```js - * ... - * comments: { - * displayDelay: 1000 - * } - * ... - * ``` - * - * To add comments at the table initialization, define the `comment` property in the `cell` config array as in an example below. - * - * @example - * - * ```js - * ... - * var hot = new Handsontable(document.getElementById('example'), { - * date: getData(), - * comments: true, - * cell: [ - * {row: 1, col: 1, comment: {value: 'Foo'}}, - * {row: 2, col: 2, comment: {value: 'Bar'}} - * ] - * }); + * This plugin provides "drag-down" and "copy-down" functionalities, both operated + * using the small square in the right bottom of the cell selection. * - * // Access to the Comments plugin instance: - * var commentsPlugin = hot.getPlugin('comments'); + * "Drag-down" expands the value of the selected cells to the neighbouring + * cells when you drag the small square in the corner. * - * // Manage comments programmatically: - * commentsPlugin.setCommentAtCell(1, 6, 'Comment contents'); - * commentsPlugin.showAtCell(1, 6); - * commentsPlugin.removeCommentAtCell(1, 6); + * "Copy-down" copies the value of the selection to all empty cells + * below when you double click the small square. * - * // You can also set range once and use proper methods: - * commentsPlugin.setRange({row: 1, col: 6}); - * commentsPlugin.setComment('Comment contents'); - * commentsPlugin.show(); - * commentsPlugin.removeComment(); - * ... - * ``` + * @class Autofill + * @plugin Autofill */ -var Comments = function (_BasePlugin) { - _inherits(Comments, _BasePlugin); +var Autofill = function (_BasePlugin) { + _inherits(Autofill, _BasePlugin); - function Comments(hotInstance) { - _classCallCheck(this, Comments); + function Autofill(hotInstance) { + _classCallCheck(this, Autofill); /** - * Instance of {@link CommentEditor}. + * Event manager * - * @type {CommentEditor} + * @type {EventManager} */ - var _this = _possibleConstructorReturn(this, (Comments.__proto__ || Object.getPrototypeOf(Comments)).call(this, hotInstance)); + var _this = _possibleConstructorReturn(this, (Autofill.__proto__ || Object.getPrototypeOf(Autofill)).call(this, hotInstance)); - _this.editor = null; + _this.eventManager = new _eventManager2.default(_this); /** - * Instance of {@link DisplaySwitch}. + * Specifies if adding new row started. * - * @type {DisplaySwitch} + * @type {Boolean} */ - _this.displaySwitch = null; + _this.addingStarted = false; /** - * Instance of {@link EventManager}. + * Specifies if there was mouse down on the cell corner. * - * @private - * @type {EventManager} + * @type {Boolean} */ - _this.eventManager = null; + _this.mouseDownOnCellCorner = false; /** - * Current cell range. + * Specifies if mouse was dragged outside Handsontable. * - * @type {Object} + * @type {Boolean} */ - _this.range = {}; + _this.mouseDragOutside = false; /** - * @private + * Specifies how many cell levels were dragged using the handle. + * * @type {Boolean} */ - _this.mouseDown = false; + _this.handleDraggedCells = 0; /** - * @private - * @type {Boolean} + * Specifies allowed directions of drag. + * + * @type {Array} */ - _this.contextMenuEvent = false; + _this.directions = []; /** - * @private - * @type {*} + * Specifies if can insert new rows if needed. + * + * @type {Boolean} */ - _this.timer = null; - - privatePool.set(_this, { - tempEditorDimensions: {}, - cellBelowCursor: null - }); + _this.autoInsertRow = false; return _this; } @@ -51483,10 +51439,10 @@ var Comments = function (_BasePlugin) { */ - _createClass(Comments, [{ + _createClass(Autofill, [{ key: 'isEnabled', value: function isEnabled() { - return !!this.hot.getSettings().comments; + return this.hot.getSettings().fillHandle; } /** @@ -51502,44 +51458,20 @@ var Comments = function (_BasePlugin) { return; } - if (!this.editor) { - this.editor = new _commentEditor2.default(); - } - - if (!this.eventManager) { - this.eventManager = new _eventManager2.default(this); - } - - if (!this.displaySwitch) { - this.displaySwitch = new _displaySwitch2.default(this.getDisplayDelaySetting()); - } + this.mapSettings(); + this.registerEvents(); - this.addHook('afterContextMenuDefaultOptions', function (options) { - return _this2.addToContextMenu(options); - }); - this.addHook('afterRenderer', function (TD, row, col, prop, value, cellProperties) { - return _this2.onAfterRenderer(TD, cellProperties); - }); - this.addHook('afterScrollHorizontally', function () { - return _this2.hide(); - }); - this.addHook('afterScrollVertically', function () { - return _this2.hide(); - }); - this.addHook('afterBeginEditing', function (args) { - return _this2.onAfterBeginEditing(args); + this.addHook('afterOnCellCornerMouseDown', function (event) { + return _this2.onAfterCellCornerMouseDown(event); }); - - this.displaySwitch.addLocalHook('hide', function () { - return _this2.hide(); + this.addHook('afterOnCellCornerDblClick', function (event) { + return _this2.onCellCornerDblClick(event); }); - this.displaySwitch.addLocalHook('show', function (row, col) { - return _this2.showAtCell(row, col); + this.addHook('beforeOnCellMouseOver', function (event, coords, TD) { + return _this2.onBeforeCellMouseOver(coords); }); - this.registerListeners(); - - _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'enablePlugin', this).call(this); + _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'enablePlugin', this).call(this); } /** @@ -51551,9 +51483,7 @@ var Comments = function (_BasePlugin) { value: function updatePlugin() { this.disablePlugin(); this.enablePlugin(); - _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'updatePlugin', this).call(this); - - this.displaySwitch.updateDelay(this.getDisplayDelaySetting()); + _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'updatePlugin', this).call(this); } /** @@ -51563,994 +51493,662 @@ var Comments = function (_BasePlugin) { }, { key: 'disablePlugin', value: function disablePlugin() { - _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'disablePlugin', this).call(this); + this.clearMappedSettings(); + _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'disablePlugin', this).call(this); } /** - * Register all necessary DOM listeners. + * Get selection data * * @private + * @returns {Array} Array with the data. */ }, { - key: 'registerListeners', - value: function registerListeners() { - var _this3 = this; - - this.eventManager.addEventListener(document, 'mouseover', function (event) { - return _this3.onMouseOver(event); - }); - this.eventManager.addEventListener(document, 'mousedown', function (event) { - return _this3.onMouseDown(event); - }); - this.eventManager.addEventListener(document, 'mouseup', function (event) { - return _this3.onMouseUp(event); - }); - this.eventManager.addEventListener(this.editor.getInputElement(), 'blur', function (event) { - return _this3.onEditorBlur(event); - }); - this.eventManager.addEventListener(this.editor.getInputElement(), 'mousedown', function (event) { - return _this3.onEditorMouseDown(event); - }); - this.eventManager.addEventListener(this.editor.getInputElement(), 'mouseup', function (event) { - return _this3.onEditorMouseUp(event); - }); - } - - /** - * Set current cell range to be able to use general methods like {@link Comments#setComment}, - * {@link Comments#removeComment}, {@link Comments#show}. - * - * @param {Object} range Object with `from` and `to` properties, each with `row` and `col` properties. - */ - - }, { - key: 'setRange', - value: function setRange(range) { - this.range = range; - } - - /** - * Clear the currently selected cell. - */ - - }, { - key: 'clearRange', - value: function clearRange() { - this.range = {}; - } - - /** - * Check if the event target is a cell containing a comment. - * - * @param {Event} event DOM event - * @returns {Boolean} - */ - - }, { - key: 'targetIsCellWithComment', - value: function targetIsCellWithComment(event) { - var closestCell = (0, _element.closest)(event.target, 'TD', 'TBODY'); - - return !!(closestCell && (0, _element.hasClass)(closestCell, 'htCommentCell') && (0, _element.closest)(closestCell, [this.hot.rootElement])); - } - - /** - * Check if the event target is a comment textarea. - * - * @param {Event} event DOM event. - * @returns {Boolean} - */ - - }, { - key: 'targetIsCommentTextArea', - value: function targetIsCommentTextArea(event) { - return this.editor.getInputElement() === event.target; - } - - /** - * Set a comment for a cell according to the previously set range (see {@link Comments#setRange}). - * - * @param {String} value Comment contents. - */ - - }, { - key: 'setComment', - value: function setComment(value) { - if (!this.range.from) { - throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())'); - } - var editorValue = this.editor.getValue(); - var comment = ''; - - if (value != null) { - comment = value; - } else if (editorValue != null) { - comment = editorValue; - } - - var row = this.range.from.row; - var col = this.range.from.col; - - this.updateCommentMeta(row, col, _defineProperty({}, META_COMMENT_VALUE, comment)); - this.hot.render(); - } - - /** - * Set a comment for a cell. - * - * @param {Number} row Visual row index. - * @param {Number} col Visual column index. - * @param {String} value Comment contents. - */ - - }, { - key: 'setCommentAtCell', - value: function setCommentAtCell(row, col, value) { - this.setRange({ - from: new _src.CellCoords(row, col) - }); - this.setComment(value); - } - - /** - * Remove a comment from a cell according to previously set range (see {@link Comments#setRange}). - * - * @param {Boolean} [forceRender = true] If set to `true`, the table will be re-rendered at the end of the operation. - */ - - }, { - key: 'removeComment', - value: function removeComment() { - var forceRender = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - - if (!this.range.from) { - throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())'); - } - - this.hot.setCellMeta(this.range.from.row, this.range.from.col, META_COMMENT, void 0); - - if (forceRender) { - this.hot.render(); - } - - this.hide(); - } - - /** - * Remove comment from a cell. - * - * @param {Number} row Visual row index. - * @param {Number} col Visual column index. - * @param {Boolean} [forceRender = true] If `true`, the table will be re-rendered at the end of the operation. - */ - - }, { - key: 'removeCommentAtCell', - value: function removeCommentAtCell(row, col) { - var forceRender = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; - - this.setRange({ - from: new _src.CellCoords(row, col) - }); - this.removeComment(forceRender); - } - - /** - * Get comment from a cell at the predefined range. - */ - - }, { - key: 'getComment', - value: function getComment() { - var row = this.range.from.row; - var column = this.range.from.col; - - return this.getCommentMeta(row, column, META_COMMENT_VALUE); - } - - /** - * Get comment from a cell at the provided coordinates. - * - * @param {Number} row Visual row index. - * @param {Number} column Visual column index. - */ + key: 'getSelectionData', + value: function getSelectionData() { + var selRange = { + from: this.hot.getSelectedRange().from, + to: this.hot.getSelectedRange().to + }; - }, { - key: 'getCommentAtCell', - value: function getCommentAtCell(row, column) { - return this.getCommentMeta(row, column, META_COMMENT_VALUE); + return this.hot.getData(selRange.from.row, selRange.from.col, selRange.to.row, selRange.to.col); } /** - * Show the comment editor accordingly to the previously set range (see {@link Comments#setRange}). + * Try to apply fill values to the area in fill border, omitting the selection border. * - * @returns {Boolean} Returns `true` if comment editor was shown. + * @private + * @returns {Boolean} reports if fill was applied. */ }, { - key: 'show', - value: function show() { - if (!this.range.from) { - throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())'); - } - var meta = this.hot.getCellMeta(this.range.from.row, this.range.from.col); - - this.refreshEditor(true); - this.editor.setValue(meta[META_COMMENT] ? meta[META_COMMENT][META_COMMENT_VALUE] : null || ''); - - if (this.editor.hidden) { - this.editor.show(); + key: 'fillIn', + value: function fillIn() { + if (this.hot.view.wt.selections.fill.isEmpty()) { + return false; } - return true; - } + var cornersOfSelectionAndDragAreas = this.hot.view.wt.selections.fill.getCorners(); - /** - * Show comment editor according to cell coordinates. - * - * @param {Number} row Visual row index. - * @param {Number} col Visual column index. - * @returns {Boolean} Returns `true` if comment editor was shown. - */ + this.resetSelectionOfDraggedArea(); - }, { - key: 'showAtCell', - value: function showAtCell(row, col) { - this.setRange({ - from: new _src.CellCoords(row, col) - }); + var cornersOfSelectedCells = this.getCornersOfSelectedCells(); - return this.show(); - } + var _getDragDirectionAndR = (0, _utils.getDragDirectionAndRange)(cornersOfSelectedCells, cornersOfSelectionAndDragAreas), + directionOfDrag = _getDragDirectionAndR.directionOfDrag, + startOfDragCoords = _getDragDirectionAndR.startOfDragCoords, + endOfDragCoords = _getDragDirectionAndR.endOfDragCoords; - /** - * Hide the comment editor. - */ + this.hot.runHooks('modifyAutofillRange', cornersOfSelectedCells, cornersOfSelectionAndDragAreas); - }, { - key: 'hide', - value: function hide() { - if (!this.editor.hidden) { - this.editor.hide(); - } - } + if (startOfDragCoords && startOfDragCoords.row > -1 && startOfDragCoords.col > -1) { + var selectionData = this.getSelectionData(); + var deltas = (0, _utils.getDeltas)(startOfDragCoords, endOfDragCoords, selectionData, directionOfDrag); + var fillData = selectionData; - /** - * Refresh comment editor position and styling. - * - * @param {Boolean} [force=false] If `true` then recalculation will be forced. - */ + this.hot.runHooks('beforeAutofill', startOfDragCoords, endOfDragCoords, selectionData); - }, { - key: 'refreshEditor', - value: function refreshEditor() { - var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + if (['up', 'left'].indexOf(directionOfDrag) > -1) { + fillData = []; - if (!force && (!this.range.from || !this.editor.isVisible())) { - return; - } - var scrollableElement = (0, _element.getScrollableElement)(this.hot.view.wt.wtTable.TABLE); - var TD = this.hot.view.wt.wtTable.getCell(this.range.from); - var row = this.range.from.row; - var column = this.range.from.col; - var cellOffset = (0, _element.offset)(TD); - var lastColWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(column); - var cellTopOffset = cellOffset.top < 0 ? 0 : cellOffset.top; - var cellLeftOffset = cellOffset.left; + var dragLength = null; + var fillOffset = null; - if (this.hot.view.wt.wtViewport.hasVerticalScroll() && scrollableElement !== window) { - cellTopOffset -= this.hot.view.wt.wtOverlays.topOverlay.getScrollPosition(); - } + if (directionOfDrag === 'up') { + dragLength = endOfDragCoords.row - startOfDragCoords.row + 1; + fillOffset = dragLength % selectionData.length; - if (this.hot.view.wt.wtViewport.hasHorizontalScroll() && scrollableElement !== window) { - cellLeftOffset -= this.hot.view.wt.wtOverlays.leftOverlay.getScrollPosition(); - } + for (var i = 0; i < dragLength; i++) { + fillData.push(selectionData[(i + (selectionData.length - fillOffset)) % selectionData.length]); + } + } else { + dragLength = endOfDragCoords.col - startOfDragCoords.col + 1; + fillOffset = dragLength % selectionData[0].length; - var x = cellLeftOffset + lastColWidth; - var y = cellTopOffset; + for (var _i = 0; _i < selectionData.length; _i++) { + fillData.push([]); + for (var j = 0; j < dragLength; j++) { + fillData[_i].push(selectionData[_i][(j + (selectionData[_i].length - fillOffset)) % selectionData[_i].length]); + } + } + } + } - var commentStyle = this.getCommentMeta(row, column, META_STYLE); - var readOnly = this.getCommentMeta(row, column, META_READONLY); + this.hot.populateFromArray(startOfDragCoords.row, startOfDragCoords.col, fillData, endOfDragCoords.row, endOfDragCoords.col, this.pluginName + '.fill', null, directionOfDrag, deltas); - if (commentStyle) { - this.editor.setSize(commentStyle.width, commentStyle.height); + this.setSelection(cornersOfSelectionAndDragAreas); } else { - this.editor.resetSize(); + // reset to avoid some range bug + this.hot.selection.refreshBorders(); } - this.editor.setReadOnlyState(readOnly); - - this.editor.setPosition(x, y); + return true; } /** - * Check if there is a comment for selected range. + * Reduce the selection area if the handle was dragged outside of the table or on headers. * * @private - * @returns {Boolean} + * @param {CellCoords} coords indexes of selection corners. + * @returns {CellCoords} */ }, { - key: 'checkSelectionCommentsConsistency', - value: function checkSelectionCommentsConsistency() { - var selected = this.hot.getSelectedRange(); - - if (!selected) { - return false; + key: 'reduceSelectionAreaIfNeeded', + value: function reduceSelectionAreaIfNeeded(coords) { + if (coords.row < 0) { + coords.row = 0; } - var hasComment = false; - var cell = selected.from; // IN EXCEL THERE IS COMMENT ONLY FOR TOP LEFT CELL IN SELECTION - if (this.getCommentMeta(cell.row, cell.col, META_COMMENT_VALUE)) { - hasComment = true; + if (coords.col < 0) { + coords.col = 0; } - - return hasComment; + return coords; } /** - * Set or update the comment-related cell meta. + * Get the coordinates of the drag & drop borders. * - * @param {Number} row Visual row index. - * @param {Number} column Visual column index. - * @param {Object} metaObject Object defining all the comment-related meta information. + * @private + * @param {CellCoords} coordsOfSelection `CellCoords` coord object. + * @returns {Array} */ }, { - key: 'updateCommentMeta', - value: function updateCommentMeta(row, column, metaObject) { - var oldComment = this.hot.getCellMeta(row, column)[META_COMMENT]; - var newComment = void 0; + key: 'getCoordsOfDragAndDropBorders', + value: function getCoordsOfDragAndDropBorders(coordsOfSelection) { + var topLeftCorner = this.hot.getSelectedRange().getTopLeftCorner(); + var bottomRightCorner = this.hot.getSelectedRange().getBottomRightCorner(); + var coords = void 0; - if (oldComment) { - newComment = (0, _object.deepClone)(oldComment); - (0, _object.deepExtend)(newComment, metaObject); + if (this.directions.includes(_utils.DIRECTIONS.vertical) && (bottomRightCorner.row < coordsOfSelection.row || topLeftCorner.row > coordsOfSelection.row)) { + coords = new _src.CellCoords(coordsOfSelection.row, bottomRightCorner.col); + } else if (this.directions.includes(_utils.DIRECTIONS.horizontal)) { + coords = new _src.CellCoords(bottomRightCorner.row, coordsOfSelection.col); } else { - newComment = metaObject; + // wrong direction + return; } - this.hot.setCellMeta(row, column, META_COMMENT, newComment); + return this.reduceSelectionAreaIfNeeded(coords); } /** - * Get the comment related meta information. + * Show the fill border. * - * @param {Number} row Visual row index. - * @param {Number} column Visual column index. - * @param {String} property Cell meta property. - * @returns {Mixed} + * @private + * @param {CellCoords} coordsOfSelection `CellCoords` coord object. */ }, { - key: 'getCommentMeta', - value: function getCommentMeta(row, column, property) { - var cellMeta = this.hot.getCellMeta(row, column); - - if (!cellMeta[META_COMMENT]) { - return void 0; - } + key: 'showBorder', + value: function showBorder(coordsOfSelection) { + var coordsOfDragAndDropBorders = this.getCoordsOfDragAndDropBorders(coordsOfSelection); - return cellMeta[META_COMMENT][property]; + if (coordsOfDragAndDropBorders) { + this.redrawBorders(coordsOfDragAndDropBorders); + } } /** - * `mousedown` event callback. + * Add new row * * @private - * @param {MouseEvent} event The `mousedown` event. */ }, { - key: 'onMouseDown', - value: function onMouseDown(event) { - this.mouseDown = true; - - if (!this.hot.view || !this.hot.view.wt) { - return; - } - - if (!this.contextMenuEvent && !this.targetIsCommentTextArea(event)) { - var eventCell = (0, _element.closest)(event.target, 'TD', 'TBODY'); - var coordinates = null; + key: 'addRow', + value: function addRow() { + var _this3 = this; - if (eventCell) { - coordinates = this.hot.view.wt.wtTable.getCoords(eventCell); - } + this.hot._registerTimeout(setTimeout(function () { + _this3.hot.alter(INSERT_ROW_ALTER_ACTION_NAME, void 0, 1, _this3.pluginName + '.fill'); - if (!eventCell || this.range.from && coordinates && (this.range.from.row !== coordinates.row || this.range.from.col !== coordinates.col)) { - this.hide(); - } - } - this.contextMenuEvent = false; + _this3.addingStarted = false; + }, INTERVAL_FOR_ADDING_ROW)); } /** - * `mouseover` event callback. + * Add new rows if they are needed to continue auto-filling values. * * @private - * @param {MouseEvent} event The `mouseover` event. */ }, { - key: 'onMouseOver', - value: function onMouseOver(event) { - var priv = privatePool.get(this); - - priv.cellBelowCursor = document.elementFromPoint(event.clientX, event.clientY); - - if (this.mouseDown || this.editor.isFocused() || (0, _element.hasClass)(event.target, 'wtBorder') || priv.cellBelowCursor !== event.target || !this.editor) { - return; - } + key: 'addNewRowIfNeeded', + value: function addNewRowIfNeeded() { + if (this.hot.view.wt.selections.fill.cellRange && this.addingStarted === false && this.autoInsertRow) { + var cornersOfSelectedCells = this.hot.getSelected(); + var cornersOfSelectedDragArea = this.hot.view.wt.selections.fill.getCorners(); + var nrOfTableRows = this.hot.countRows(); - if (this.targetIsCellWithComment(event)) { - var coordinates = this.hot.view.wt.wtTable.getCoords(event.target); - var range = { - from: new _src.CellCoords(coordinates.row, coordinates.col) - }; + if (cornersOfSelectedCells[2] < nrOfTableRows - 1 && cornersOfSelectedDragArea[2] === nrOfTableRows - 1) { + this.addingStarted = true; - this.displaySwitch.show(range); - } else if ((0, _element.isChildOf)(event.target, document) && !this.targetIsCommentTextArea(event)) { - this.displaySwitch.hide(); + this.addRow(); + } } } /** - * `mouseup` event callback. + * Get corners of selected cells. * * @private - * @param {MouseEvent} event The `mouseup` event. + * @returns {Array} */ }, { - key: 'onMouseUp', - value: function onMouseUp(event) { - this.mouseDown = false; + key: 'getCornersOfSelectedCells', + value: function getCornersOfSelectedCells() { + if (this.hot.selection.isMultiple()) { + return this.hot.view.wt.selections.area.getCorners(); + } + return this.hot.view.wt.selections.current.getCorners(); } - /** * - * The `afterRenderer` hook callback.. + /** + * Get index of last adjacent filled in row * * @private - * @param {HTMLTableCellElement} TD The rendered `TD` element. - * @param {Object} cellProperties The rendered cell's property object. + * @param {Array} cornersOfSelectedCells indexes of selection corners. + * @returns {Number} gives number greater than or equal to zero when selection adjacent can be applied. + * or -1 when selection adjacent can't be applied */ }, { - key: 'onAfterRenderer', - value: function onAfterRenderer(TD, cellProperties) { - if (cellProperties[META_COMMENT] && cellProperties[META_COMMENT][META_COMMENT_VALUE]) { - (0, _element.addClass)(TD, cellProperties.commentedCellClassName); + key: 'getIndexOfLastAdjacentFilledInRow', + value: function getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells) { + var data = this.hot.getData(); + var nrOfTableRows = this.hot.countRows(); + var lastFilledInRowIndex = void 0; + + for (var rowIndex = cornersOfSelectedCells[2] + 1; rowIndex < nrOfTableRows; rowIndex++) { + for (var columnIndex = cornersOfSelectedCells[1]; columnIndex <= cornersOfSelectedCells[3]; columnIndex++) { + var dataInCell = data[rowIndex][columnIndex]; + + if (dataInCell) { + return -1; + } + } + + var dataInNextLeftCell = data[rowIndex][cornersOfSelectedCells[1] - 1]; + var dataInNextRightCell = data[rowIndex][cornersOfSelectedCells[3] + 1]; + + if (!!dataInNextLeftCell || !!dataInNextRightCell) { + lastFilledInRowIndex = rowIndex; + } } + return lastFilledInRowIndex; } /** - * `blur` event callback for the comment editor. + * Add a selection from the start area to the specific row index. * * @private - * @param {Event} event The `blur` event. + * @param {Array} selectStartArea selection area from which we start to create more comprehensive selection. + * @param {Number} rowIndex */ }, { - key: 'onEditorBlur', - value: function onEditorBlur(event) { - this.setComment(); + key: 'addSelectionFromStartAreaToSpecificRowIndex', + value: function addSelectionFromStartAreaToSpecificRowIndex(selectStartArea, rowIndex) { + this.hot.view.wt.selections.fill.clear(); + this.hot.view.wt.selections.fill.add(new _src.CellCoords(selectStartArea[0], selectStartArea[1])); + this.hot.view.wt.selections.fill.add(new _src.CellCoords(rowIndex, selectStartArea[3])); } /** - * `mousedown` hook. Along with `onEditorMouseUp` used to simulate the textarea resizing event. + * Set selection based on passed corners. * * @private - * @param {MouseEvent} event The `mousedown` event. + * @param {Array} cornersOfArea */ }, { - key: 'onEditorMouseDown', - value: function onEditorMouseDown(event) { - var priv = privatePool.get(this); - - priv.tempEditorDimensions = { - width: (0, _element.outerWidth)(event.target), - height: (0, _element.outerHeight)(event.target) - }; + key: 'setSelection', + value: function setSelection(cornersOfArea) { + this.hot.selection.setRangeStart(new _src.CellCoords(cornersOfArea[0], cornersOfArea[1])); + this.hot.selection.setRangeEnd(new _src.CellCoords(cornersOfArea[2], cornersOfArea[3])); } /** - * `mouseup` hook. Along with `onEditorMouseDown` used to simulate the textarea resizing event. + * Try to select cells down to the last row in the left column and then returns if selection was applied. * * @private - * @param {MouseEvent} event The `mouseup` event. + * @returns {Boolean} */ }, { - key: 'onEditorMouseUp', - value: function onEditorMouseUp(event) { - var priv = privatePool.get(this); - var currentWidth = (0, _element.outerWidth)(event.target); - var currentHeight = (0, _element.outerHeight)(event.target); + key: 'selectAdjacent', + value: function selectAdjacent() { + var cornersOfSelectedCells = this.getCornersOfSelectedCells(); + var lastFilledInRowIndex = this.getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells); - if (currentWidth !== priv.tempEditorDimensions.width + 1 || currentHeight !== priv.tempEditorDimensions.height + 2) { - this.updateCommentMeta(this.range.from.row, this.range.from.col, _defineProperty({}, META_STYLE, { - width: currentWidth, - height: currentHeight - })); + if (lastFilledInRowIndex === -1) { + return false; } + this.addSelectionFromStartAreaToSpecificRowIndex(cornersOfSelectedCells, lastFilledInRowIndex); + + return true; } /** - * Context Menu's "Add comment" callback. Results in showing the comment editor. + * Reset selection of dragged area. * * @private */ }, { - key: 'onContextMenuAddComment', - value: function onContextMenuAddComment() { - var _this4 = this; - - this.displaySwitch.cancelHiding(); - var coords = this.hot.getSelectedRange(); + key: 'resetSelectionOfDraggedArea', + value: function resetSelectionOfDraggedArea() { + this.handleDraggedCells = 0; - this.contextMenuEvent = true; - this.setRange({ - from: coords.from - }); - this.show(); - setTimeout(function () { - if (_this4.hot) { - _this4.hot.deselectCell(); - _this4.editor.focus(); - } - }, 10); + this.hot.view.wt.selections.fill.clear(); } /** - * Context Menu's "remove comment" callback. + * Redraw borders. * * @private - * @param {Object} selection The current selection. + * @param {CellCoords} coords `CellCoords` coord object. */ }, { - key: 'onContextMenuRemoveComment', - value: function onContextMenuRemoveComment(selection) { - this.contextMenuEvent = true; - - for (var i = selection.start.row; i <= selection.end.row; i++) { - for (var j = selection.start.col; j <= selection.end.col; j++) { - this.removeCommentAtCell(i, j, false); - } - } - - this.hot.render(); + key: 'redrawBorders', + value: function redrawBorders(coords) { + this.hot.view.wt.selections.fill.clear(); + this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().from); + this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().to); + this.hot.view.wt.selections.fill.add(coords); + this.hot.view.render(); } /** - * Context Menu's "make comment read-only" callback. + * Get if mouse was dragged outside. * * @private - * @param {Object} selection The current selection. + * @param {MouseEvent} event `mousemove` event properties. + * @returns {Boolean} */ }, { - key: 'onContextMenuMakeReadOnly', - value: function onContextMenuMakeReadOnly(selection) { - this.contextMenuEvent = true; - - for (var i = selection.start.row; i <= selection.end.row; i++) { - for (var j = selection.start.col; j <= selection.end.col; j++) { - var currentState = !!this.getCommentMeta(i, j, META_READONLY); + key: 'getIfMouseWasDraggedOutside', + value: function getIfMouseWasDraggedOutside(event) { + var tableBottom = (0, _element.offset)(this.hot.table).top - (window.pageYOffset || document.documentElement.scrollTop) + (0, _element.outerHeight)(this.hot.table); + var tableRight = (0, _element.offset)(this.hot.table).left - (window.pageXOffset || document.documentElement.scrollLeft) + (0, _element.outerWidth)(this.hot.table); - this.updateCommentMeta(i, j, _defineProperty({}, META_READONLY, !currentState)); - } - } + return event.clientY > tableBottom && event.clientX <= tableRight; } /** - * Add Comments plugin options to the Context Menu. + * Bind the events used by the plugin. * * @private - * @param {Object} defaultOptions */ }, { - key: 'addToContextMenu', - value: function addToContextMenu(defaultOptions) { - var _this5 = this; - - defaultOptions.items.push({ - name: '---------' - }, { - key: 'commentsAddEdit', - name: function name() { - return _this5.checkSelectionCommentsConsistency() ? 'Edit comment' : 'Add comment'; - }, - callback: function callback() { - return _this5.onContextMenuAddComment(); - }, - disabled: function disabled() { - return !(this.getSelected() && !this.selection.selectedHeader.corner); - } - }, { - key: 'commentsRemove', - name: function name() { - return 'Delete comment'; - }, - - callback: function callback(key, selection) { - return _this5.onContextMenuRemoveComment(selection); - }, - disabled: function disabled() { - return _this5.hot.selection.selectedHeader.corner; - } - }, { - key: 'commentsReadOnly', - name: function name() { - var _this6 = this; - - var label = 'Read only comment'; - var hasProperty = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var readOnlyProperty = _this6.getCellMeta(row, col)[META_COMMENT]; - if (readOnlyProperty) { - readOnlyProperty = readOnlyProperty[META_READONLY]; - } - - if (readOnlyProperty) { - return true; - } - }); - - if (hasProperty) { - label = (0, _utils.markLabelAsSelected)(label); - } - - return label; - }, + key: 'registerEvents', + value: function registerEvents() { + var _this4 = this; - callback: function callback(key, selection) { - return _this5.onContextMenuMakeReadOnly(selection); - }, - disabled: function disabled() { - return _this5.hot.selection.selectedHeader.corner || !_this5.checkSelectionCommentsConsistency(); - } + this.eventManager.addEventListener(document.documentElement, 'mouseup', function () { + return _this4.onMouseUp(); + }); + this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) { + return _this4.onMouseMove(event); }); } /** - * Get `displayDelay` setting of comment plugin. + * On cell corner double click callback. * - * @returns {Number|undefined} + * @private */ }, { - key: 'getDisplayDelaySetting', - value: function getDisplayDelaySetting() { - var commentSetting = this.hot.getSettings().comments; + key: 'onCellCornerDblClick', + value: function onCellCornerDblClick() { + var selectionApplied = this.selectAdjacent(); - if ((0, _object.isObject)(commentSetting)) { - return commentSetting.displayDelay; + if (selectionApplied) { + this.fillIn(); } - - return void 0; } /** - * `afterBeginEditing` hook callback. + * On after cell corner mouse down listener. * * @private - * @param {Number} row Visual row index of the currently edited cell. - * @param {Number} column Visual column index of the currently edited cell. */ }, { - key: 'onAfterBeginEditing', - value: function onAfterBeginEditing(row, column) { - this.hide(); + key: 'onAfterCellCornerMouseDown', + value: function onAfterCellCornerMouseDown() { + this.handleDraggedCells = 1; + this.mouseDownOnCellCorner = true; } /** - * Destroy plugin instance. + * On before cell mouse over listener. + * + * @private + * @param {CellCoords} coords `CellCoords` coord object. */ }, { - key: 'destroy', - value: function destroy() { - if (this.editor) { - this.editor.destroy(); - } + key: 'onBeforeCellMouseOver', + value: function onBeforeCellMouseOver(coords) { + if (this.mouseDownOnCellCorner && !this.hot.view.isMouseDown() && this.handleDraggedCells) { + this.handleDraggedCells++; - if (this.displaySwitch) { - this.displaySwitch.destroy(); + this.showBorder(coords); + this.addNewRowIfNeeded(); } - - _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'destroy', this).call(this); } - }]); - - return Comments; -}(_base2.default); - -(0, _plugins.registerPlugin)('comments', Comments); - -exports.default = Comments; - -/***/ }), -/* 219 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _function = __webpack_require__(35); - -var _object = __webpack_require__(1); - -var _localHooks = __webpack_require__(69); - -var _localHooks2 = _interopRequireDefault(_localHooks); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var DEFAULT_DISPLAY_DELAY = 250; -var DEFAULT_HIDE_DELAY = 250; - -/** - * Display switch for the Comments plugin. Manages the time of delayed displaying / hiding comments. - * - * @class DisplaySwitch - * @plugin Comments - */ - -var DisplaySwitch = function () { - function DisplaySwitch(displayDelay) { - _classCallCheck(this, DisplaySwitch); /** - * Flag to determine if comment can be showed or hidden. State `true` mean that last performed action - * was an attempt to show comment element. State `false` mean that it was attempt to hide comment element. - * - * @type {Boolean} - */ - this.wasLastActionShow = true; - /** - * Show comment after predefined delay. It keeps reference to immutable `debounce` function. - * - * @type {Function} - */ - this.showDebounced = null; - /** - * Reference to timer, run by `setTimeout`, which is hiding comment + * On mouse up listener. * - * @type {Number} + * @private */ - this.hidingTimer = null; - - this.updateDelay(displayDelay); - } - - /** - * Responsible for hiding comment after proper delay. - */ - - - _createClass(DisplaySwitch, [{ - key: 'hide', - value: function hide() { - var _this = this; - this.wasLastActionShow = false; - - this.hidingTimer = setTimeout(function () { - if (_this.wasLastActionShow === false) { - _this.runLocalHooks('hide'); + }, { + key: 'onMouseUp', + value: function onMouseUp() { + if (this.handleDraggedCells) { + if (this.handleDraggedCells > 1) { + this.fillIn(); } - }, DEFAULT_HIDE_DELAY); + + this.handleDraggedCells = 0; + this.mouseDownOnCellCorner = false; + } } /** - * Responsible for showing comment after proper delay. + * On mouse move listener. * - * @param {Object} range Coordinates of selected cell. + * @private + * @param {MouseEvent} event `mousemove` event properties. */ }, { - key: 'show', - value: function show(range) { - this.wasLastActionShow = true; - this.showDebounced(range); - } - }, { - key: 'cancelHiding', + key: 'onMouseMove', + value: function onMouseMove(event) { + var mouseWasDraggedOutside = this.getIfMouseWasDraggedOutside(event); + + if (this.addingStarted === false && this.handleDraggedCells > 0 && mouseWasDraggedOutside) { + this.mouseDragOutside = true; + this.addingStarted = true; + } else { + this.mouseDragOutside = false; + } + if (this.mouseDragOutside && this.autoInsertRow) { + this.addRow(); + } + } /** - * Cancel hiding comment. + * Clear mapped settings. + * + * @private */ - value: function cancelHiding() { - this.wasLastActionShow = true; - clearTimeout(this.hidingTimer); - this.hidingTimer = null; + }, { + key: 'clearMappedSettings', + value: function clearMappedSettings() { + this.directions.length = 0; + this.autoInsertRow = false; } /** - * Update the switch settings. + * Map settings. * - * @param {Number} displayDelay Delay of showing the comments (in milliseconds). + * @private */ }, { - key: 'updateDelay', - value: function updateDelay() { - var _this2 = this; - - var displayDelay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_DISPLAY_DELAY; - - this.showDebounced = (0, _function.debounce)(function (range) { - if (_this2.wasLastActionShow) { - _this2.runLocalHooks('show', range.from.row, range.from.col); - } - }, displayDelay); + key: 'mapSettings', + value: function mapSettings() { + var mappedSettings = (0, _utils.getMappedFillHandleSetting)(this.hot.getSettings().fillHandle); + this.directions = mappedSettings.directions; + this.autoInsertRow = mappedSettings.autoInsertRow; } /** - * Destroy the switcher. + * Destroy plugin instance. */ }, { key: 'destroy', value: function destroy() { - this.clearLocalHooks(); + _get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'destroy', this).call(this); } }]); - return DisplaySwitch; -}(); + return Autofill; +}(_base2.default); -(0, _object.mixin)(DisplaySwitch, _localHooks2.default); +(0, _plugins.registerPlugin)('autofill', Autofill); -exports.default = DisplaySwitch; +exports.default = Autofill; /***/ }), -/* 220 */ +/* 250 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; +exports.DIRECTIONS = undefined; +exports.getDeltas = getDeltas; +exports.getDragDirectionAndRange = getDragDirectionAndRange; +exports.getMappedFillHandleSetting = getMappedFillHandleSetting; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _object = __webpack_require__(1); -var _array = __webpack_require__(2); +var _mixed = __webpack_require__(22); -var _object = __webpack_require__(1); +var _src = __webpack_require__(12); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var DIRECTIONS = exports.DIRECTIONS = { + horizontal: 'horizontal', + vertical: 'vertical' +}; /** - * Command executor for ContextMenu. + * Get deltas array. * - * @class CommandExecutor - * @plugin ContextMenu + * @param {CellCoords} start + * @param {CellCoords} end + * @param {Array} data + * @param {String} direction + * @returns {Array} */ -var CommandExecutor = function () { - function CommandExecutor(hotInstance) { - _classCallCheck(this, CommandExecutor); - - this.hot = hotInstance; - this.commands = {}; - this.commonCallback = null; - } +function getDeltas(start, end, data, direction) { + var rowsLength = data.length; + var columnsLength = data ? data[0].length : 0; + var deltas = []; + var diffRow = end.row - start.row; + var diffCol = end.col - start.col; - /** - * Register command. - * - * @param {String} name Command name. - * @param {Object} commandDescriptor Command descriptor object with properties like `key` (command id), - * `callback` (task to execute), `name` (command name), `disabled` (command availability). - */ + if (['down', 'up'].indexOf(direction) !== -1) { + var arr = []; + for (var col = 0; col <= diffCol; col++) { + var startValue = parseInt(data[0][col], 10); + var endValue = parseInt(data[rowsLength - 1][col], 10); + var delta = (direction === 'down' ? endValue - startValue : startValue - endValue) / (rowsLength - 1) || 0; - _createClass(CommandExecutor, [{ - key: 'registerCommand', - value: function registerCommand(name, commandDescriptor) { - this.commands[name] = commandDescriptor; + arr.push(delta); } - /** - * Set common callback which will be trigger on every executed command. - * - * @param {Function} callback Function which will be fired on every command execute. - */ + deltas.push(arr); + } - }, { - key: 'setCommonCallback', - value: function setCommonCallback(callback) { - this.commonCallback = callback; + if (['right', 'left'].indexOf(direction) !== -1) { + for (var row = 0; row <= diffRow; row++) { + var _startValue = parseInt(data[row][0], 10); + var _endValue = parseInt(data[row][columnsLength - 1], 10); + var _delta = (direction === 'right' ? _endValue - _startValue : _startValue - _endValue) / (columnsLength - 1) || 0; + + deltas.push([_delta]); } + } - /** - * Execute command by its name. - * - * @param {String} commandName Command id. - * @param {*} params Arguments passed to command task. - */ + return deltas; +} - }, { - key: 'execute', - value: function execute(commandName) { - var _this = this; +/** + * Get direction between positions and cords of selections difference (drag area) + * + * @param {Array} startSelection + * @param {Array} endSelection + * @returns {{direction: String, start: CellCoords, end: CellCoords}} + */ +function getDragDirectionAndRange(startSelection, endSelection) { + var startOfDragCoords = void 0, + endOfDragCoords = void 0, + directionOfDrag = void 0; - for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - params[_key - 1] = arguments[_key]; - } + if (endSelection[0] === startSelection[0] && endSelection[1] < startSelection[1]) { + directionOfDrag = 'left'; - var commandSplit = commandName.split(':'); - commandName = commandSplit[0]; + startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]); + endOfDragCoords = new _src.CellCoords(endSelection[2], startSelection[1] - 1); + } else if (endSelection[0] === startSelection[0] && endSelection[3] > startSelection[3]) { + directionOfDrag = 'right'; - var subCommandName = commandSplit.length === 2 ? commandSplit[1] : null; - var command = this.commands[commandName]; + startOfDragCoords = new _src.CellCoords(endSelection[0], startSelection[3] + 1); + endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]); + } else if (endSelection[0] < startSelection[0] && endSelection[1] === startSelection[1]) { + directionOfDrag = 'up'; - if (!command) { - throw new Error('Menu command \'' + commandName + '\' not exists.'); - } - if (subCommandName && command.submenu) { - command = findSubCommand(subCommandName, command.submenu.items); - } - if (command.disabled === true) { - return; - } - if (typeof command.disabled == 'function' && command.disabled.call(this.hot) === true) { - return; - } - if ((0, _object.hasOwnProperty)(command, 'submenu')) { - return; - } - var callbacks = []; + startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]); + endOfDragCoords = new _src.CellCoords(startSelection[0] - 1, endSelection[3]); + } else if (endSelection[2] > startSelection[2] && endSelection[1] === startSelection[1]) { + directionOfDrag = 'down'; - if (typeof command.callback === 'function') { - callbacks.push(command.callback); - } - if (typeof this.commonCallback === 'function') { - callbacks.push(this.commonCallback); - } - params.unshift(commandSplit.join(':')); - (0, _array.arrayEach)(callbacks, function (callback) { - return callback.apply(_this.hot, params); - }); - } - }]); + startOfDragCoords = new _src.CellCoords(startSelection[2] + 1, endSelection[1]); + endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]); + } - return CommandExecutor; -}(); + return { + directionOfDrag: directionOfDrag, + startOfDragCoords: startOfDragCoords, + endOfDragCoords: endOfDragCoords + }; +} -function findSubCommand(subCommandName, subCommands) { - var command = void 0; +/** + * Get mapped FillHandle setting containing information about + * allowed FillHandle directions and if allowed is automatic insertion of rows on drag + * + * @param {Boolean|Object} fillHandle property of Handsontable settings + * @returns {{directions: Array, autoInsertRow: Boolean}} object allowing access to information + * about FillHandle in more useful way + */ +function getMappedFillHandleSetting(fillHandle) { + var mappedSettings = {}; - (0, _array.arrayEach)(subCommands, function (cmd) { - var cmds = cmd.key ? cmd.key.split(':') : null; + if (fillHandle === true) { + mappedSettings.directions = Object.keys(DIRECTIONS); + mappedSettings.autoInsertRow = true; + } else if ((0, _object.isObject)(fillHandle)) { + if ((0, _mixed.isDefined)(fillHandle.autoInsertRow)) { - if (Array.isArray(cmds) && cmds[1] === subCommandName) { - command = cmd; + // autoInsertRow for horizontal direction will be always false - return false; + if (fillHandle.direction === DIRECTIONS.horizontal) { + mappedSettings.autoInsertRow = false; + } else { + mappedSettings.autoInsertRow = fillHandle.autoInsertRow; + } + } else { + mappedSettings.autoInsertRow = false; } - }); - return command; -} + if ((0, _mixed.isDefined)(fillHandle.direction)) { + mappedSettings.directions = [fillHandle.direction]; + } else { + mappedSettings.directions = Object.keys(DIRECTIONS); + } + } else if (typeof fillHandle === 'string') { + mappedSettings.directions = [fillHandle]; + mappedSettings.autoInsertRow = true; + } else { + mappedSettings.directions = []; + mappedSettings.autoInsertRow = false; + } -exports.default = CommandExecutor; + return mappedSettings; +} /***/ }), -/* 221 */ +/* 251 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -52562,41 +52160,31 @@ var _get = function get(object, property, receiver) { if (object === null) objec var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _base = __webpack_require__(12); +var _base = __webpack_require__(13); var _base2 = _interopRequireDefault(_base); -var _pluginHooks = __webpack_require__(8); - -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - var _array = __webpack_require__(2); -var _commandExecutor = __webpack_require__(220); - -var _commandExecutor2 = _interopRequireDefault(_commandExecutor); - -var _eventManager = __webpack_require__(4); +var _feature = __webpack_require__(34); -var _eventManager2 = _interopRequireDefault(_eventManager); +var _element = __webpack_require__(0); -var _itemsFactory = __webpack_require__(223); +var _ghostTable = __webpack_require__(85); -var _itemsFactory2 = _interopRequireDefault(_itemsFactory); +var _ghostTable2 = _interopRequireDefault(_ghostTable); -var _menu = __webpack_require__(224); +var _object = __webpack_require__(1); -var _menu2 = _interopRequireDefault(_menu); +var _number = __webpack_require__(6); var _plugins = __webpack_require__(5); -var _event = __webpack_require__(7); - -var _element = __webpack_require__(0); +var _samplesGenerator = __webpack_require__(175); -var _predefinedItems = __webpack_require__(70); +var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator); -__webpack_require__(299); +var _string = __webpack_require__(32); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -52606,84 +52194,120 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -_pluginHooks2.default.getSingleton().register('afterContextMenuDefaultOptions'); -_pluginHooks2.default.getSingleton().register('afterContextMenuShow'); -_pluginHooks2.default.getSingleton().register('afterContextMenuHide'); -_pluginHooks2.default.getSingleton().register('afterContextMenuExecute'); - /** + * @plugin AutoRowSize + * * @description - * This plugin creates the Handsontable Context Menu. It allows to create a new row or - * column at any place in the grid among [other features](http://docs.handsontable.com/demo-context-menu.html). - * Possible values: - * * `true` (to enable default options), - * * `false` (to disable completely) + * This plugin allows to set row heights based on their highest cells. * - * or array of any available strings: - * * `["row_above", "row_below", "col_left", "col_right", - * "remove_row", "remove_col", "---------", "undo", "redo"]`. + * By default, the plugin is declared as `undefined`, which makes it disabled (same as if it was declared as `false`). + * Enabling this plugin may decrease the overall table performance, as it needs to calculate the heights of all cells to + * resize the rows accordingly. + * If you experience problems with the performance, try turning this feature off and declaring the row heights manually. * - * See [the context menu demo](http://docs.handsontable.com/demo-context-menu.html) for examples. + * Row height calculations are divided into sync and async part. Each of this parts has their own advantages and + * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't + * block the browser UI. * - * @example + * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object: * ```js * ... - * // as a boolean - * contextMenu: true + * // as a number (300 columns in sync, rest async) + * autoRowSize: {syncLimit: 300}, * ... - * // as a array - * contextMenu: ['row_above', 'row_below', '---------', 'undo', 'redo'] + * + * ... + * // as a string (percent) + * autoRowSize: {syncLimit: '40%'}, * ... * ``` * - * @plugin ContextMenu + * You can also use the `allowSampleDuplicates` option to allow sampling duplicate values when calculating the row height. Note, that this might have + * a negative impact on performance. + * + * To configure this plugin see {@link Options#autoRowSize}. + * + * @example + * + * ```js + * ... + * var hot = new Handsontable(document.getElementById('example'), { + * date: getData(), + * autoRowSize: true + * }); + * // Access to plugin instance: + * var plugin = hot.getPlugin('autoRowSize'); + * + * plugin.getRowHeight(4); + * + * if (plugin.isEnabled()) { + * // code... + * } + * ... + * ``` */ +var AutoRowSize = function (_BasePlugin) { + _inherits(AutoRowSize, _BasePlugin); -var ContextMenu = function (_BasePlugin) { - _inherits(ContextMenu, _BasePlugin); - - _createClass(ContextMenu, null, [{ - key: 'DEFAULT_ITEMS', - - /** - * Default menu items order when `contextMenu` is enabled by `true`. - * - * @returns {Array} - */ + _createClass(AutoRowSize, null, [{ + key: 'CALCULATION_STEP', get: function get() { - return [_predefinedItems.ROW_ABOVE, _predefinedItems.ROW_BELOW, _predefinedItems.SEPARATOR, _predefinedItems.COLUMN_LEFT, _predefinedItems.COLUMN_RIGHT, _predefinedItems.SEPARATOR, _predefinedItems.REMOVE_ROW, _predefinedItems.REMOVE_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.UNDO, _predefinedItems.REDO, _predefinedItems.SEPARATOR, _predefinedItems.READ_ONLY, _predefinedItems.SEPARATOR, _predefinedItems.ALIGNMENT]; + return 50; + } + }, { + key: 'SYNC_CALCULATION_LIMIT', + get: function get() { + return 500; } }]); - function ContextMenu(hotInstance) { - _classCallCheck(this, ContextMenu); + function AutoRowSize(hotInstance) { + _classCallCheck(this, AutoRowSize); /** - * Instance of {@link EventManager}. + * Cached rows heights. * - * @type {EventManager} + * @type {Array} */ - var _this = _possibleConstructorReturn(this, (ContextMenu.__proto__ || Object.getPrototypeOf(ContextMenu)).call(this, hotInstance)); + var _this = _possibleConstructorReturn(this, (AutoRowSize.__proto__ || Object.getPrototypeOf(AutoRowSize)).call(this, hotInstance)); - _this.eventManager = new _eventManager2.default(_this); + _this.heights = []; /** - * Instance of {@link CommandExecutor}. + * Instance of {@link GhostTable} for rows and columns size calculations. * - * @type {CommandExecutor} + * @type {GhostTable} */ - _this.commandExecutor = new _commandExecutor2.default(_this.hot); + _this.ghostTable = new _ghostTable2.default(_this.hot); /** - * Instance of {@link ItemsFactory}. + * Instance of {@link SamplesGenerator} for generating samples necessary for rows height calculations. * - * @type {ItemsFactory} + * @type {SamplesGenerator} */ - _this.itemsFactory = null; + _this.samplesGenerator = new _samplesGenerator2.default(function (row, col) { + if (row >= 0) { + return _this.hot.getDataAtCell(row, col); + } else if (row === -1) { + return _this.hot.getColHeader(col); + } + return null; + }); /** - * Instance of {@link Menu}. + * `true` if only the first calculation was performed. * - * @type {Menu} + * @type {Boolean} */ - _this.menu = null; + _this.firstCalculation = true; + /** + * `true` if the size calculation is in progress. + * + * @type {Boolean} + */ + _this.inProgress = false; + + // moved to constructor to allow auto-sizing the rows when the plugin is disabled + _this.addHook('beforeRowResize', function (row, size, isDblClick) { + return _this.onBeforeRowResize(row, size, isDblClick); + }); return _this; } @@ -52694,281 +52318,486 @@ var ContextMenu = function (_BasePlugin) { */ - _createClass(ContextMenu, [{ + _createClass(AutoRowSize, [{ key: 'isEnabled', value: function isEnabled() { - return this.hot.getSettings().contextMenu; + return this.hot.getSettings().autoRowSize === true || (0, _object.isObject)(this.hot.getSettings().autoRowSize); + } + + /** + * Enable plugin for this Handsontable instance. + */ + + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; + + if (this.enabled) { + return; + } + + this.setSamplingOptions(); + + this.addHook('afterLoadData', function () { + return _this2.onAfterLoadData(); + }); + this.addHook('beforeChange', function (changes) { + return _this2.onBeforeChange(changes); + }); + this.addHook('beforeColumnMove', function () { + return _this2.recalculateAllRowsHeight(); + }); + this.addHook('beforeColumnResize', function () { + return _this2.recalculateAllRowsHeight(); + }); + this.addHook('beforeColumnSort', function () { + return _this2.clearCache(); + }); + this.addHook('beforeRender', function (force) { + return _this2.onBeforeRender(force); + }); + this.addHook('beforeRowMove', function (rowStart, rowEnd) { + return _this2.onBeforeRowMove(rowStart, rowEnd); + }); + this.addHook('modifyRowHeight', function (height, row) { + return _this2.getRowHeight(row, height); + }); + this.addHook('modifyColumnHeaderHeight', function () { + return _this2.getColumnHeaderHeight(); + }); + _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'enablePlugin', this).call(this); + } + + /** + * Disable plugin for this Handsontable instance. + */ + + }, { + key: 'disablePlugin', + value: function disablePlugin() { + _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'disablePlugin', this).call(this); + } + + /** + * Calculate a given rows height. + * + * @param {Number|Object} rowRange Row range object. + * @param {Number|Object} colRange Column range object. + * @param {Boolean} [force=false] If `true` force calculate height even when value was cached earlier. + */ + + }, { + key: 'calculateRowsHeight', + value: function calculateRowsHeight() { + var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countRows() - 1 }; + + var _this3 = this; + + var colRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { from: 0, to: this.hot.countCols() - 1 }; + var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + if (typeof rowRange === 'number') { + rowRange = { from: rowRange, to: rowRange }; + } + if (typeof colRange === 'number') { + colRange = { from: colRange, to: colRange }; + } + + if (this.hot.getColHeader(0) !== null) { + var samples = this.samplesGenerator.generateRowSamples(-1, colRange); + + this.ghostTable.addColumnHeadersRow(samples.get(-1)); + } + + (0, _number.rangeEach)(rowRange.from, rowRange.to, function (row) { + // For rows we must calculate row height even when user had set height value manually. + // We can shrink column but cannot shrink rows! + if (force || _this3.heights[row] === void 0) { + var _samples = _this3.samplesGenerator.generateRowSamples(row, colRange); + + _samples.forEach(function (sample, row) { + _this3.ghostTable.addRow(row, sample); + }); + } + }); + if (this.ghostTable.rows.length) { + this.ghostTable.getHeights(function (row, height) { + _this3.heights[row] = height; + }); + this.ghostTable.clean(); + } + } + + /** + * Calculate the height of all the rows. + * + * @param {Object|Number} colRange Column range object. + */ + + }, { + key: 'calculateAllRowsHeight', + value: function calculateAllRowsHeight() { + var _this4 = this; + + var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countCols() - 1 }; + + var current = 0; + var length = this.hot.countRows() - 1; + var timer = null; + + this.inProgress = true; + + var loop = function loop() { + // When hot was destroyed after calculating finished cancel frame + if (!_this4.hot) { + (0, _feature.cancelAnimationFrame)(timer); + _this4.inProgress = false; + + return; + } + _this4.calculateRowsHeight({ from: current, to: Math.min(current + AutoRowSize.CALCULATION_STEP, length) }, colRange); + current = current + AutoRowSize.CALCULATION_STEP + 1; + + if (current < length) { + timer = (0, _feature.requestAnimationFrame)(loop); + } else { + (0, _feature.cancelAnimationFrame)(timer); + _this4.inProgress = false; + + // @TODO Should call once per render cycle, currently fired separately in different plugins + _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); + // tmp + if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) { + _this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw(); + } + } + }; + // sync + if (this.firstCalculation && this.getSyncCalculationLimit()) { + this.calculateRowsHeight({ from: 0, to: this.getSyncCalculationLimit() }, colRange); + this.firstCalculation = false; + current = this.getSyncCalculationLimit() + 1; + } + // async + if (current < length) { + loop(); + } else { + this.inProgress = false; + this.hot.view.wt.wtOverlays.adjustElementsSize(false); + } } /** - * Enable plugin for this Handsontable instance. + * Set the sampling options. + * + * @private */ }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + key: 'setSamplingOptions', + value: function setSamplingOptions() { + var setting = this.hot.getSettings().autoRowSize; + var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoRowSize.samplingRatio : void 0; + var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoRowSize.allowSampleDuplicates : void 0; - if (this.enabled) { - return; + if (samplingRatio && !isNaN(samplingRatio)) { + this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10)); } - this.itemsFactory = new _itemsFactory2.default(this.hot, ContextMenu.DEFAULT_ITEMS); - var settings = this.hot.getSettings().contextMenu; - var predefinedItems = { - items: this.itemsFactory.getItems(settings) - }; - this.registerEvents(); - - if (typeof settings.callback === 'function') { - this.commandExecutor.setCommonCallback(settings.callback); + if (allowSampleDuplicates) { + this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates); } - _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'enablePlugin', this).call(this); + } - this.callOnPluginsReady(function () { - _this2.hot.runHooks('afterContextMenuDefaultOptions', predefinedItems); + /** + * Recalculate all rows height (overwrite cache values). + */ - _this2.itemsFactory.setPredefinedItems(predefinedItems.items); - var menuItems = _this2.itemsFactory.getItems(settings); + }, { + key: 'recalculateAllRowsHeight', + value: function recalculateAllRowsHeight() { + if ((0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) { + this.clearCache(); + this.calculateAllRowsHeight(); + } + } - _this2.menu = new _menu2.default(_this2.hot, { - className: 'htContextMenu', - keepInViewport: true - }); - _this2.hot.runHooks('beforeContextMenuSetItems', menuItems); + /** + * Get value which tells how much rows will be calculated synchronously. Rest rows will be calculated asynchronously. + * + * @returns {Number} + */ - _this2.menu.setMenuItems(menuItems); + }, { + key: 'getSyncCalculationLimit', + value: function getSyncCalculationLimit() { + /* eslint-disable no-bitwise */ + var limit = AutoRowSize.SYNC_CALCULATION_LIMIT; + var rowsLimit = this.hot.countRows() - 1; - _this2.menu.addLocalHook('afterOpen', function () { - return _this2.onMenuAfterOpen(); - }); - _this2.menu.addLocalHook('afterClose', function () { - return _this2.onMenuAfterClose(); - }); - _this2.menu.addLocalHook('executeCommand', function () { - for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) { - params[_key] = arguments[_key]; - } + if ((0, _object.isObject)(this.hot.getSettings().autoRowSize)) { + limit = this.hot.getSettings().autoRowSize.syncLimit; - return _this2.executeCommand.apply(_this2, params); - }); + if ((0, _string.isPercentValue)(limit)) { + limit = (0, _number.valueAccordingPercent)(rowsLimit, limit); + } else { + // Force to Number + limit >>= 0; + } + } - // Register all commands. Predefined and added by user or by plugins - (0, _array.arrayEach)(menuItems, function (command) { - return _this2.commandExecutor.registerCommand(command.key, command); - }); - }); + return Math.min(limit, rowsLimit); } /** - * Updates the plugin to use the latest options you have specified. + * Get the calculated row height. + * + * @param {Number} row Visual row index. + * @param {Number} [defaultHeight] Default row height. It will be pick up if no calculated height found. + * @returns {Number} */ }, { - key: 'updatePlugin', - value: function updatePlugin() { - this.disablePlugin(); - this.enablePlugin(); + key: 'getRowHeight', + value: function getRowHeight(row) { + var defaultHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0; - _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'updatePlugin', this).call(this); + var height = defaultHeight; + + if (this.heights[row] !== void 0 && this.heights[row] > (defaultHeight || 0)) { + height = this.heights[row]; + } + + return height; } /** - * Disable plugin for this Handsontable instance. + * Get the calculated column header height. + * + * @returns {Number|undefined} */ }, { - key: 'disablePlugin', - value: function disablePlugin() { - this.close(); - - if (this.menu) { - this.menu.destroy(); - this.menu = null; - } - _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'disablePlugin', this).call(this); + key: 'getColumnHeaderHeight', + value: function getColumnHeaderHeight() { + return this.heights[-1]; } /** - * Register dom listeners. + * Get the first visible row. * - * @private + * @returns {Number} Returns row index or -1 if table is not rendered. */ }, { - key: 'registerEvents', - value: function registerEvents() { - var _this3 = this; + key: 'getFirstVisibleRow', + value: function getFirstVisibleRow() { + var wot = this.hot.view.wt; - this.eventManager.addEventListener(this.hot.rootElement, 'contextmenu', function (event) { - return _this3.onContextMenu(event); - }); + if (wot.wtViewport.rowsVisibleCalculator) { + return wot.wtTable.getFirstVisibleRow(); + } + if (wot.wtViewport.rowsRenderCalculator) { + return wot.wtTable.getFirstRenderedRow(); + } + + return -1; } /** - * Open menu and re-position it based on dom event object. + * Get the last visible row. * - * @param {Event} event The event object. + * @returns {Number} Returns row index or -1 if table is not rendered. */ }, { - key: 'open', - value: function open(event) { - if (!this.menu) { - return; + key: 'getLastVisibleRow', + value: function getLastVisibleRow() { + var wot = this.hot.view.wt; + + if (wot.wtViewport.rowsVisibleCalculator) { + return wot.wtTable.getLastVisibleRow(); + } + if (wot.wtViewport.rowsRenderCalculator) { + return wot.wtTable.getLastRenderedRow(); } - this.menu.open(); - this.menu.setPosition({ - top: parseInt((0, _event.pageY)(event), 10) - (0, _element.getWindowScrollTop)(), - left: parseInt((0, _event.pageX)(event), 10) - (0, _element.getWindowScrollLeft)() - }); - // ContextMenu is not detected HotTableEnv correctly because is injected outside hot-table - this.menu.hotMenu.isHotTableEnv = this.hot.isHotTableEnv; - // Handsontable.eventManager.isHotTableEnv = this.hot.isHotTableEnv; + return -1; } /** - * Close menu. + * Clear cached heights. */ }, { - key: 'close', - value: function close() { - if (!this.menu) { - return; - } - this.menu.close(); + key: 'clearCache', + value: function clearCache() { + this.heights.length = 0; + this.heights[-1] = void 0; } /** - * Execute context menu command. - * - * You can execute all predefined commands: - * * `'row_above'` - Insert row above - * * `'row_below'` - Insert row below - * * `'col_left'` - Insert column on the left - * * `'col_right'` - Insert column on the right - * * `'clear_column'` - Clear selected column - * * `'remove_row'` - Remove row - * * `'remove_col'` - Remove column - * * `'undo'` - Undo last action - * * `'redo'` - Redo last action - * * `'make_read_only'` - Make cell read only - * * `'alignment:left'` - Alignment to the left - * * `'alignment:top'` - Alignment to the top - * * `'alignment:right'` - Alignment to the right - * * `'alignment:bottom'` - Alignment to the bottom - * * `'alignment:middle'` - Alignment to the middle - * * `'alignment:center'` - Alignment to the center (justify) - * - * Or you can execute command registered in settings where `key` is your command name. + * Clear cache by range. * - * @param {String} commandName - * @param {*} params + * @param {Object|Number} range Row range object. */ }, { - key: 'executeCommand', - value: function executeCommand() { - for (var _len2 = arguments.length, params = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - params[_key2] = arguments[_key2]; + key: 'clearCacheByRange', + value: function clearCacheByRange(range) { + var _this5 = this; + + if (typeof range === 'number') { + range = { from: range, to: range }; } + (0, _number.rangeEach)(Math.min(range.from, range.to), Math.max(range.from, range.to), function (row) { + _this5.heights[row] = void 0; + }); + } - this.commandExecutor.execute.apply(this.commandExecutor, params); + /** + * @returns {Boolean} + */ + + }, { + key: 'isNeedRecalculate', + value: function isNeedRecalculate() { + return !!(0, _array.arrayFilter)(this.heights, function (item) { + return item === void 0; + }).length; } /** - * On context menu listener. + * On before render listener. * * @private - * @param {Event} event */ }, { - key: 'onContextMenu', - value: function onContextMenu(event) { - var settings = this.hot.getSettings(); - var showRowHeaders = settings.rowHeaders; - var showColHeaders = settings.colHeaders; + key: 'onBeforeRender', + value: function onBeforeRender() { + var force = this.hot.renderCall; + this.calculateRowsHeight({ from: this.getFirstVisibleRow(), to: this.getLastVisibleRow() }, void 0, force); - function isValidElement(element) { - return element.nodeName === 'TD' || element.parentNode.nodeName === 'TD'; + var fixedRowsBottom = this.hot.getSettings().fixedRowsBottom; + + // Calculate rows height synchronously for bottom overlay + if (fixedRowsBottom) { + var totalRows = this.hot.countRows() - 1; + this.calculateRowsHeight({ from: totalRows - fixedRowsBottom, to: totalRows }); } - // if event is from hot-table we must get web component element not element inside him - var element = event.realTarget; - this.close(); - if ((0, _element.hasClass)(element, 'handsontableInput')) { - return; + if (this.isNeedRecalculate() && !this.inProgress) { + this.calculateAllRowsHeight(); } + } - event.preventDefault(); - (0, _event.stopPropagation)(event); + /** + * On before row move listener. + * + * @private + * @param {Number} from Row index where was grabbed. + * @param {Number} to Destination row index. + */ - if (!(showRowHeaders || showColHeaders)) { - if (!isValidElement(element) && !((0, _element.hasClass)(element, 'current') && (0, _element.hasClass)(element, 'wtBorder'))) { - return; - } + }, { + key: 'onBeforeRowMove', + value: function onBeforeRowMove(from, to) { + this.clearCacheByRange({ from: from, to: to }); + this.calculateAllRowsHeight(); + } + + /** + * On before row resize listener. + * + * @private + * @param {Number} row + * @param {Number} size + * @param {Boolean} isDblClick + * @returns {Number} + */ + + }, { + key: 'onBeforeRowResize', + value: function onBeforeRowResize(row, size, isDblClick) { + if (isDblClick) { + this.calculateRowsHeight(row, void 0, true); + size = this.getRowHeight(row); } - this.open(event); + return size; } /** - * On menu after open listener. + * On after load data listener. * * @private */ }, { - key: 'onMenuAfterOpen', - value: function onMenuAfterOpen() { - this.hot.runHooks('afterContextMenuShow', this); + key: 'onAfterLoadData', + value: function onAfterLoadData() { + var _this6 = this; + + if (this.hot.view) { + this.recalculateAllRowsHeight(); + } else { + // first load - initialization + setTimeout(function () { + if (_this6.hot) { + _this6.recalculateAllRowsHeight(); + } + }, 0); + } } /** - * On menu after close listener. + * On before change listener. * * @private + * @param {Array} changes */ }, { - key: 'onMenuAfterClose', - value: function onMenuAfterClose() { - this.hot.listen(); - this.hot.runHooks('afterContextMenuHide', this); + key: 'onBeforeChange', + value: function onBeforeChange(changes) { + var range = null; + + if (changes.length === 1) { + range = changes[0][0]; + } else if (changes.length > 1) { + range = { + from: changes[0][0], + to: changes[changes.length - 1][0] + }; + } + if (range !== null) { + this.clearCacheByRange(range); + } } /** - * Destroy instance. + * Destroy plugin instance. */ }, { key: 'destroy', value: function destroy() { - this.close(); - - if (this.menu) { - this.menu.destroy(); - } - _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'destroy', this).call(this); + this.ghostTable.clean(); + _get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'destroy', this).call(this); } }]); - return ContextMenu; + return AutoRowSize; }(_base2.default); -ContextMenu.SEPARATOR = { - name: _predefinedItems.SEPARATOR -}; - -(0, _plugins.registerPlugin)('contextMenu', ContextMenu); +(0, _plugins.registerPlugin)('autoRowSize', AutoRowSize); -exports.default = ContextMenu; +exports.default = AutoRowSize; /***/ }), -/* 222 */ +/* 252 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -52976,2545 +52805,2610 @@ exports.default = ContextMenu; exports.__esModule = true; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _moment = __webpack_require__(63); + +var _moment2 = _interopRequireDefault(_moment); + var _element = __webpack_require__(0); -var _event = __webpack_require__(7); +var _array = __webpack_require__(2); + +var _mixed = __webpack_require__(22); + +var _object = __webpack_require__(1); + +var _base = __webpack_require__(13); + +var _base2 = _interopRequireDefault(_base); + +var _plugins = __webpack_require__(5); + +var _mergeSort = __webpack_require__(253); + +var _mergeSort2 = _interopRequireDefault(_mergeSort); + +var _pluginHooks = __webpack_require__(7); + +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +_pluginHooks2.default.getSingleton().register('beforeColumnSort'); +_pluginHooks2.default.getSingleton().register('afterColumnSort'); + +// TODO: Implement mixin arrayMapper to ColumnSorting plugin. + /** - * Helper class for checking if element will fit at the desired side of cursor. + * @plugin ColumnSorting * - * @class Cursor - * @plugin ContextMenu + * @description + * This plugin sorts the view by a column (but does not sort the data source!). + * To enable the plugin, set the `columnSorting` property to either: + * * a boolean value (`true`/`false`), + * * an object defining the initial sorting order (see the example below). + * + * @example + * ```js + * ... + * // as boolean + * columnSorting: true + * ... + * // as a object with initial order (sort ascending column at index 2) + * columnSorting: { + * column: 2, + * sortOrder: true, // true = ascending, false = descending, undefined = original order + * sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table + * } + * ... + * ``` + * @dependencies ObserveChanges */ -var Cursor = function () { - function Cursor(object) { - _classCallCheck(this, Cursor); - var windowScrollTop = (0, _element.getWindowScrollTop)(); - var windowScrollLeft = (0, _element.getWindowScrollLeft)(); - var top = void 0, - topRelative = void 0; - var left = void 0, - leftRelative = void 0; - var cellHeight = void 0, - cellWidth = void 0; +var ColumnSorting = function (_BasePlugin) { + _inherits(ColumnSorting, _BasePlugin); - this.type = this.getSourceType(object); + function ColumnSorting(hotInstance) { + _classCallCheck(this, ColumnSorting); - if (this.type === 'literal') { - top = parseInt(object.top, 10); - left = parseInt(object.left, 10); - cellHeight = object.height || 0; - cellWidth = object.width || 0; - topRelative = top; - leftRelative = left; - top += windowScrollTop; - left += windowScrollLeft; - } else if (this.type === 'event') { - top = parseInt((0, _event.pageY)(object), 10); - left = parseInt((0, _event.pageX)(object), 10); - cellHeight = object.target.clientHeight; - cellWidth = object.target.clientWidth; - topRelative = top - windowScrollTop; - leftRelative = left - windowScrollLeft; - } + var _this2 = _possibleConstructorReturn(this, (ColumnSorting.__proto__ || Object.getPrototypeOf(ColumnSorting)).call(this, hotInstance)); - this.top = top; - this.topRelative = topRelative; - this.left = left; - this.leftRelative = leftRelative; - this.scrollTop = windowScrollTop; - this.scrollLeft = windowScrollLeft; - this.cellHeight = cellHeight; - this.cellWidth = cellWidth; + _this2.sortIndicators = []; + _this2.lastSortedColumn = null; + _this2.sortEmptyCells = false; + return _this2; } /** - * Get source type name. + * Check if the plugin is enabled in the handsontable settings. * - * @param {*} object Event or Object with coordinates. - * @returns {String} Returns one of this values: `'literal'`, `'event'`. + * @returns {Boolean} */ - _createClass(Cursor, [{ - key: 'getSourceType', - value: function getSourceType(object) { - var type = 'literal'; + _createClass(ColumnSorting, [{ + key: 'isEnabled', + value: function isEnabled() { + return !!this.hot.getSettings().columnSorting; + } + + /** + * Enable plugin for this Handsontable instance. + */ + + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this3 = this; + + if (this.enabled) { + return; + } + + this.setPluginOptions(); + + var _this = this; + this.hot.sortIndex = []; + + this.hot.sort = function () { + var args = Array.prototype.slice.call(arguments); + + return _this.sortByColumn.apply(_this, _toConsumableArray(args)); + }; - if (object instanceof Event) { - type = 'event'; + if (typeof this.hot.getSettings().observeChanges === 'undefined') { + this.enableObserveChangesPlugin(); } - return type; + this.addHook('afterTrimRow', function (row) { + return _this3.sort(); + }); + this.addHook('afterUntrimRow', function (row) { + return _this3.sort(); + }); + this.addHook('modifyRow', function (row) { + return _this3.translateRow(row); + }); + this.addHook('unmodifyRow', function (row) { + return _this3.untranslateRow(row); + }); + this.addHook('afterUpdateSettings', function () { + return _this3.onAfterUpdateSettings(); + }); + this.addHook('afterGetColHeader', function (col, TH) { + return _this3.getColHeader(col, TH); + }); + this.addHook('afterOnCellMouseDown', function (event, target) { + return _this3.onAfterOnCellMouseDown(event, target); + }); + this.addHook('afterCreateRow', function () { + _this.afterCreateRow.apply(_this, arguments); + }); + this.addHook('afterRemoveRow', function () { + _this.afterRemoveRow.apply(_this, arguments); + }); + this.addHook('afterInit', function () { + return _this3.sortBySettings(); + }); + this.addHook('afterLoadData', function () { + _this3.hot.sortIndex = []; + + if (_this3.hot.view) { + _this3.sortBySettings(); + } + }); + if (this.hot.view) { + this.sortBySettings(); + } + _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'enablePlugin', this).call(this); } /** - * Checks if element can be placed above the cursor. - * - * @param {HTMLElement} element Element to check if it's size will fit above the cursor. - * @returns {Boolean} + * Disable plugin for this Handsontable instance. */ }, { - key: 'fitsAbove', - value: function fitsAbove(element) { - return this.topRelative >= element.offsetHeight; + key: 'disablePlugin', + value: function disablePlugin() { + this.hot.sort = void 0; + _get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'disablePlugin', this).call(this); } /** - * Checks if element can be placed below the cursor. + * afterUpdateSettings callback. * - * @param {HTMLElement} element Element to check if it's size will fit below the cursor. - * @param {Number} [viewportHeight] The viewport height. - * @returns {Boolean} + * @private */ }, { - key: 'fitsBelow', - value: function fitsBelow(element) { - var viewportHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window.innerHeight; - - return this.topRelative + element.offsetHeight <= viewportHeight; + key: 'onAfterUpdateSettings', + value: function onAfterUpdateSettings() { + this.sortBySettings(); } - - /** - * Checks if element can be placed on the right of the cursor. - * - * @param {HTMLElement} element Element to check if it's size will fit on the right of the cursor. - * @param {Number} [viewportWidth] The viewport width. - * @returns {Boolean} - */ - }, { - key: 'fitsOnRight', - value: function fitsOnRight(element) { - var viewportWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window.innerWidth; + key: 'sortBySettings', + value: function sortBySettings() { + var sortingSettings = this.hot.getSettings().columnSorting; + var loadedSortingState = this.loadSortingState(); + var sortingColumn = void 0; + var sortingOrder = void 0; - return this.leftRelative + this.cellWidth + element.offsetWidth <= viewportWidth; + if (typeof loadedSortingState === 'undefined') { + sortingColumn = sortingSettings.column; + sortingOrder = sortingSettings.sortOrder; + } else { + sortingColumn = loadedSortingState.sortColumn; + sortingOrder = loadedSortingState.sortOrder; + } + if (typeof sortingColumn === 'number') { + this.lastSortedColumn = sortingColumn; + this.sortByColumn(sortingColumn, sortingOrder); + } } /** - * Checks if element can be placed on the left on the cursor. + * Set sorted column and order info * - * @param {HTMLElement} element Element to check if it's size will fit on the left of the cursor. - * @returns {Boolean} + * @param {number} col Sorted visual column index. + * @param {boolean|undefined} order Sorting order (`true` for ascending, `false` for descending). */ }, { - key: 'fitsOnLeft', - value: function fitsOnLeft(element) { - return this.leftRelative >= element.offsetWidth; - } - }]); - - return Cursor; -}(); - -exports.default = Cursor; - -/***/ }), -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { + key: 'setSortingColumn', + value: function setSortingColumn(col, order) { + if (typeof col == 'undefined') { + this.hot.sortColumn = void 0; + this.hot.sortOrder = void 0; -"use strict"; + return; + } else if (this.hot.sortColumn === col && typeof order == 'undefined') { + if (this.hot.sortOrder === false) { + this.hot.sortOrder = void 0; + } else { + this.hot.sortOrder = !this.hot.sortOrder; + } + } else { + this.hot.sortOrder = typeof order === 'undefined' ? true : order; + } + this.hot.sortColumn = col; + } + }, { + key: 'sortByColumn', + value: function sortByColumn(col, order) { + this.setSortingColumn(col, order); -exports.__esModule = true; + if (typeof this.hot.sortColumn == 'undefined') { + return; + } -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + var allowSorting = this.hot.runHooks('beforeColumnSort', this.hot.sortColumn, this.hot.sortOrder); -var _object = __webpack_require__(1); + if (allowSorting !== false) { + this.sort(); + } + this.updateOrderClass(); + this.updateSortIndicator(); -var _array = __webpack_require__(2); + this.hot.runHooks('afterColumnSort', this.hot.sortColumn, this.hot.sortOrder); -var _predefinedItems = __webpack_require__(70); + this.hot.render(); + this.saveSortingState(); + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** + * Save the sorting state + */ -/** - * Predefined items class factory for menu items. - * - * @class ItemsFactory - * @plugin ContextMenu - */ -var ItemsFactory = function () { - function ItemsFactory(hotInstance) { - var orderPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + }, { + key: 'saveSortingState', + value: function saveSortingState() { + var sortingState = {}; - _classCallCheck(this, ItemsFactory); + if (typeof this.hot.sortColumn != 'undefined') { + sortingState.sortColumn = this.hot.sortColumn; + } - this.hot = hotInstance; - this.predefinedItems = (0, _predefinedItems.predefinedItems)(); - this.defaultOrderPattern = orderPattern; - } + if (typeof this.hot.sortOrder != 'undefined') { + sortingState.sortOrder = this.hot.sortOrder; + } - /** - * Set predefined items. - * - * @param {Array} predefinedItems Array of predefined items. - */ + if ((0, _object.hasOwnProperty)(sortingState, 'sortColumn') || (0, _object.hasOwnProperty)(sortingState, 'sortOrder')) { + this.hot.runHooks('persistentStateSave', 'columnSorting', sortingState); + } + } + /** + * Load the sorting state. + * + * @returns {*} Previously saved sorting state. + */ - _createClass(ItemsFactory, [{ - key: 'setPredefinedItems', - value: function setPredefinedItems(predefinedItems) { - var _this = this; + }, { + key: 'loadSortingState', + value: function loadSortingState() { + var storedState = {}; + this.hot.runHooks('persistentStateLoad', 'columnSorting', storedState); - var items = {}; + return storedState.value; + } - this.defaultOrderPattern.length = 0; + /** + * Update sorting class name state. + */ - (0, _object.objectEach)(predefinedItems, function (value, key) { - var menuItemKey = ''; + }, { + key: 'updateOrderClass', + value: function updateOrderClass() { + var orderClass = void 0; - if (value.name === _predefinedItems.SEPARATOR) { - items[_predefinedItems.SEPARATOR] = value; - menuItemKey = _predefinedItems.SEPARATOR; + if (this.hot.sortOrder === true) { + orderClass = 'ascending'; + } else if (this.hot.sortOrder === false) { + orderClass = 'descending'; + } + this.sortOrderClass = orderClass; + } + }, { + key: 'enableObserveChangesPlugin', + value: function enableObserveChangesPlugin() { + var _this = this; - // Menu item added as a property to array - } else if (isNaN(parseInt(key, 10))) { - value.key = value.key === void 0 ? key : value.key; - items[key] = value; - menuItemKey = value.key; - } else { - items[value.key] = value; - menuItemKey = value.key; - } - _this.defaultOrderPattern.push(menuItemKey); - }); - this.predefinedItems = items; + this.hot._registerTimeout(setTimeout(function () { + _this.hot.updateSettings({ + observeChanges: true + }); + }, 0)); } /** - * Get all menu items based on pattern. + * Default sorting algorithm. * - * @param {Array|Object|Boolean} pattern Pattern which you can define by displaying menu items order. If `true` default - * pattern will be used. - * @returns {Array} + * @param {Boolean} sortOrder Sorting order - `true` for ascending, `false` for descending. + * @param {Object} columnMeta Column meta object. + * @returns {Function} The comparing function. */ }, { - key: 'getItems', - value: function getItems() { - var pattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - - return _getItems(pattern, this.defaultOrderPattern, this.predefinedItems); - } - }]); + key: 'defaultSort', + value: function defaultSort(sortOrder, columnMeta) { + return function (a, b) { + if (typeof a[1] == 'string') { + a[1] = a[1].toLowerCase(); + } + if (typeof b[1] == 'string') { + b[1] = b[1].toLowerCase(); + } - return ItemsFactory; -}(); + if (a[1] === b[1]) { + return 0; + } -function _getItems() { - var pattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - var defaultPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - var items = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if ((0, _mixed.isEmpty)(a[1])) { + if ((0, _mixed.isEmpty)(b[1])) { + return 0; + } - var result = []; + if (columnMeta.columnSorting.sortEmptyCells) { + return sortOrder ? -1 : 1; + } - if (pattern && pattern.items) { - pattern = pattern.items; - } else if (!Array.isArray(pattern)) { - pattern = defaultPattern; - } - if ((0, _object.isObject)(pattern)) { - (0, _object.objectEach)(pattern, function (value, key) { - var item = items[typeof value === 'string' ? value : key]; + return 1; + } + if ((0, _mixed.isEmpty)(b[1])) { + if ((0, _mixed.isEmpty)(a[1])) { + return 0; + } - if (!item) { - item = value; - } - if ((0, _object.isObject)(value)) { - (0, _object.extend)(item, value); - } else if (typeof item === 'string') { - item = { name: item }; - } - if (item.key === void 0) { - item.key = key; - } - result.push(item); - }); - } else { - (0, _array.arrayEach)(pattern, function (name, key) { - var item = items[name]; + if (columnMeta.columnSorting.sortEmptyCells) { + return sortOrder ? 1 : -1; + } - // Item deleted from settings `allowInsertRow: false` etc. - if (!item && _predefinedItems.ITEMS.indexOf(name) >= 0) { - return; - } - if (!item) { - item = { name: name, key: '' + key }; - } - if ((0, _object.isObject)(name)) { - (0, _object.extend)(item, name); - } - if (item.key === void 0) { - item.key = key; - } - result.push(item); - }); - } + return -1; + } - return result; -} + if (isNaN(a[1]) && !isNaN(b[1])) { + return sortOrder ? 1 : -1; + } else if (!isNaN(a[1]) && isNaN(b[1])) { + return sortOrder ? -1 : 1; + } else if (!(isNaN(a[1]) || isNaN(b[1]))) { + a[1] = parseFloat(a[1]); + b[1] = parseFloat(b[1]); + } + if (a[1] < b[1]) { + return sortOrder ? -1 : 1; + } + if (a[1] > b[1]) { + return sortOrder ? 1 : -1; + } -exports.default = ItemsFactory; + return 0; + }; + } -/***/ }), -/* 224 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Date sorting algorithm + * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending). + * @param {Object} columnMeta Column meta object. + * @returns {Function} The compare function. + */ -"use strict"; + }, { + key: 'dateSort', + value: function dateSort(sortOrder, columnMeta) { + return function (a, b) { + if (a[1] === b[1]) { + return 0; + } + if ((0, _mixed.isEmpty)(a[1])) { + if ((0, _mixed.isEmpty)(b[1])) { + return 0; + } -exports.__esModule = true; + if (columnMeta.columnSorting.sortEmptyCells) { + return sortOrder ? -1 : 1; + } -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + return 1; + } -var _core = __webpack_require__(63); + if ((0, _mixed.isEmpty)(b[1])) { + if ((0, _mixed.isEmpty)(a[1])) { + return 0; + } -var _core2 = _interopRequireDefault(_core); + if (columnMeta.columnSorting.sortEmptyCells) { + return sortOrder ? 1 : -1; + } -var _element = __webpack_require__(0); + return -1; + } -var _array = __webpack_require__(2); + var aDate = (0, _moment2.default)(a[1], columnMeta.dateFormat); + var bDate = (0, _moment2.default)(b[1], columnMeta.dateFormat); -var _cursor = __webpack_require__(222); + if (!aDate.isValid()) { + return 1; + } + if (!bDate.isValid()) { + return -1; + } -var _cursor2 = _interopRequireDefault(_cursor); + if (bDate.isAfter(aDate)) { + return sortOrder ? -1 : 1; + } + if (bDate.isBefore(aDate)) { + return sortOrder ? 1 : -1; + } -var _eventManager = __webpack_require__(4); + return 0; + }; + } -var _eventManager2 = _interopRequireDefault(_eventManager); + /** + * Numeric sorting algorithm. + * + * @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending). + * @param {Object} columnMeta Column meta object. + * @returns {Function} The compare function. + */ -var _object = __webpack_require__(1); + }, { + key: 'numericSort', + value: function numericSort(sortOrder, columnMeta) { + return function (a, b) { + var parsedA = parseFloat(a[1]); + var parsedB = parseFloat(b[1]); -var _function = __webpack_require__(35); + // Watch out when changing this part of code! + // Check below returns 0 (as expected) when comparing empty string, null, undefined + if (parsedA === parsedB || isNaN(parsedA) && isNaN(parsedB)) { + return 0; + } -var _utils = __webpack_require__(17); + if (columnMeta.columnSorting.sortEmptyCells) { + if ((0, _mixed.isEmpty)(a[1])) { + return sortOrder ? -1 : 1; + } -var _unicode = __webpack_require__(16); + if ((0, _mixed.isEmpty)(b[1])) { + return sortOrder ? 1 : -1; + } + } -var _localHooks = __webpack_require__(69); + if (isNaN(parsedA)) { + return 1; + } -var _localHooks2 = _interopRequireDefault(_localHooks); + if (isNaN(parsedB)) { + return -1; + } -var _predefinedItems = __webpack_require__(70); + if (parsedA < parsedB) { + return sortOrder ? -1 : 1; + } else if (parsedA > parsedB) { + return sortOrder ? 1 : -1; + } -var _event = __webpack_require__(7); + return 0; + }; + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** + * Perform the sorting. + */ -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + }, { + key: 'sort', + value: function sort() { + if (typeof this.hot.sortOrder == 'undefined') { + this.hot.sortIndex.length = 0; -/** - * @class Menu - * @plugin ContextMenu - */ -var Menu = function () { - function Menu(hotInstance, options) { - _classCallCheck(this, Menu); + return; + } - this.hot = hotInstance; - this.options = options || { - parent: null, - name: null, - className: '', - keepInViewport: true, - standalone: false - }; - this.eventManager = new _eventManager2.default(this); - this.container = this.createContainer(this.options.name); - this.hotMenu = null; - this.hotSubMenus = {}; - this.parentMenu = this.options.parent || null; - this.menuItems = null; - this.origOutsideClickDeselects = null; - this.keyEvent = false; + var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn); + var emptyRows = this.hot.countEmptyRows(); + var sortFunction = void 0; + var nrOfRows = void 0; - this.offset = { - above: 0, - below: 0, - left: 0, - right: 0 - }; - this._afterScrollCallback = null; + this.hot.sortingEnabled = false; // this is required by translateRow plugin hook + this.hot.sortIndex.length = 0; - this.registerEvents(); - } + if (typeof colMeta.columnSorting.sortEmptyCells === 'undefined') { + colMeta.columnSorting = { sortEmptyCells: this.sortEmptyCells }; + } - /** - * Register event listeners. - * - * @private - */ + if (this.hot.getSettings().maxRows === Number.POSITIVE_INFINITY) { + nrOfRows = this.hot.countRows() - this.hot.getSettings().minSpareRows; + } else { + nrOfRows = this.hot.countRows() - emptyRows; + } + for (var i = 0, ilen = nrOfRows; i < ilen; i++) { + this.hot.sortIndex.push([i, this.hot.getDataAtCell(i, this.hot.sortColumn)]); + } - _createClass(Menu, [{ - key: 'registerEvents', - value: function registerEvents() { - var _this = this; + if (colMeta.sortFunction) { + sortFunction = colMeta.sortFunction; + } else { + switch (colMeta.type) { + case 'date': + sortFunction = this.dateSort; + break; + case 'numeric': + sortFunction = this.numericSort; + break; + default: + sortFunction = this.defaultSort; + } + } - this.eventManager.addEventListener(document.documentElement, 'mousedown', function (event) { - return _this.onDocumentMouseDown(event); - }); + (0, _mergeSort2.default)(this.hot.sortIndex, sortFunction(this.hot.sortOrder, colMeta)); + + // Append spareRows + for (var _i = this.hot.sortIndex.length; _i < this.hot.countRows(); _i++) { + this.hot.sortIndex.push([_i, this.hot.getDataAtCell(_i, this.hot.sortColumn)]); + } + + this.hot.sortingEnabled = true; // this is required by translateRow plugin hook } /** - * Set array of objects which defines menu items. - * - * @param {Array} menuItems Menu items to display. + * Update indicator states. */ }, { - key: 'setMenuItems', - value: function setMenuItems(menuItems) { - this.menuItems = menuItems; + key: 'updateSortIndicator', + value: function updateSortIndicator() { + if (typeof this.hot.sortOrder == 'undefined') { + return; + } + var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn); + + this.sortIndicators[this.hot.sortColumn] = colMeta.sortIndicator; } /** - * Set offset menu position for specified area (`above`, `below`, `left` or `right`). + * `modifyRow` hook callback. Translates physical row index to the sorted row index. * - * @param {String} area Specified area name (`above`, `below`, `left` or `right`). - * @param {Number} offset Offset value. + * @param {Number} row Row index. + * @returns {Number} Sorted row index. */ }, { - key: 'setOffset', - value: function setOffset(area) { - var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + key: 'translateRow', + value: function translateRow(row) { + if (this.hot.sortingEnabled && typeof this.hot.sortOrder !== 'undefined' && this.hot.sortIndex && this.hot.sortIndex.length && this.hot.sortIndex[row]) { + return this.hot.sortIndex[row][0]; + } - this.offset[area] = offset; + return row; } /** - * Check if menu is using as sub-menu. + * Translates sorted row index to physical row index. * - * @returns {Boolean} + * @param {Number} row Sorted (visual) row index. + * @returns {number} Physical row index. */ }, { - key: 'isSubMenu', - value: function isSubMenu() { - return this.parentMenu !== null; + key: 'untranslateRow', + value: function untranslateRow(row) { + if (this.hot.sortingEnabled && this.hot.sortIndex && this.hot.sortIndex.length) { + for (var i = 0; i < this.hot.sortIndex.length; i++) { + if (this.hot.sortIndex[i][0] == row) { + return i; + } + } + } } /** - * Open menu. + * `afterGetColHeader` callback. Adds column sorting css classes to clickable headers. + * + * @private + * @param {Number} col Visual column index. + * @param {Element} TH TH HTML element. */ }, { - key: 'open', - value: function open() { - var _this2 = this; - - this.container.removeAttribute('style'); - this.container.style.display = 'block'; + key: 'getColHeader', + value: function getColHeader(col, TH) { + if (col < 0 || !TH.parentNode) { + return false; + } - var delayedOpenSubMenu = (0, _function.debounce)(function (row) { - return _this2.openSubMenu(row); - }, 300); + var headerLink = TH.querySelector('.colHeader'); + var colspan = TH.getAttribute('colspan'); + var TRs = TH.parentNode.parentNode.childNodes; + var headerLevel = Array.prototype.indexOf.call(TRs, TH.parentNode); + headerLevel -= TRs.length; - var filteredItems = (0, _array.arrayFilter)(this.menuItems, function (item) { - return (0, _utils.isItemHidden)(item, _this2.hot); - }); + if (!headerLink) { + return; + } - filteredItems = (0, _utils.filterSeparators)(filteredItems, _predefinedItems.SEPARATOR); + if (this.hot.getSettings().columnSorting && col >= 0 && headerLevel === -1) { + (0, _element.addClass)(headerLink, 'columnSorting'); + } + (0, _element.removeClass)(headerLink, 'descending'); + (0, _element.removeClass)(headerLink, 'ascending'); - var settings = { - data: filteredItems, - colHeaders: false, - colWidths: [200], - autoRowSize: false, - readOnly: true, - copyPaste: false, - columns: [{ - data: 'name', - renderer: function renderer(hot, TD, row, col, prop, value) { - return _this2.menuItemRenderer(hot, TD, row, col, prop, value); - } - }], - renderAllRows: true, - fragmentSelection: 'cell', - disableVisualSelection: 'area', - beforeKeyDown: function beforeKeyDown(event) { - return _this2.onBeforeKeyDown(event); - }, - afterOnCellMouseOver: function afterOnCellMouseOver(event, coords, TD) { - if (_this2.isAllSubMenusClosed()) { - delayedOpenSubMenu(coords.row); - } else { - _this2.openSubMenu(coords.row); + if (this.sortIndicators[col]) { + if (col === this.hot.sortColumn) { + if (this.sortOrderClass === 'ascending') { + (0, _element.addClass)(headerLink, 'ascending'); + } else if (this.sortOrderClass === 'descending') { + (0, _element.addClass)(headerLink, 'descending'); } - }, - rowHeights: function rowHeights(row) { - return filteredItems[row].name === _predefinedItems.SEPARATOR ? 1 : 23; } - }; - this.origOutsideClickDeselects = this.hot.getSettings().outsideClickDeselects; - this.hot.getSettings().outsideClickDeselects = false; - this.hotMenu = new _core2.default(this.container, settings); - this.hotMenu.addHook('afterInit', function () { - return _this2.onAfterInit(); - }); - this.hotMenu.addHook('afterSelection', function (r, c, r2, c2, preventScrolling) { - return _this2.onAfterSelection(r, c, r2, c2, preventScrolling); - }); - this.hotMenu.init(); - this.hotMenu.listen(); - this.blockMainTableCallbacks(); - this.runLocalHooks('afterOpen'); + } } /** - * Close menu. + * Check if any column is in a sorted state. * - * @param {Boolean} [closeParent=false] if `true` try to close parent menu if exists. + * @returns {Boolean} */ }, { - key: 'close', - value: function close() { - var closeParent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - - if (!this.isOpened()) { - return; - } - if (closeParent && this.parentMenu) { - this.parentMenu.close(); - } else { - this.closeAllSubMenus(); - this.container.style.display = 'none'; - this.releaseMainTableCallbacks(); - this.hotMenu.destroy(); - this.hotMenu = null; - this.hot.getSettings().outsideClickDeselects = this.origOutsideClickDeselects; - this.runLocalHooks('afterClose'); - - if (this.parentMenu) { - this.parentMenu.hotMenu.listen(); - } - } + key: 'isSorted', + value: function isSorted() { + return typeof this.hot.sortColumn != 'undefined'; } /** - * Open sub menu at the provided row index. + * `afterCreateRow` callback. Updates the sorting state after a row have been created. * - * @param {Number} row Row index. - * @returns {Menu|Boolean} Returns created menu or `false` if no one menu was created. + * @private + * @param {Number} index Visual row index. + * @param {Number} amount */ }, { - key: 'openSubMenu', - value: function openSubMenu(row) { - if (!this.hotMenu) { - return false; + key: 'afterCreateRow', + value: function afterCreateRow(index, amount) { + if (!this.isSorted()) { + return; } - var cell = this.hotMenu.getCell(row, 0); - this.closeAllSubMenus(); + for (var i = 0; i < this.hot.sortIndex.length; i++) { + if (this.hot.sortIndex[i][0] >= index) { + this.hot.sortIndex[i][0] += amount; + } + } - if (!cell || !(0, _utils.hasSubMenu)(cell)) { - return false; + for (var _i2 = 0; _i2 < amount; _i2++) { + this.hot.sortIndex.splice(index + _i2, 0, [index + _i2, this.hot.getSourceData()[index + _i2][this.hot.sortColumn + this.hot.colOffset()]]); } - var dataItem = this.hotMenu.getSourceDataAtRow(row); - var subMenu = new Menu(this.hot, { - parent: this, - name: dataItem.name, - className: this.options.className, - keepInViewport: true - }); - subMenu.setMenuItems(dataItem.submenu.items); - subMenu.open(); - subMenu.setPosition(cell.getBoundingClientRect()); - this.hotSubMenus[dataItem.key] = subMenu; - return subMenu; + this.saveSortingState(); } /** - * Close sub menu at row index. + * `afterRemoveRow` hook callback. * - * @param {Number} row Row index. + * @private + * @param {Number} index Visual row index. + * @param {Number} amount */ }, { - key: 'closeSubMenu', - value: function closeSubMenu(row) { - var dataItem = this.hotMenu.getSourceDataAtRow(row); - var menus = this.hotSubMenus[dataItem.key]; - - if (menus) { - menus.destroy(); - delete this.hotSubMenus[dataItem.key]; + key: 'afterRemoveRow', + value: function afterRemoveRow(index, amount) { + if (!this.isSorted()) { + return; } - } + var removedRows = this.hot.sortIndex.splice(index, amount); - /** - * Close all opened sub menus. - */ + removedRows = (0, _array.arrayMap)(removedRows, function (row) { + return row[0]; + }); - }, { - key: 'closeAllSubMenus', - value: function closeAllSubMenus() { - var _this3 = this; + function countRowShift(logicalRow) { + // Todo: compare perf between reduce vs sort->each->brake + return (0, _array.arrayReduce)(removedRows, function (count, removedLogicalRow) { + if (logicalRow > removedLogicalRow) { + count++; + } - (0, _array.arrayEach)(this.hotMenu.getData(), function (value, row) { - return _this3.closeSubMenu(row); - }); - } + return count; + }, 0); + } - /** - * Checks if all created and opened sub menus are closed. - * - * @returns {Boolean} - */ + this.hot.sortIndex = (0, _array.arrayMap)(this.hot.sortIndex, function (logicalRow, physicalRow) { + var rowShift = countRowShift(logicalRow[0]); - }, { - key: 'isAllSubMenusClosed', - value: function isAllSubMenusClosed() { - return Object.keys(this.hotSubMenus).length === 0; - } + if (rowShift) { + logicalRow[0] -= rowShift; + } - /** - * Destroy instance. - */ + return logicalRow; + }); - }, { - key: 'destroy', - value: function destroy() { - this.clearLocalHooks(); - this.close(); - this.parentMenu = null; - this.eventManager.destroy(); + this.saveSortingState(); } /** - * Checks if menu was opened. + * Set options by passed settings * - * @returns {Boolean} Returns `true` if menu was opened. + * @private */ }, { - key: 'isOpened', - value: function isOpened() { - return this.hotMenu !== null; + key: 'setPluginOptions', + value: function setPluginOptions() { + var columnSorting = this.hot.getSettings().columnSorting; + + if ((typeof columnSorting === 'undefined' ? 'undefined' : _typeof(columnSorting)) === 'object') { + this.sortEmptyCells = columnSorting.sortEmptyCells || false; + } else { + this.sortEmptyCells = false; + } } /** - * Execute menu command. + * `onAfterOnCellMouseDown` hook callback. * - * @param {Event} [event] + * @private + * @param {Event} event Event which are provided by hook. + * @param {CellCoords} coords Visual coords of the selected cell. */ }, { - key: 'executeCommand', - value: function executeCommand(event) { - if (!this.isOpened() || !this.hotMenu.getSelected()) { + key: 'onAfterOnCellMouseDown', + value: function onAfterOnCellMouseDown(event, coords) { + if (coords.row > -1) { return; } - var selectedItem = this.hotMenu.getSourceDataAtRow(this.hotMenu.getSelected()[0]); - this.runLocalHooks('select', selectedItem, event); + if ((0, _element.hasClass)(event.realTarget, 'columnSorting')) { + // reset order state on every new column header click + if (coords.col !== this.lastSortedColumn) { + this.hot.sortOrder = true; + } - if (selectedItem.isCommand === false || selectedItem.name === _predefinedItems.SEPARATOR) { - return; - } - var selRange = this.hot.getSelectedRange(); - var normalizedSelection = selRange ? (0, _utils.normalizeSelection)(selRange) : {}; - var autoClose = true; + this.lastSortedColumn = coords.col; - // Don't close context menu if item is disabled or it has submenu - if (selectedItem.disabled === true || typeof selectedItem.disabled === 'function' && selectedItem.disabled.call(this.hot) === true || selectedItem.submenu) { - autoClose = false; + this.sortByColumn(coords.col); } + } + }]); - this.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event); + return ColumnSorting; +}(_base2.default); - if (this.isSubMenu()) { - this.parentMenu.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event); - } +(0, _plugins.registerPlugin)('columnSorting', ColumnSorting); - if (autoClose) { - this.close(true); - } +exports.default = ColumnSorting; + +/***/ }), +/* 253 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; +exports.default = mergeSort; +exports.merge = merge; + +var _linkedList = __webpack_require__(254); + +var _linkedList2 = _interopRequireDefault(_linkedList); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Refactored implementation of mergeSort (part of javascript-algorithms project) by Github users: + * mgechev, AndriiHeonia and lekkas (part of javascript-algorithms project - all project contributors + * at repository website) + * + * Link to repository: https://github.com/mgechev/javascript-algorithms + */ + +/** + * Specifies a function that defines the sort order. The array is sorted according to each + * character's Unicode code point value, according to the string conversion of each element. + * + * @param a {*} first compared element. + * @param b {*} second compared element. + * @returns {Number} + */ +var defaultCompareFunction = function defaultCompareFunction(a, b) { + // sort lexically + + var firstValue = a.toString(); + var secondValue = b.toString(); + + if (firstValue === secondValue) { + return 0; + } else if (firstValue < secondValue) { + return -1; + } + return 1; +}; + +/** + * Mergesort method which is recursively called for sorting the input array. + * + * @param {Array} array The array which should be sorted. + * @param {Function} compareFunction Compares two items in an array. If compareFunction is not supplied, + * elements are sorted by converting them to strings and comparing strings in Unicode code point order. + * @param {Number} startIndex Left side of the subarray. + * @param {Number} endIndex Right side of the subarray. + * @returns {Array} Array with sorted subarray. + */ +function mergeSort(array) { + var compareFunction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultCompareFunction; + var startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length; + + if (Math.abs(endIndex - startIndex) <= 1) { + return []; + } + + var middleIndex = Math.ceil((startIndex + endIndex) / 2); + + mergeSort(array, compareFunction, startIndex, middleIndex); + mergeSort(array, compareFunction, middleIndex, endIndex); + + return merge(array, compareFunction, startIndex, middleIndex, endIndex); +} + +/** + * Devides and sort merges two subarrays of given array + * + * @param {Array} array The array which subarrays should be sorted. + * @param {Number} startIndex The start of the first subarray. + * This subarray is with end middle - 1. + * @param {Number} middleIndex The start of the second array. + * @param {Number} endIndex end - 1 is the end of the second array. + * @returns {Array} The array with sorted subarray. + */ +function merge(array, compareFunction, startIndex, middleIndex, endIndex) { + var leftElements = new _linkedList2.default(); + var rightElements = new _linkedList2.default(); + var leftSize = middleIndex - startIndex; + var rightSize = endIndex - middleIndex; + var maxSize = Math.max(leftSize, rightSize); + var size = endIndex - startIndex; + + for (var _i = 0; _i < maxSize; _i += 1) { + if (_i < leftSize) { + leftElements.push(array[startIndex + _i]); } - /** - * Set menu position based on dom event or based on literal object. - * - * @param {Event|Object} coords Event or literal Object with coordinates. - */ + if (_i < rightSize) { + rightElements.push(array[middleIndex + _i]); + } + } - }, { - key: 'setPosition', - value: function setPosition(coords) { - var cursor = new _cursor2.default(coords); + var i = 0; - if (this.options.keepInViewport) { - if (cursor.fitsBelow(this.container)) { - this.setPositionBelowCursor(cursor); - } else if (cursor.fitsAbove(this.container)) { - this.setPositionAboveCursor(cursor); - } else { - this.setPositionBelowCursor(cursor); - } - if (cursor.fitsOnRight(this.container)) { - this.setPositionOnRightOfCursor(cursor); - } else { - this.setPositionOnLeftOfCursor(cursor); - } + while (i < size) { + if (leftElements.first && rightElements.first) { + if (compareFunction(leftElements.first.data, rightElements.first.data) > 0) { + array[startIndex + i] = rightElements.shift().data; } else { - this.setPositionBelowCursor(cursor); - this.setPositionOnRightOfCursor(cursor); + array[startIndex + i] = leftElements.shift().data; } + } else if (leftElements.first) { + + array[startIndex + i] = leftElements.shift().data; + } else { + + array[startIndex + i] = rightElements.shift().data; } - /** - * Set menu position above cursor object. - * - * @param {Cursor} cursor `Cursor` object. - */ + i += 1; + } - }, { - key: 'setPositionAboveCursor', - value: function setPositionAboveCursor(cursor) { - var top = this.offset.above + cursor.top - this.container.offsetHeight; + return array; +}; - if (this.isSubMenu()) { - top = cursor.top + cursor.cellHeight - this.container.offsetHeight + 3; - } - this.container.style.top = top + 'px'; - } +/***/ }), +/* 254 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Set menu position below cursor object. - * - * @param {Cursor} cursor `Cursor` object. - */ +"use strict"; - }, { - key: 'setPositionBelowCursor', - value: function setPositionBelowCursor(cursor) { - var top = this.offset.below + cursor.top; - if (this.isSubMenu()) { - top = cursor.top - 1; - } - this.container.style.top = top + 'px'; - } +exports.__esModule = true; - /** - * Set menu position on the right of cursor object. - * - * @param {Cursor} cursor `Cursor` object. - */ +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - }, { - key: 'setPositionOnRightOfCursor', - value: function setPositionOnRightOfCursor(cursor) { - var left = void 0; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - if (this.isSubMenu()) { - left = 1 + cursor.left + cursor.cellWidth; - } else { - left = this.offset.right + 1 + cursor.left; - } +/** + * Refactored implementation of LinkedList (part of javascript-algorithms project) by Github users: + * mgechev, AndriiHeonia, Microfed and Jakeh (part of javascript-algorithms project - all project contributors + * at repository website) + * + * Link to repository: https://github.com/mgechev/javascript-algorithms + */ - this.container.style.left = left + 'px'; - } +/** + * Linked list node. + * + * @class NodeStructure + * @util + */ +var NodeStructure = function NodeStructure(data) { + _classCallCheck(this, NodeStructure); - /** - * Set menu position on the left of cursor object. - * - * @param {Cursor} cursor `Cursor` object. - */ + /** + * Data of the node. + * @member {Object} + */ + this.data = data; + /** + * Next node. + * @member {NodeStructure} + */ + this.next = null; + /** + * Previous node. + * @member {NodeStructure} + */ + this.prev = null; +}; - }, { - key: 'setPositionOnLeftOfCursor', - value: function setPositionOnLeftOfCursor(cursor) { - var left = this.offset.left + cursor.left - this.container.offsetWidth + (0, _element.getScrollbarWidth)() + 4; +/** + * Linked list. + * + * @class LinkedList + * @util + */ - this.container.style.left = left + 'px'; - } - /** - * Select first cell in opened menu. - */ +var LinkedList = function () { + function LinkedList() { + _classCallCheck(this, LinkedList); - }, { - key: 'selectFirstCell', - value: function selectFirstCell() { - var cell = this.hotMenu.getCell(0, 0); + this.first = null; + this.last = null; + } - if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { - this.selectNextCell(0, 0); - } else { - this.hotMenu.selectCell(0, 0); - } - } + /** + * Add data to the end of linked list. + * + * @param {Object} data Data which should be added. + */ - /** - * Select last cell in opened menu. - */ - }, { - key: 'selectLastCell', - value: function selectLastCell() { - var lastRow = this.hotMenu.countRows() - 1; - var cell = this.hotMenu.getCell(lastRow, 0); + _createClass(LinkedList, [{ + key: "push", + value: function push(data) { + var node = new NodeStructure(data); - if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { - this.selectPrevCell(lastRow, 0); + if (this.first === null) { + this.first = node; + this.last = node; } else { - this.hotMenu.selectCell(lastRow, 0); + var temp = this.last; + + this.last = node; + node.prev = temp; + temp.next = node; } } /** - * Select next cell in opened menu. + * Add data to the beginning of linked list. * - * @param {Number} row Row index. - * @param {Number} col Column index. + * @param {Object} data Data which should be added. */ }, { - key: 'selectNextCell', - value: function selectNextCell(row, col) { - var nextRow = row + 1; - var cell = nextRow < this.hotMenu.countRows() ? this.hotMenu.getCell(nextRow, col) : null; + key: "unshift", + value: function unshift(data) { + var node = new NodeStructure(data); - if (!cell) { - return; - } - if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { - this.selectNextCell(nextRow, col); + if (this.first === null) { + this.first = node; + this.last = node; } else { - this.hotMenu.selectCell(nextRow, col); + var temp = this.first; + + this.first = node; + node.next = temp; + temp.prev = node; } } /** - * Select previous cell in opened menu. + * In order traversal of the linked list. * - * @param {Number} row Row index. - * @param {Number} col Column index. + * @param {Function} callback Callback which should be executed on each node. */ }, { - key: 'selectPrevCell', - value: function selectPrevCell(row, col) { - var prevRow = row - 1; - var cell = prevRow >= 0 ? this.hotMenu.getCell(prevRow, col) : null; + key: "inorder", + value: function inorder(callback) { + var temp = this.first; - if (!cell) { - return; - } - if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { - this.selectPrevCell(prevRow, col); - } else { - this.hotMenu.selectCell(prevRow, col); + while (temp) { + callback(temp); + temp = temp.next; } } /** - * Menu item renderer. + * Remove data from the linked list. * - * @private + * @param {Object} data Data which should be removed. + * @returns {Boolean} Returns true if data has been removed. */ }, { - key: 'menuItemRenderer', - value: function menuItemRenderer(hot, TD, row, col, prop, value) { - var _this4 = this; + key: "remove", + value: function remove(data) { + if (this.first === null) { + return false; + } - var item = hot.getSourceDataAtRow(row); - var wrapper = document.createElement('div'); + var temp = this.first; + var next = void 0; + var prev = void 0; - var isSubMenu = function isSubMenu(item) { - return (0, _object.hasOwnProperty)(item, 'submenu'); - }; - var itemIsSeparator = function itemIsSeparator(item) { - return new RegExp(_predefinedItems.SEPARATOR, 'i').test(item.name); - }; - var itemIsDisabled = function itemIsDisabled(item) { - return item.disabled === true || typeof item.disabled == 'function' && item.disabled.call(_this4.hot) === true; - }; - var itemIsSelectionDisabled = function itemIsSelectionDisabled(item) { - return item.disableSelection; - }; + while (temp) { + if (temp.data === data) { + next = temp.next; + prev = temp.prev; - if (typeof value === 'function') { - value = value.call(this.hot); - } - (0, _element.empty)(TD); - (0, _element.addClass)(wrapper, 'htItemWrapper'); - TD.appendChild(wrapper); + if (next) { + next.prev = prev; + } - if (itemIsSeparator(item)) { - (0, _element.addClass)(TD, 'htSeparator'); - } else if (typeof item.renderer === 'function') { - (0, _element.addClass)(TD, 'htCustomMenuRenderer'); - TD.appendChild(item.renderer(hot, wrapper, row, col, prop, value)); - } else { - (0, _element.fastInnerHTML)(wrapper, value); - } - if (itemIsDisabled(item)) { - (0, _element.addClass)(TD, 'htDisabled'); - this.eventManager.addEventListener(TD, 'mouseenter', function () { - return hot.deselectCell(); - }); - } else if (itemIsSelectionDisabled(item)) { - (0, _element.addClass)(TD, 'htSelectionDisabled'); - this.eventManager.addEventListener(TD, 'mouseenter', function () { - return hot.deselectCell(); - }); - } else if (isSubMenu(item)) { - (0, _element.addClass)(TD, 'htSubmenu'); + if (prev) { + prev.next = next; + } - if (itemIsSelectionDisabled(item)) { - this.eventManager.addEventListener(TD, 'mouseenter', function () { - return hot.deselectCell(); - }); - } else { - this.eventManager.addEventListener(TD, 'mouseenter', function () { - return hot.selectCell(row, col, void 0, void 0, false, false); - }); - } - } else { - (0, _element.removeClass)(TD, 'htSubmenu'); - (0, _element.removeClass)(TD, 'htDisabled'); + if (temp === this.first) { + this.first = next; + } - if (itemIsSelectionDisabled(item)) { - this.eventManager.addEventListener(TD, 'mouseenter', function () { - return hot.deselectCell(); - }); - } else { - this.eventManager.addEventListener(TD, 'mouseenter', function () { - return hot.selectCell(row, col, void 0, void 0, false, false); - }); + if (temp === this.last) { + this.last = prev; + } + + return true; } + + temp = temp.next; } + + return false; } /** - * Create container/wrapper for handsontable. + * Check if linked list contains cycle. * - * @private - * @param {String} [name] Class name. - * @returns {HTMLElement} + * @returns {Boolean} Returns true if linked list contains cycle. */ }, { - key: 'createContainer', - value: function createContainer() { - var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - - if (name) { - name = name.replace(/[^A-z0-9]/g, '_'); - name = this.options.className + 'Sub_' + name; - } - var container = void 0; - - if (name) { - container = document.querySelector('.' + this.options.className + '.' + name); - } else { - container = document.querySelector('.' + this.options.className); - } - if (!container) { - container = document.createElement('div'); - (0, _element.addClass)(container, 'htMenu ' + this.options.className); + key: "hasCycle", + value: function hasCycle() { + var fast = this.first; + var slow = this.first; - if (name) { - (0, _element.addClass)(container, name); + while (true) { + if (fast === null) { + return false; } - document.getElementsByTagName('body')[0].appendChild(container); - } - - return container; - } - /** - * @private - */ + fast = fast.next; - }, { - key: 'blockMainTableCallbacks', - value: function blockMainTableCallbacks() { - this._afterScrollCallback = function () {}; - this.hot.addHook('afterScrollVertically', this._afterScrollCallback); - this.hot.addHook('afterScrollHorizontally', this._afterScrollCallback); - } + if (fast === null) { + return false; + } - /** - * @private - */ + fast = fast.next; + slow = slow.next; - }, { - key: 'releaseMainTableCallbacks', - value: function releaseMainTableCallbacks() { - if (this._afterScrollCallback) { - this.hot.removeHook('afterScrollVertically', this._afterScrollCallback); - this.hot.removeHook('afterScrollHorizontally', this._afterScrollCallback); - this._afterScrollCallback = null; + if (fast === slow) { + return true; + } } } + }, { + key: "pop", + /** - * On before key down listener. + * Return last node from the linked list. * - * @private - * @param {Event} event + * @returns {NodeStructure} Last node. */ - - }, { - key: 'onBeforeKeyDown', - value: function onBeforeKeyDown(event) { - var selection = this.hotMenu.getSelected(); - var stopEvent = false; - this.keyEvent = true; - - switch (event.keyCode) { - case _unicode.KEY_CODES.ESCAPE: - this.close(); - stopEvent = true; - break; - - case _unicode.KEY_CODES.ENTER: - if (selection) { - if (this.hotMenu.getSourceDataAtRow(selection[0]).submenu) { - stopEvent = true; - } else { - this.executeCommand(event); - this.close(true); - } - } - break; - - case _unicode.KEY_CODES.ARROW_DOWN: - if (selection) { - this.selectNextCell(selection[0], selection[1]); - } else { - this.selectFirstCell(); - } - stopEvent = true; - break; - - case _unicode.KEY_CODES.ARROW_UP: - if (selection) { - this.selectPrevCell(selection[0], selection[1]); - } else { - this.selectLastCell(); - } - stopEvent = true; - break; - - case _unicode.KEY_CODES.ARROW_RIGHT: - if (selection) { - var menu = this.openSubMenu(selection[0]); - - if (menu) { - menu.selectFirstCell(); - } - } - stopEvent = true; - - break; - - case _unicode.KEY_CODES.ARROW_LEFT: - if (selection && this.isSubMenu()) { - this.close(); - - if (this.parentMenu) { - this.parentMenu.hotMenu.listen(); - } - stopEvent = true; - } - break; - default: - break; - } - if (stopEvent) { - event.preventDefault(); - (0, _event.stopImmediatePropagation)(event); + value: function pop() { + if (this.last === null) { + return null; } - this.keyEvent = false; + var temp = this.last; + this.last = this.last.prev; + + return temp; } + }, { + key: "shift", + /** - * On after init listener. + * Return first node from the linked list. * - * @private + * @returns {NodeStructure} First node. */ + value: function shift() { + if (this.first === null) { + return null; + } - }, { - key: 'onAfterInit', - value: function onAfterInit() { - var data = this.hotMenu.getSettings().data; - var hiderStyle = this.hotMenu.view.wt.wtTable.hider.style; - var holderStyle = this.hotMenu.view.wt.wtTable.holder.style; - var currentHiderWidth = parseInt(hiderStyle.width, 10); - - var realHeight = (0, _array.arrayReduce)(data, function (accumulator, value) { - return accumulator + (value.name === _predefinedItems.SEPARATOR ? 1 : 26); - }, 0); + var temp = this.first; + this.first = this.first.next; - holderStyle.width = currentHiderWidth + 22 + 'px'; - holderStyle.height = realHeight + 4 + 'px'; - hiderStyle.height = holderStyle.height; + return temp; } + }, { + key: "recursiveReverse", + /** - * On after selection listener. - * - * @param {Number} r Selection start row index. - * @param {Number} c Selection start column index. - * @param {Number} r2 Selection end row index. - * @param {Number} c2 Selection end column index. - * @param {Object} preventScrolling Object with `value` property where its value change will be observed. + * Reverses the linked list recursively */ + value: function recursiveReverse() { + function inverse(current, next) { + if (!next) { + return; + } + inverse(next, next.next); + next.next = current; + } - }, { - key: 'onAfterSelection', - value: function onAfterSelection(r, c, r2, c2, preventScrolling) { - if (this.keyEvent === false) { - preventScrolling.value = true; + if (!this.first) { + return; } + + inverse(this.first, this.first.next); + + this.first.next = null; + var temp = this.first; + this.first = this.last; + this.last = temp; } + }, { + key: "reverse", + /** - * Document mouse down listener. - * - * @private - * @param {Event} event + * Reverses the linked list iteratively */ - - }, { - key: 'onDocumentMouseDown', - value: function onDocumentMouseDown(event) { - if (!this.isOpened()) { + value: function reverse() { + if (!this.first || !this.first.next) { return; } - if (this.container && (0, _element.isChildOf)(event.target, this.container)) { - this.executeCommand(event); - } - // Close menu when clicked element is not belongs to menu itself - if (this.options.standalone && this.hotMenu && !(0, _element.isChildOf)(event.target, this.hotMenu.rootElement)) { - this.close(true); - // Automatically close menu when clicked element is not belongs to menu or submenu (not necessarily to itself) - } else if ((this.isAllSubMenusClosed() || this.isSubMenu()) && !(0, _element.isChildOf)(event.target, '.htMenu') && (0, _element.isChildOf)(event.target, document)) { - this.close(true); + var current = this.first.next; + var prev = this.first; + var temp = void 0; + + while (current) { + temp = current.next; + current.next = prev; + prev.prev = current; + prev = current; + current = temp; } + + this.first.next = null; + this.last.prev = null; + temp = this.first; + this.first = prev; + this.last = temp; } }]); - return Menu; + return LinkedList; }(); -(0, _object.mixin)(Menu, _localHooks2.default); +; -exports.default = Menu; +exports.NodeStructure = NodeStructure; +exports.default = LinkedList; /***/ }), -/* 225 */ +/* 255 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; -exports.KEY = undefined; -exports.default = alignmentItem; - -var _utils = __webpack_require__(17); - -var _separator = __webpack_require__(71); - -var KEY = exports.KEY = 'alignment'; -function alignmentItem() { - return { - key: KEY, - name: 'Alignment', - disabled: function disabled() { - return !(this.getSelectedRange() && !this.selection.selectedHeader.corner); - }, - - submenu: { - items: [{ - key: KEY + ':left', - name: function name() { - var _this = this; - - var label = 'Left'; - var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var className = _this.getCellMeta(row, col).className; - - if (className && className.indexOf('htLeft') !== -1) { - return true; - } - }); - - if (hasClass) { - label = (0, _utils.markLabelAsSelected)(label); - } - - return label; - }, - callback: function callback() { - var _this2 = this; - - var range = this.getSelectedRange(); - var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { - return _this2.getCellMeta(row, col).className; - }); - var type = 'horizontal'; - var alignment = 'htLeft'; - - this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); - (0, _utils.align)(range, type, alignment, function (row, col) { - return _this2.getCellMeta(row, col); - }, function (row, col, key, value) { - return _this2.setCellMeta(row, col, key, value); - }); - this.render(); - }, - - disabled: false - }, { - key: KEY + ':center', - name: function name() { - var _this3 = this; - - var label = 'Center'; - var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var className = _this3.getCellMeta(row, col).className; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (className && className.indexOf('htCenter') !== -1) { - return true; - } - }); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - if (hasClass) { - label = (0, _utils.markLabelAsSelected)(label); - } +var _element = __webpack_require__(0); - return label; - }, - callback: function callback() { - var _this4 = this; +var _object = __webpack_require__(1); - var range = this.getSelectedRange(); - var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { - return _this4.getCellMeta(row, col).className; - }); - var type = 'horizontal'; - var alignment = 'htCenter'; +var _eventManager = __webpack_require__(4); - this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); - (0, _utils.align)(range, type, alignment, function (row, col) { - return _this4.getCellMeta(row, col); - }, function (row, col, key, value) { - return _this4.setCellMeta(row, col, key, value); - }); - this.render(); - }, +var _eventManager2 = _interopRequireDefault(_eventManager); - disabled: false - }, { - key: KEY + ':right', - name: function name() { - var _this5 = this; +var _src = __webpack_require__(12); - var label = 'Right'; - var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var className = _this5.getCellMeta(row, col).className; +var _plugins = __webpack_require__(5); - if (className && className.indexOf('htRight') !== -1) { - return true; - } - }); +var _base = __webpack_require__(13); - if (hasClass) { - label = (0, _utils.markLabelAsSelected)(label); - } +var _base2 = _interopRequireDefault(_base); - return label; - }, - callback: function callback() { - var _this6 = this; +var _commentEditor = __webpack_require__(256); - var range = this.getSelectedRange(); - var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { - return _this6.getCellMeta(row, col).className; - }); - var type = 'horizontal'; - var alignment = 'htRight'; +var _commentEditor2 = _interopRequireDefault(_commentEditor); - this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); - (0, _utils.align)(range, type, alignment, function (row, col) { - return _this6.getCellMeta(row, col); - }, function (row, col, key, value) { - return _this6.setCellMeta(row, col, key, value); - }); - this.render(); - }, +var _utils = __webpack_require__(19); - disabled: false - }, { - key: KEY + ':justify', - name: function name() { - var _this7 = this; +var _displaySwitch = __webpack_require__(257); - var label = 'Justify'; - var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var className = _this7.getCellMeta(row, col).className; +var _displaySwitch2 = _interopRequireDefault(_displaySwitch); - if (className && className.indexOf('htJustify') !== -1) { - return true; - } - }); +__webpack_require__(258); - if (hasClass) { - label = (0, _utils.markLabelAsSelected)(label); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return label; - }, - callback: function callback() { - var _this8 = this; +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - var range = this.getSelectedRange(); - var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { - return _this8.getCellMeta(row, col).className; - }); - var type = 'horizontal'; - var alignment = 'htJustify'; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); - (0, _utils.align)(range, type, alignment, function (row, col) { - return _this8.getCellMeta(row, col); - }, function (row, col, key, value) { - return _this8.setCellMeta(row, col, key, value); - }); - this.render(); - }, +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - disabled: false - }, { - name: _separator.KEY - }, { - key: KEY + ':top', - name: function name() { - var _this9 = this; +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var label = 'Top'; - var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var className = _this9.getCellMeta(row, col).className; +var privatePool = new WeakMap(); +var META_COMMENT = 'comment'; +var META_COMMENT_VALUE = 'value'; +var META_STYLE = 'style'; +var META_READONLY = 'readOnly'; - if (className && className.indexOf('htTop') !== -1) { - return true; - } - }); +/** + * @plugin Comments + * + * @description + * This plugin allows setting and managing cell comments by either an option in the context menu or with the use of the API. + * + * To enable the plugin, you'll need to set the comments property of the config object to `true`: + * ```js + * ... + * comments: true + * ... + * ``` + * + * or object with extra predefined plugin config: + * + * ```js + * ... + * comments: { + * displayDelay: 1000 + * } + * ... + * ``` + * + * To add comments at the table initialization, define the `comment` property in the `cell` config array as in an example below. + * + * @example + * + * ```js + * ... + * var hot = new Handsontable(document.getElementById('example'), { + * date: getData(), + * comments: true, + * cell: [ + * {row: 1, col: 1, comment: {value: 'Foo'}}, + * {row: 2, col: 2, comment: {value: 'Bar'}} + * ] + * }); + * + * // Access to the Comments plugin instance: + * var commentsPlugin = hot.getPlugin('comments'); + * + * // Manage comments programmatically: + * commentsPlugin.setCommentAtCell(1, 6, 'Comment contents'); + * commentsPlugin.showAtCell(1, 6); + * commentsPlugin.removeCommentAtCell(1, 6); + * + * // You can also set range once and use proper methods: + * commentsPlugin.setRange({row: 1, col: 6}); + * commentsPlugin.setComment('Comment contents'); + * commentsPlugin.show(); + * commentsPlugin.removeComment(); + * ... + * ``` + */ - if (hasClass) { - label = (0, _utils.markLabelAsSelected)(label); - } - return label; - }, - callback: function callback() { - var _this10 = this; +var Comments = function (_BasePlugin) { + _inherits(Comments, _BasePlugin); - var range = this.getSelectedRange(); - var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { - return _this10.getCellMeta(row, col).className; - }); - var type = 'vertical'; - var alignment = 'htTop'; + function Comments(hotInstance) { + _classCallCheck(this, Comments); - this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); - (0, _utils.align)(range, type, alignment, function (row, col) { - return _this10.getCellMeta(row, col); - }, function (row, col, key, value) { - return _this10.setCellMeta(row, col, key, value); - }); - this.render(); - }, + /** + * Instance of {@link CommentEditor}. + * + * @type {CommentEditor} + */ + var _this = _possibleConstructorReturn(this, (Comments.__proto__ || Object.getPrototypeOf(Comments)).call(this, hotInstance)); - disabled: false - }, { - key: KEY + ':middle', - name: function name() { - var _this11 = this; + _this.editor = null; + /** + * Instance of {@link DisplaySwitch}. + * + * @type {DisplaySwitch} + */ + _this.displaySwitch = null; + /** + * Instance of {@link EventManager}. + * + * @private + * @type {EventManager} + */ + _this.eventManager = null; + /** + * Current cell range. + * + * @type {Object} + */ + _this.range = {}; + /** + * @private + * @type {Boolean} + */ + _this.mouseDown = false; + /** + * @private + * @type {Boolean} + */ + _this.contextMenuEvent = false; + /** + * @private + * @type {*} + */ + _this.timer = null; - var label = 'Middle'; - var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var className = _this11.getCellMeta(row, col).className; + privatePool.set(_this, { + tempEditorDimensions: {}, + cellBelowCursor: null + }); + return _this; + } - if (className && className.indexOf('htMiddle') !== -1) { - return true; - } - }); + /** + * Check if the plugin is enabled in the Handsontable settings. + * + * @returns {Boolean} + */ - if (hasClass) { - label = (0, _utils.markLabelAsSelected)(label); - } - return label; - }, - callback: function callback() { - var _this12 = this; + _createClass(Comments, [{ + key: 'isEnabled', + value: function isEnabled() { + return !!this.hot.getSettings().comments; + } - var range = this.getSelectedRange(); - var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { - return _this12.getCellMeta(row, col).className; - }); - var type = 'vertical'; - var alignment = 'htMiddle'; + /** + * Enable plugin for this Handsontable instance. + */ - this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); - (0, _utils.align)(range, type, alignment, function (row, col) { - return _this12.getCellMeta(row, col); - }, function (row, col, key, value) { - return _this12.setCellMeta(row, col, key, value); - }); - this.render(); - }, + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; - disabled: false - }, { - key: KEY + ':bottom', - name: function name() { - var _this13 = this; + if (this.enabled) { + return; + } - var label = 'Bottom'; - var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - var className = _this13.getCellMeta(row, col).className; + if (!this.editor) { + this.editor = new _commentEditor2.default(); + } - if (className && className.indexOf('htBottom') !== -1) { - return true; - } - }); + if (!this.eventManager) { + this.eventManager = new _eventManager2.default(this); + } - if (hasClass) { - label = (0, _utils.markLabelAsSelected)(label); - } + if (!this.displaySwitch) { + this.displaySwitch = new _displaySwitch2.default(this.getDisplayDelaySetting()); + } - return label; - }, - callback: function callback() { - var _this14 = this; + this.addHook('afterContextMenuDefaultOptions', function (options) { + return _this2.addToContextMenu(options); + }); + this.addHook('afterRenderer', function (TD, row, col, prop, value, cellProperties) { + return _this2.onAfterRenderer(TD, cellProperties); + }); + this.addHook('afterScrollHorizontally', function () { + return _this2.hide(); + }); + this.addHook('afterScrollVertically', function () { + return _this2.hide(); + }); + this.addHook('afterBeginEditing', function (args) { + return _this2.onAfterBeginEditing(args); + }); - var range = this.getSelectedRange(); - var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { - return _this14.getCellMeta(row, col).className; - }); - var type = 'vertical'; - var alignment = 'htBottom'; + this.displaySwitch.addLocalHook('hide', function () { + return _this2.hide(); + }); + this.displaySwitch.addLocalHook('show', function (row, col) { + return _this2.showAtCell(row, col); + }); - this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); - (0, _utils.align)(range, type, alignment, function (row, col) { - return _this14.getCellMeta(row, col); - }, function (row, col, key, value) { - return _this14.setCellMeta(row, col, key, value); - }); - this.render(); - }, + this.registerListeners(); - disabled: false - }] + _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'enablePlugin', this).call(this); } - }; -} - -/***/ }), -/* 226 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; + /** + * Update plugin for this Handsontable instance. + */ + }, { + key: 'updatePlugin', + value: function updatePlugin() { + this.disablePlugin(); + this.enablePlugin(); + _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'updatePlugin', this).call(this); -exports.__esModule = true; -exports.KEY = undefined; -exports.default = clearColumnItem; + this.displaySwitch.updateDelay(this.getDisplayDelaySetting()); + } -var _utils = __webpack_require__(17); + /** + * Disable plugin for this Handsontable instance. + */ -var KEY = exports.KEY = 'clear_column'; + }, { + key: 'disablePlugin', + value: function disablePlugin() { + _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'disablePlugin', this).call(this); + } -function clearColumnItem() { - return { - key: KEY, - name: 'Clear column', + /** + * Register all necessary DOM listeners. + * + * @private + */ - callback: function callback(key, selection) { - var column = selection.start.col; + }, { + key: 'registerListeners', + value: function registerListeners() { + var _this3 = this; - if (this.countRows()) { - this.populateFromArray(0, column, [[null]], Math.max(selection.start.row, selection.end.row), column, 'ContextMenu.clearColumn'); - } - }, - disabled: function disabled() { - var selected = (0, _utils.getValidSelection)(this); + this.eventManager.addEventListener(document, 'mouseover', function (event) { + return _this3.onMouseOver(event); + }); + this.eventManager.addEventListener(document, 'mousedown', function (event) { + return _this3.onMouseDown(event); + }); + this.eventManager.addEventListener(document, 'mouseup', function (event) { + return _this3.onMouseUp(event); + }); + this.eventManager.addEventListener(this.editor.getInputElement(), 'blur', function (event) { + return _this3.onEditorBlur(event); + }); + this.eventManager.addEventListener(this.editor.getInputElement(), 'mousedown', function (event) { + return _this3.onEditorMouseDown(event); + }); + this.eventManager.addEventListener(this.editor.getInputElement(), 'mouseup', function (event) { + return _this3.onEditorMouseUp(event); + }); + } - if (!selected) { - return true; - } - var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1]; - var rowSelected = entireRowSelection.join(',') == selected.join(','); + /** + * Set current cell range to be able to use general methods like {@link Comments#setComment}, + * {@link Comments#removeComment}, {@link Comments#show}. + * + * @param {Object} range Object with `from` and `to` properties, each with `row` and `col` properties. + */ - return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || rowSelected; + }, { + key: 'setRange', + value: function setRange(range) { + this.range = range; } - }; -} -/***/ }), -/* 227 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Clear the currently selected cell. + */ -"use strict"; + }, { + key: 'clearRange', + value: function clearRange() { + this.range = {}; + } + /** + * Check if the event target is a cell containing a comment. + * + * @param {Event} event DOM event + * @returns {Boolean} + */ -exports.__esModule = true; -exports.KEY = undefined; -exports.default = columnLeftItem; + }, { + key: 'targetIsCellWithComment', + value: function targetIsCellWithComment(event) { + var closestCell = (0, _element.closest)(event.target, 'TD', 'TBODY'); -var _utils = __webpack_require__(17); + return !!(closestCell && (0, _element.hasClass)(closestCell, 'htCommentCell') && (0, _element.closest)(closestCell, [this.hot.rootElement])); + } -var KEY = exports.KEY = 'col_left'; + /** + * Check if the event target is a comment textarea. + * + * @param {Event} event DOM event. + * @returns {Boolean} + */ -function columnLeftItem() { - return { - key: KEY, - name: 'Insert column on the left', - callback: function callback(key, selection) { - this.alter('insert_col', selection.start.col, 1, 'ContextMenu.columnLeft'); - }, - disabled: function disabled() { - var selected = (0, _utils.getValidSelection)(this); + }, { + key: 'targetIsCommentTextArea', + value: function targetIsCommentTextArea(event) { + return this.editor.getInputElement() === event.target; + } - if (!selected) { - return true; - } - if (!this.isColumnModificationAllowed()) { - return true; + /** + * Set a comment for a cell according to the previously set range (see {@link Comments#setRange}). + * + * @param {String} value Comment contents. + */ + + }, { + key: 'setComment', + value: function setComment(value) { + if (!this.range.from) { + throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())'); } - var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1]; - var rowSelected = entireRowSelection.join(',') == selected.join(','); - var onlyOneColumn = this.countCols() === 1; + var editorValue = this.editor.getValue(); + var comment = ''; - return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected; - }, - hidden: function hidden() { - return !this.getSettings().allowInsertColumn; - } - }; -} + if (value != null) { + comment = value; + } else if (editorValue != null) { + comment = editorValue; + } -/***/ }), -/* 228 */ -/***/ (function(module, exports, __webpack_require__) { + var row = this.range.from.row; + var col = this.range.from.col; -"use strict"; + this.updateCommentMeta(row, col, _defineProperty({}, META_COMMENT_VALUE, comment)); + this.hot.render(); + } + /** + * Set a comment for a cell. + * + * @param {Number} row Visual row index. + * @param {Number} col Visual column index. + * @param {String} value Comment contents. + */ -exports.__esModule = true; -exports.KEY = undefined; -exports.default = columnRightItem; + }, { + key: 'setCommentAtCell', + value: function setCommentAtCell(row, col, value) { + this.setRange({ + from: new _src.CellCoords(row, col) + }); + this.setComment(value); + } -var _utils = __webpack_require__(17); + /** + * Remove a comment from a cell according to previously set range (see {@link Comments#setRange}). + * + * @param {Boolean} [forceRender = true] If set to `true`, the table will be re-rendered at the end of the operation. + */ -var KEY = exports.KEY = 'col_right'; + }, { + key: 'removeComment', + value: function removeComment() { + var forceRender = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; -function columnRightItem() { - return { - key: KEY, - name: 'Insert column on the right', + if (!this.range.from) { + throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())'); + } - callback: function callback(key, selection) { - this.alter('insert_col', selection.end.col + 1, 1, 'ContextMenu.columnRight'); - }, - disabled: function disabled() { - var selected = (0, _utils.getValidSelection)(this); + this.hot.setCellMeta(this.range.from.row, this.range.from.col, META_COMMENT, void 0); - if (!selected) { - return true; - } - if (!this.isColumnModificationAllowed()) { - return true; + if (forceRender) { + this.hot.render(); } - var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1]; - var rowSelected = entireRowSelection.join(',') == selected.join(','); - var onlyOneColumn = this.countCols() === 1; - return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected; - }, - hidden: function hidden() { - return !this.getSettings().allowInsertColumn; + this.hide(); } - }; -} -/***/ }), -/* 229 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Remove comment from a cell. + * + * @param {Number} row Visual row index. + * @param {Number} col Visual column index. + * @param {Boolean} [forceRender = true] If `true`, the table will be re-rendered at the end of the operation. + */ -"use strict"; + }, { + key: 'removeCommentAtCell', + value: function removeCommentAtCell(row, col) { + var forceRender = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + this.setRange({ + from: new _src.CellCoords(row, col) + }); + this.removeComment(forceRender); + } -exports.__esModule = true; -exports.KEY = undefined; -exports.default = readOnlyItem; + /** + * Get comment from a cell at the predefined range. + */ -var _utils = __webpack_require__(17); + }, { + key: 'getComment', + value: function getComment() { + var row = this.range.from.row; + var column = this.range.from.col; -var KEY = exports.KEY = 'make_read_only'; + return this.getCommentMeta(row, column, META_COMMENT_VALUE); + } -function readOnlyItem() { - return { - key: KEY, - name: function name() { - var _this = this; + /** + * Get comment from a cell at the provided coordinates. + * + * @param {Number} row Visual row index. + * @param {Number} column Visual column index. + */ - var label = 'Read only'; - var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { - return _this.getCellMeta(row, col).readOnly; - }); + }, { + key: 'getCommentAtCell', + value: function getCommentAtCell(row, column) { + return this.getCommentMeta(row, column, META_COMMENT_VALUE); + } - if (atLeastOneReadOnly) { - label = (0, _utils.markLabelAsSelected)(label); + /** + * Show the comment editor accordingly to the previously set range (see {@link Comments#setRange}). + * + * @returns {Boolean} Returns `true` if comment editor was shown. + */ + + }, { + key: 'show', + value: function show() { + if (!this.range.from) { + throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())'); } + var meta = this.hot.getCellMeta(this.range.from.row, this.range.from.col); - return label; - }, - callback: function callback() { - var _this2 = this; + this.refreshEditor(true); + this.editor.setValue(meta[META_COMMENT] ? meta[META_COMMENT][META_COMMENT_VALUE] : null || ''); - var range = this.getSelectedRange(); - var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(range, function (row, col) { - return _this2.getCellMeta(row, col).readOnly; - }); + if (this.editor.hidden) { + this.editor.show(); + } - range.forAll(function (row, col) { - _this2.setCellMeta(row, col, 'readOnly', !atLeastOneReadOnly); - }); - this.render(); - }, - disabled: function disabled() { - return !(this.getSelectedRange() && !this.selection.selectedHeader.corner); + return true; } - }; -} - -/***/ }), -/* 230 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; + /** + * Show comment editor according to cell coordinates. + * + * @param {Number} row Visual row index. + * @param {Number} col Visual column index. + * @returns {Boolean} Returns `true` if comment editor was shown. + */ + }, { + key: 'showAtCell', + value: function showAtCell(row, col) { + this.setRange({ + from: new _src.CellCoords(row, col) + }); -exports.__esModule = true; -exports.default = redoItem; -var KEY = exports.KEY = 'redo'; + return this.show(); + } -function redoItem() { - return { - key: KEY, - name: 'Redo', + /** + * Hide the comment editor. + */ - callback: function callback() { - this.redo(); - }, - disabled: function disabled() { - return this.undoRedo && !this.undoRedo.isRedoAvailable(); + }, { + key: 'hide', + value: function hide() { + if (!this.editor.hidden) { + this.editor.hide(); + } } - }; -} -/***/ }), -/* 231 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Refresh comment editor position and styling. + * + * @param {Boolean} [force=false] If `true` then recalculation will be forced. + */ -"use strict"; + }, { + key: 'refreshEditor', + value: function refreshEditor() { + var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + if (!force && (!this.range.from || !this.editor.isVisible())) { + return; + } + var scrollableElement = (0, _element.getScrollableElement)(this.hot.view.wt.wtTable.TABLE); + var TD = this.hot.view.wt.wtTable.getCell(this.range.from); + var row = this.range.from.row; + var column = this.range.from.col; + var cellOffset = (0, _element.offset)(TD); + var lastColWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(column); + var cellTopOffset = cellOffset.top < 0 ? 0 : cellOffset.top; + var cellLeftOffset = cellOffset.left; -exports.__esModule = true; -exports.KEY = undefined; -exports.default = removeColumnItem; + if (this.hot.view.wt.wtViewport.hasVerticalScroll() && scrollableElement !== window) { + cellTopOffset -= this.hot.view.wt.wtOverlays.topOverlay.getScrollPosition(); + } -var _utils = __webpack_require__(17); + if (this.hot.view.wt.wtViewport.hasHorizontalScroll() && scrollableElement !== window) { + cellLeftOffset -= this.hot.view.wt.wtOverlays.leftOverlay.getScrollPosition(); + } -var KEY = exports.KEY = 'remove_col'; + var x = cellLeftOffset + lastColWidth; + var y = cellTopOffset; -function removeColumnItem() { - return { - key: KEY, - name: 'Remove column', + var commentStyle = this.getCommentMeta(row, column, META_STYLE); + var readOnly = this.getCommentMeta(row, column, META_READONLY); - callback: function callback(key, selection) { - var amount = selection.end.col - selection.start.col + 1; + if (commentStyle) { + this.editor.setSize(commentStyle.width, commentStyle.height); + } else { + this.editor.resetSize(); + } - this.alter('remove_col', selection.start.col, amount, 'ContextMenu.removeColumn'); - }, - disabled: function disabled() { - var selected = (0, _utils.getValidSelection)(this); - var totalColumns = this.countCols(); + this.editor.setReadOnlyState(readOnly); - return !selected || this.selection.selectedHeader.rows || this.selection.selectedHeader.corner || !this.isColumnModificationAllowed() || !totalColumns; - }, - hidden: function hidden() { - return !this.getSettings().allowRemoveColumn; + this.editor.setPosition(x, y); } - }; -} - -/***/ }), -/* 232 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; + /** + * Check if there is a comment for selected range. + * + * @private + * @returns {Boolean} + */ + }, { + key: 'checkSelectionCommentsConsistency', + value: function checkSelectionCommentsConsistency() { + var selected = this.hot.getSelectedRange(); -exports.__esModule = true; -exports.KEY = undefined; -exports.default = removeRowItem; + if (!selected) { + return false; + } + var hasComment = false; + var cell = selected.from; // IN EXCEL THERE IS COMMENT ONLY FOR TOP LEFT CELL IN SELECTION -var _utils = __webpack_require__(17); + if (this.getCommentMeta(cell.row, cell.col, META_COMMENT_VALUE)) { + hasComment = true; + } -var KEY = exports.KEY = 'remove_row'; + return hasComment; + } -function removeRowItem() { - return { - key: KEY, - name: 'Remove row', + /** + * Set or update the comment-related cell meta. + * + * @param {Number} row Visual row index. + * @param {Number} column Visual column index. + * @param {Object} metaObject Object defining all the comment-related meta information. + */ - callback: function callback(key, selection) { - var amount = selection.end.row - selection.start.row + 1; + }, { + key: 'updateCommentMeta', + value: function updateCommentMeta(row, column, metaObject) { + var oldComment = this.hot.getCellMeta(row, column)[META_COMMENT]; + var newComment = void 0; - this.alter('remove_row', selection.start.row, amount, 'ContextMenu.removeRow'); - }, - disabled: function disabled() { - var selected = (0, _utils.getValidSelection)(this); - var totalRows = this.countRows(); + if (oldComment) { + newComment = (0, _object.deepClone)(oldComment); + (0, _object.deepExtend)(newComment, metaObject); + } else { + newComment = metaObject; + } - return !selected || this.selection.selectedHeader.cols || this.selection.selectedHeader.corner || !totalRows; - }, - hidden: function hidden() { - return !this.getSettings().allowRemoveRow; + this.hot.setCellMeta(row, column, META_COMMENT, newComment); } - }; -} -/***/ }), -/* 233 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Get the comment related meta information. + * + * @param {Number} row Visual row index. + * @param {Number} column Visual column index. + * @param {String} property Cell meta property. + * @returns {Mixed} + */ -"use strict"; + }, { + key: 'getCommentMeta', + value: function getCommentMeta(row, column, property) { + var cellMeta = this.hot.getCellMeta(row, column); + + if (!cellMeta[META_COMMENT]) { + return void 0; + } + return cellMeta[META_COMMENT][property]; + } -exports.__esModule = true; -exports.KEY = undefined; -exports.default = rowAboveItem; + /** + * `mousedown` event callback. + * + * @private + * @param {MouseEvent} event The `mousedown` event. + */ -var _utils = __webpack_require__(17); + }, { + key: 'onMouseDown', + value: function onMouseDown(event) { + this.mouseDown = true; -var KEY = exports.KEY = 'row_above'; + if (!this.hot.view || !this.hot.view.wt) { + return; + } -function rowAboveItem() { - return { - key: KEY, - name: 'Insert row above', + if (!this.contextMenuEvent && !this.targetIsCommentTextArea(event)) { + var eventCell = (0, _element.closest)(event.target, 'TD', 'TBODY'); + var coordinates = null; - callback: function callback(key, selection) { - this.alter('insert_row', selection.start.row, 1, 'ContextMenu.rowAbove'); - }, - disabled: function disabled() { - var selected = (0, _utils.getValidSelection)(this); + if (eventCell) { + coordinates = this.hot.view.wt.wtTable.getCoords(eventCell); + } - return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows; - }, - hidden: function hidden() { - return !this.getSettings().allowInsertRow; + if (!eventCell || this.range.from && coordinates && (this.range.from.row !== coordinates.row || this.range.from.col !== coordinates.col)) { + this.hide(); + } + } + this.contextMenuEvent = false; } - }; -} - -/***/ }), -/* 234 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; + /** + * `mouseover` event callback. + * + * @private + * @param {MouseEvent} event The `mouseover` event. + */ + }, { + key: 'onMouseOver', + value: function onMouseOver(event) { + var priv = privatePool.get(this); -exports.__esModule = true; -exports.KEY = undefined; -exports.default = rowBelowItem; + priv.cellBelowCursor = document.elementFromPoint(event.clientX, event.clientY); -var _utils = __webpack_require__(17); + if (this.mouseDown || this.editor.isFocused() || (0, _element.hasClass)(event.target, 'wtBorder') || priv.cellBelowCursor !== event.target || !this.editor) { + return; + } -var KEY = exports.KEY = 'row_below'; + if (this.targetIsCellWithComment(event)) { + var coordinates = this.hot.view.wt.wtTable.getCoords(event.target); + var range = { + from: new _src.CellCoords(coordinates.row, coordinates.col) + }; -function rowBelowItem() { - return { - key: KEY, - name: 'Insert row below', + this.displaySwitch.show(range); + } else if ((0, _element.isChildOf)(event.target, document) && !this.targetIsCommentTextArea(event)) { + this.displaySwitch.hide(); + } + } - callback: function callback(key, selection) { - this.alter('insert_row', selection.end.row + 1, 1, 'ContextMenu.rowBelow'); - }, - disabled: function disabled() { - var selected = (0, _utils.getValidSelection)(this); + /** + * `mouseup` event callback. + * + * @private + * @param {MouseEvent} event The `mouseup` event. + */ - return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows; - }, - hidden: function hidden() { - return !this.getSettings().allowInsertRow; + }, { + key: 'onMouseUp', + value: function onMouseUp(event) { + this.mouseDown = false; } - }; -} -/***/ }), -/* 235 */ -/***/ (function(module, exports, __webpack_require__) { + /** * + * The `afterRenderer` hook callback.. + * + * @private + * @param {HTMLTableCellElement} TD The rendered `TD` element. + * @param {Object} cellProperties The rendered cell's property object. + */ -"use strict"; + }, { + key: 'onAfterRenderer', + value: function onAfterRenderer(TD, cellProperties) { + if (cellProperties[META_COMMENT] && cellProperties[META_COMMENT][META_COMMENT_VALUE]) { + (0, _element.addClass)(TD, cellProperties.commentedCellClassName); + } + } + /** + * `blur` event callback for the comment editor. + * + * @private + * @param {Event} event The `blur` event. + */ -exports.__esModule = true; -exports.default = undoItem; -var KEY = exports.KEY = 'undo'; + }, { + key: 'onEditorBlur', + value: function onEditorBlur(event) { + this.setComment(); + } -function undoItem() { - return { - key: KEY, - name: 'Undo', + /** + * `mousedown` hook. Along with `onEditorMouseUp` used to simulate the textarea resizing event. + * + * @private + * @param {MouseEvent} event The `mousedown` event. + */ - callback: function callback() { - this.undo(); - }, - disabled: function disabled() { - return this.undoRedo && !this.undoRedo.isUndoAvailable(); - } - }; -} + }, { + key: 'onEditorMouseDown', + value: function onEditorMouseDown(event) { + var priv = privatePool.get(this); -/***/ }), -/* 236 */ -/***/ (function(module, exports, __webpack_require__) { + priv.tempEditorDimensions = { + width: (0, _element.outerWidth)(event.target), + height: (0, _element.outerHeight)(event.target) + }; + } -"use strict"; + /** + * `mouseup` hook. Along with `onEditorMouseDown` used to simulate the textarea resizing event. + * + * @private + * @param {MouseEvent} event The `mouseup` event. + */ + }, { + key: 'onEditorMouseUp', + value: function onEditorMouseUp(event) { + var priv = privatePool.get(this); + var currentWidth = (0, _element.outerWidth)(event.target); + var currentHeight = (0, _element.outerHeight)(event.target); -exports.__esModule = true; -exports.default = copyItem; -function copyItem(copyPastePlugin) { - return { - key: 'copy', - name: 'Copy', - callback: function callback() { - copyPastePlugin.setCopyableText(); - copyPastePlugin.copy(true); - }, - disabled: function disabled() { - return !copyPastePlugin.hot.getSelected(); - }, + if (currentWidth !== priv.tempEditorDimensions.width + 1 || currentHeight !== priv.tempEditorDimensions.height + 2) { + this.updateCommentMeta(this.range.from.row, this.range.from.col, _defineProperty({}, META_STYLE, { + width: currentWidth, + height: currentHeight + })); + } + } - hidden: false - }; -} + /** + * Context Menu's "Add comment" callback. Results in showing the comment editor. + * + * @private + */ -/***/ }), -/* 237 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: 'onContextMenuAddComment', + value: function onContextMenuAddComment() { + var _this4 = this; -"use strict"; + this.displaySwitch.cancelHiding(); + var coords = this.hot.getSelectedRange(); + this.contextMenuEvent = true; + this.setRange({ + from: coords.from + }); + this.show(); + setTimeout(function () { + if (_this4.hot) { + _this4.hot.deselectCell(); + _this4.editor.focus(); + } + }, 10); + } -exports.__esModule = true; -exports.default = cutItem; -function cutItem(copyPastePlugin) { - return { - key: 'cut', - name: 'Cut', - callback: function callback() { - copyPastePlugin.setCopyableText(); - copyPastePlugin.cut(true); - }, - disabled: function disabled() { - return !copyPastePlugin.hot.getSelected(); - }, + /** + * Context Menu's "remove comment" callback. + * + * @private + * @param {Object} selection The current selection. + */ - hidden: false - }; -} + }, { + key: 'onContextMenuRemoveComment', + value: function onContextMenuRemoveComment(selection) { + this.contextMenuEvent = true; -/***/ }), -/* 238 */ -/***/ (function(module, exports, __webpack_require__) { + for (var i = selection.start.row; i <= selection.end.row; i++) { + for (var j = selection.start.col; j <= selection.end.col; j++) { + this.removeCommentAtCell(i, j, false); + } + } -"use strict"; + this.hot.render(); + } + /** + * Context Menu's "make comment read-only" callback. + * + * @private + * @param {Object} selection The current selection. + */ -exports.__esModule = true; + }, { + key: 'onContextMenuMakeReadOnly', + value: function onContextMenuMakeReadOnly(selection) { + this.contextMenuEvent = true; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + for (var i = selection.start.row; i <= selection.end.row; i++) { + for (var j = selection.start.col; j <= selection.end.col; j++) { + var currentState = !!this.getCommentMeta(i, j, META_READONLY); -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + this.updateCommentMeta(i, j, _defineProperty({}, META_READONLY, !currentState)); + } + } + } -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + /** + * Add Comments plugin options to the Context Menu. + * + * @private + * @param {Object} defaultOptions + */ -var _base = __webpack_require__(12); + }, { + key: 'addToContextMenu', + value: function addToContextMenu(defaultOptions) { + var _this5 = this; -var _base2 = _interopRequireDefault(_base); + defaultOptions.items.push({ + name: '---------' + }, { + key: 'commentsAddEdit', + name: function name() { + return _this5.checkSelectionCommentsConsistency() ? 'Edit comment' : 'Add comment'; + }, + callback: function callback() { + return _this5.onContextMenuAddComment(); + }, + disabled: function disabled() { + return !(this.getSelected() && !this.selection.selectedHeader.corner); + } + }, { + key: 'commentsRemove', + name: function name() { + return 'Delete comment'; + }, -var _pluginHooks = __webpack_require__(8); + callback: function callback(key, selection) { + return _this5.onContextMenuRemoveComment(selection); + }, + disabled: function disabled() { + return _this5.hot.selection.selectedHeader.corner; + } + }, { + key: 'commentsReadOnly', + name: function name() { + var _this6 = this; -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + var label = 'Read only comment'; + var hasProperty = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var readOnlyProperty = _this6.getCellMeta(row, col)[META_COMMENT]; + if (readOnlyProperty) { + readOnlyProperty = readOnlyProperty[META_READONLY]; + } -var _SheetClip = __webpack_require__(134); + if (readOnlyProperty) { + return true; + } + }); -var _SheetClip2 = _interopRequireDefault(_SheetClip); + if (hasProperty) { + label = (0, _utils.markLabelAsSelected)(label); + } -var _src = __webpack_require__(11); + return label; + }, -var _unicode = __webpack_require__(16); + callback: function callback(key, selection) { + return _this5.onContextMenuMakeReadOnly(selection); + }, + disabled: function disabled() { + return _this5.hot.selection.selectedHeader.corner || !_this5.checkSelectionCommentsConsistency(); + } + }); + } -var _element = __webpack_require__(0); + /** + * Get `displayDelay` setting of comment plugin. + * + * @returns {Number|undefined} + */ -var _array = __webpack_require__(2); + }, { + key: 'getDisplayDelaySetting', + value: function getDisplayDelaySetting() { + var commentSetting = this.hot.getSettings().comments; -var _number = __webpack_require__(6); + if ((0, _object.isObject)(commentSetting)) { + return commentSetting.displayDelay; + } -var _event = __webpack_require__(7); + return void 0; + } -var _plugins = __webpack_require__(5); + /** + * `afterBeginEditing` hook callback. + * + * @private + * @param {Number} row Visual row index of the currently edited cell. + * @param {Number} column Visual column index of the currently edited cell. + */ -var _textarea = __webpack_require__(239); + }, { + key: 'onAfterBeginEditing', + value: function onAfterBeginEditing(row, column) { + this.hide(); + } -var _textarea2 = _interopRequireDefault(_textarea); + /** + * Destroy plugin instance. + */ -var _copy = __webpack_require__(236); + }, { + key: 'destroy', + value: function destroy() { + if (this.editor) { + this.editor.destroy(); + } -var _copy2 = _interopRequireDefault(_copy); + if (this.displaySwitch) { + this.displaySwitch.destroy(); + } -var _cut = __webpack_require__(237); + _get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'destroy', this).call(this); + } + }]); -var _cut2 = _interopRequireDefault(_cut); + return Comments; +}(_base2.default); -var _eventManager = __webpack_require__(4); +(0, _plugins.registerPlugin)('comments', Comments); -var _eventManager2 = _interopRequireDefault(_eventManager); +exports.default = Comments; -__webpack_require__(300); +/***/ }), +/* 256 */ +/***/ (function(module, exports, __webpack_require__) { -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +"use strict"; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +exports.__esModule = true; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -_pluginHooks2.default.getSingleton().register('afterCopyLimit'); -_pluginHooks2.default.getSingleton().register('modifyCopyableRange'); -_pluginHooks2.default.getSingleton().register('beforeCut'); -_pluginHooks2.default.getSingleton().register('afterCut'); -_pluginHooks2.default.getSingleton().register('beforePaste'); -_pluginHooks2.default.getSingleton().register('afterPaste'); -_pluginHooks2.default.getSingleton().register('beforeCopy'); -_pluginHooks2.default.getSingleton().register('afterCopy'); +var _element = __webpack_require__(0); -var ROWS_LIMIT = 1000; -var COLUMNS_LIMIT = 1000; -var privatePool = new WeakMap(); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * @description - * This plugin enables the copy/paste functionality in the Handsontable. + * Comment editor for the Comments plugin. * - * @example - * ```js - * ... - * copyPaste: true, - * ... - * ``` - * @class CopyPaste - * @plugin CopyPaste + * @class CommentEditor + * @plugin Comments */ +var CommentEditor = function () { + _createClass(CommentEditor, null, [{ + key: 'CLASS_EDITOR_CONTAINER', + get: function get() { + return 'htCommentsContainer'; + } + }, { + key: 'CLASS_EDITOR', + get: function get() { + return 'htComments'; + } + }, { + key: 'CLASS_INPUT', + get: function get() { + return 'htCommentTextArea'; + } + }, { + key: 'CLASS_CELL', + get: function get() { + return 'htCommentCell'; + } + }]); -var CopyPaste = function (_BasePlugin) { - _inherits(CopyPaste, _BasePlugin); - - function CopyPaste(hotInstance) { - _classCallCheck(this, CopyPaste); + function CommentEditor() { + _classCallCheck(this, CommentEditor); - /** - * Event manager - * - * @type {EventManager} - */ - var _this = _possibleConstructorReturn(this, (CopyPaste.__proto__ || Object.getPrototypeOf(CopyPaste)).call(this, hotInstance)); + this.editor = this.createEditor(); + this.editorStyle = this.editor.style; - _this.eventManager = new _eventManager2.default(_this); - /** - * Maximum number of columns than can be copied to clipboard using CTRL + C. - * - * @private - * @type {Number} - * @default 1000 - */ - _this.columnsLimit = COLUMNS_LIMIT; - /** - * Ranges of the cells coordinates, which should be used to copy/cut/paste actions. - * - * @private - * @type {Array} - */ - _this.copyableRanges = []; - /** - * Defines paste (CTRL + V) behavior. - * * Default value `"overwrite"` will paste clipboard value over current selection. - * * When set to `"shift_down"`, clipboard data will be pasted in place of current selection, while all selected cells are moved down. - * * When set to `"shift_right"`, clipboard data will be pasted in place of current selection, while all selected cells are moved right. - * - * @private - * @type {String} - * @default 'overwrite' - */ - _this.pasteMode = 'overwrite'; - /** - * Maximum number of rows than can be copied to clipboard using CTRL + C. - * - * @private - * @type {Number} - * @default 1000 - */ - _this.rowsLimit = ROWS_LIMIT; - /** - * The `textarea` element which is necessary to process copying, cutting off and pasting. - * - * @private - * @type {HTMLElement} - * @default undefined - */ - _this.textarea = void 0; + this.hidden = true; - privatePool.set(_this, { - isTriggeredByPaste: false - }); - return _this; + this.hide(); } /** - * Check if plugin is enabled. + * Set position of the comments editor according to the provided x and y coordinates. * - * @returns {Boolean} + * @param {Number} x X position (in pixels). + * @param {Number} y Y position (in pixels). */ - _createClass(CopyPaste, [{ - key: 'isEnabled', - value: function isEnabled() { - return !!this.hot.getSettings().copyPaste; + _createClass(CommentEditor, [{ + key: 'setPosition', + value: function setPosition(x, y) { + this.editorStyle.left = x + 'px'; + this.editorStyle.top = y + 'px'; } /** - * Enable the plugin. + * Set the editor size according to the provided arguments. + * + * @param {Number} width Width in pixels. + * @param {Number} height Height in pixels. */ }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; - - if (this.enabled) { - return; - } - - var settings = this.hot.getSettings(); - - this.textarea = _textarea2.default.getSingleton(); + key: 'setSize', + value: function setSize(width, height) { + if (width && height) { + var input = this.getInputElement(); - if (_typeof(settings.copyPaste) === 'object') { - this.pasteMode = settings.copyPaste.pasteMode || this.pasteMode; - this.rowsLimit = settings.copyPaste.rowsLimit || this.rowsLimit; - this.columnsLimit = settings.copyPaste.columnsLimit || this.columnsLimit; + input.style.width = width + 'px'; + input.style.height = height + 'px'; } - - this.addHook('afterContextMenuDefaultOptions', function (options) { - return _this2.onAfterContextMenuDefaultOptions(options); - }); - this.addHook('beforeKeyDown', function (event) { - return _this2.onBeforeKeyDown(event); - }); - - this.registerEvents(); - - _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'enablePlugin', this).call(this); } + /** - * Updates the plugin to use the latest options you have specified. + * Reset the editor size to its initial state. */ }, { - key: 'updatePlugin', - value: function updatePlugin() { - this.disablePlugin(); - this.enablePlugin(); + key: 'resetSize', + value: function resetSize() { + var input = this.getInputElement(); - _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'updatePlugin', this).call(this); + input.style.width = ''; + input.style.height = ''; } /** - * Disable plugin for this Handsontable instance. + * Set the read-only state for the comments editor. + * + * @param {Boolean} state The new read only state. */ }, { - key: 'disablePlugin', - value: function disablePlugin() { - if (this.textarea) { - this.textarea.destroy(); - } + key: 'setReadOnlyState', + value: function setReadOnlyState(state) { + var input = this.getInputElement(); - _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'disablePlugin', this).call(this); + input.readOnly = state; } /** - * Prepares copyable text from the cells selection in the invisible textarea. - * - * @function setCopyable - * @memberof CopyPaste# + * Show the comments editor. */ }, { - key: 'setCopyableText', - value: function setCopyableText() { - var selRange = this.hot.getSelectedRange(); - - if (!selRange) { - return; - } - - var topLeft = selRange.getTopLeftCorner(); - var bottomRight = selRange.getBottomRightCorner(); - var startRow = topLeft.row; - var startCol = topLeft.col; - var endRow = bottomRight.row; - var endCol = bottomRight.col; - var finalEndRow = Math.min(endRow, startRow + this.rowsLimit - 1); - var finalEndCol = Math.min(endCol, startCol + this.columnsLimit - 1); - - this.copyableRanges.length = 0; - - this.copyableRanges.push({ - startRow: startRow, - startCol: startCol, - endRow: finalEndRow, - endCol: finalEndCol - }); - - this.copyableRanges = this.hot.runHooks('modifyCopyableRange', this.copyableRanges); - - var copyableData = this.getRangedCopyableData(this.copyableRanges); - - this.textarea.setValue(copyableData); - - if (endRow !== finalEndRow || endCol !== finalEndCol) { - this.hot.runHooks('afterCopyLimit', endRow - startRow + 1, endCol - startCol + 1, this.rowsLimit, this.columnsLimit); - } + key: 'show', + value: function show() { + this.editorStyle.display = 'block'; + this.hidden = false; } /** - * Create copyable text releated to range objects. - * - * @since 0.19.0 - * @param {Array} ranges Array of Objects with properties `startRow`, `endRow`, `startCol` and `endCol`. - * @returns {String} Returns string which will be copied into clipboard. + * Hide the comments editor. */ }, { - key: 'getRangedCopyableData', - value: function getRangedCopyableData(ranges) { - var _this3 = this; - - var dataSet = []; - var copyableRows = []; - var copyableColumns = []; - - // Count all copyable rows and columns - (0, _array.arrayEach)(ranges, function (range) { - (0, _number.rangeEach)(range.startRow, range.endRow, function (row) { - if (copyableRows.indexOf(row) === -1) { - copyableRows.push(row); - } - }); - (0, _number.rangeEach)(range.startCol, range.endCol, function (column) { - if (copyableColumns.indexOf(column) === -1) { - copyableColumns.push(column); - } - }); - }); - // Concat all rows and columns data defined in ranges into one copyable string - (0, _array.arrayEach)(copyableRows, function (row) { - var rowSet = []; - - (0, _array.arrayEach)(copyableColumns, function (column) { - rowSet.push(_this3.hot.getCopyableData(row, column)); - }); - - dataSet.push(rowSet); - }); - - return _SheetClip2.default.stringify(dataSet); + key: 'hide', + value: function hide() { + this.editorStyle.display = 'none'; + this.hidden = true; } /** - * Create copyable text releated to range objects. + * Checks if the editor is visible. * - * @since 0.31.1 - * @param {Array} ranges Array of Objects with properties `startRow`, `startCol`, `endRow` and `endCol`. - * @returns {Array} Returns array of arrays which will be copied into clipboard. + * @returns {Boolean} */ }, { - key: 'getRangedData', - value: function getRangedData(ranges) { - var _this4 = this; - - var dataSet = []; - var copyableRows = []; - var copyableColumns = []; - - // Count all copyable rows and columns - (0, _array.arrayEach)(ranges, function (range) { - (0, _number.rangeEach)(range.startRow, range.endRow, function (row) { - if (copyableRows.indexOf(row) === -1) { - copyableRows.push(row); - } - }); - (0, _number.rangeEach)(range.startCol, range.endCol, function (column) { - if (copyableColumns.indexOf(column) === -1) { - copyableColumns.push(column); - } - }); - }); - // Concat all rows and columns data defined in ranges into one copyable string - (0, _array.arrayEach)(copyableRows, function (row) { - var rowSet = []; - - (0, _array.arrayEach)(copyableColumns, function (column) { - rowSet.push(_this4.hot.getCopyableData(row, column)); - }); - - dataSet.push(rowSet); - }); - - return dataSet; + key: 'isVisible', + value: function isVisible() { + return this.editorStyle.display === 'block'; } /** - * Copy action. + * Set the comment value. * - * @param {Boolean} isTriggeredByClick Flag to determine that copy action was executed by the mouse click. + * @param {String} [value] The value to use. */ }, { - key: 'copy', - value: function copy(isTriggeredByClick) { - var rangedData = this.getRangedData(this.copyableRanges); - - var allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges); - - if (allowCopying) { - this.textarea.setValue(_SheetClip2.default.stringify(rangedData)); - this.textarea.select(); - - if (isTriggeredByClick) { - document.execCommand('copy'); - } + key: 'setValue', + value: function setValue() { + var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; - this.hot.runHooks('afterCopy', rangedData, this.copyableRanges); - } else { - this.textarea.setValue(''); - } + value = value || ''; + this.getInputElement().value = value; } /** - * Cut action. + * Get the comment value. * - * @param {Boolean} isTriggeredByClick Flag to determine that cut action was executed by the mouse click. + * @returns {String} */ }, { - key: 'cut', - value: function cut(isTriggeredByClick) { - var rangedData = this.getRangedData(this.copyableRanges); - - var allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges); - - if (allowCuttingOut) { - this.textarea.setValue(_SheetClip2.default.stringify(rangedData)); - this.hot.selection.empty(); - this.textarea.select(); - - if (isTriggeredByClick) { - document.execCommand('cut'); - } - - this.hot.runHooks('afterCut', rangedData, this.copyableRanges); - } else { - this.textarea.setValue(''); - } + key: 'getValue', + value: function getValue() { + return this.getInputElement().value; } /** - * Simulated paste action. + * Checks if the comment input element is focused. * - * @param {String} [value=''] New value, which should be `pasted`. + * @returns {Boolean} */ }, { - key: 'paste', - value: function paste() { - var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; - - this.textarea.setValue(value); - - this.onPaste(); - this.onInput(); + key: 'isFocused', + value: function isFocused() { + return document.activeElement === this.getInputElement(); } /** - * Register event listeners. - * - * @private + * Focus the comments input element. */ }, { - key: 'registerEvents', - value: function registerEvents() { - var _this5 = this; - - this.eventManager.addEventListener(this.textarea.element, 'paste', function (event) { - return _this5.onPaste(event); - }); - this.eventManager.addEventListener(this.textarea.element, 'input', function (event) { - return _this5.onInput(event); - }); + key: 'focus', + value: function focus() { + this.getInputElement().focus(); } /** - * Trigger to make possible observe `onInput` in textarea. + * Create the `textarea` to be used as a comments editor. * - * @private + * @returns {HTMLElement} */ }, { - key: 'triggerPaste', - value: function triggerPaste() { - this.textarea.select(); + key: 'createEditor', + value: function createEditor() { + var container = document.querySelector('.' + CommentEditor.CLASS_EDITOR_CONTAINER); + var editor = void 0; + var textArea = void 0; - this.onPaste(); + if (!container) { + container = document.createElement('div'); + (0, _element.addClass)(container, CommentEditor.CLASS_EDITOR_CONTAINER); + document.body.appendChild(container); + } + editor = document.createElement('div'); + (0, _element.addClass)(editor, CommentEditor.CLASS_EDITOR); + + textArea = document.createElement('textarea'); + (0, _element.addClass)(textArea, CommentEditor.CLASS_INPUT); + + editor.appendChild(textArea); + container.appendChild(editor); + + return editor; } /** - * `paste` event callback on textarea element. + * Get the input element. * - * @private + * @returns {HTMLElement} */ }, { - key: 'onPaste', - value: function onPaste() { - var priv = privatePool.get(this); - - priv.isTriggeredByPaste = true; + key: 'getInputElement', + value: function getInputElement() { + return this.editor.querySelector('.' + CommentEditor.CLASS_INPUT); } /** - * `input` event callback is called after `paste` event callback. - * - * @private + * Destroy the comments editor. */ }, { - key: 'onInput', - value: function onInput() { - var _this6 = this; + key: 'destroy', + value: function destroy() { + this.editor.parentNode.removeChild(this.editor); + this.editor = null; + this.editorStyle = null; + } + }]); - var priv = privatePool.get(this); + return CommentEditor; +}(); - if (!this.hot.isListening() || !priv.isTriggeredByPaste) { - return; - } +exports.default = CommentEditor; - priv.isTriggeredByPaste = false; +/***/ }), +/* 257 */ +/***/ (function(module, exports, __webpack_require__) { - var input = void 0, - inputArray = void 0, - selected = void 0, - coordsFrom = void 0, - coordsTo = void 0, - cellRange = void 0, - topLeftCorner = void 0, - bottomRightCorner = void 0, - areaStart = void 0, - areaEnd = void 0; +"use strict"; - input = this.textarea.getValue(); - inputArray = _SheetClip2.default.parse(input); - var allowPasting = !!this.hot.runHooks('beforePaste', inputArray, this.copyableRanges); +exports.__esModule = true; - if (!allowPasting) { - return; - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - selected = this.hot.getSelected(); - coordsFrom = new _src.CellCoords(selected[0], selected[1]); - coordsTo = new _src.CellCoords(selected[2], selected[3]); - cellRange = new _src.CellRange(coordsFrom, coordsFrom, coordsTo); - topLeftCorner = cellRange.getTopLeftCorner(); - bottomRightCorner = cellRange.getBottomRightCorner(); - areaStart = topLeftCorner; - areaEnd = new _src.CellCoords(Math.max(bottomRightCorner.row, inputArray.length - 1 + topLeftCorner.row), Math.max(bottomRightCorner.col, inputArray[0].length - 1 + topLeftCorner.col)); +var _function = __webpack_require__(35); - var isSelRowAreaCoverInputValue = coordsTo.row - coordsFrom.row >= inputArray.length - 1; - var isSelColAreaCoverInputValue = coordsTo.col - coordsFrom.col >= inputArray[0].length - 1; +var _object = __webpack_require__(1); - this.hot.addHookOnce('afterChange', function (changes, source) { - var changesLength = changes ? changes.length : 0; +var _localHooks = __webpack_require__(87); - if (changesLength) { - var offset = { row: 0, col: 0 }; - var highestColumnIndex = -1; +var _localHooks2 = _interopRequireDefault(_localHooks); - (0, _array.arrayEach)(changes, function (change, index) { - var nextChange = changesLength > index + 1 ? changes[index + 1] : null; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (nextChange) { - if (!isSelRowAreaCoverInputValue) { - offset.row += Math.max(nextChange[0] - change[0] - 1, 0); - } - if (!isSelColAreaCoverInputValue && change[1] > highestColumnIndex) { - highestColumnIndex = change[1]; - offset.col += Math.max(nextChange[1] - change[1] - 1, 0); - } - } - }); - _this6.hot.selectCell(areaStart.row, areaStart.col, areaEnd.row + offset.row, areaEnd.col + offset.col); - } - }); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - this.hot.populateFromArray(areaStart.row, areaStart.col, inputArray, areaEnd.row, areaEnd.col, 'CopyPaste.paste', this.pasteMode); - this.hot.runHooks('afterPaste', inputArray, this.copyableRanges); - } +var DEFAULT_DISPLAY_DELAY = 250; +var DEFAULT_HIDE_DELAY = 250; + +/** + * Display switch for the Comments plugin. Manages the time of delayed displaying / hiding comments. + * + * @class DisplaySwitch + * @plugin Comments + */ + +var DisplaySwitch = function () { + function DisplaySwitch(displayDelay) { + _classCallCheck(this, DisplaySwitch); /** - * Add copy, cut and paste options to the Context Menu. + * Flag to determine if comment can be showed or hidden. State `true` mean that last performed action + * was an attempt to show comment element. State `false` mean that it was attempt to hide comment element. * - * @private - * @param {Object} options Contains default added options of the Context Menu. + * @type {Boolean} + */ + this.wasLastActionShow = true; + /** + * Show comment after predefined delay. It keeps reference to immutable `debounce` function. + * + * @type {Function} + */ + this.showDebounced = null; + /** + * Reference to timer, run by `setTimeout`, which is hiding comment + * + * @type {Number} */ + this.hidingTimer = null; - }, { - key: 'onAfterContextMenuDefaultOptions', - value: function onAfterContextMenuDefaultOptions(options) { - options.items.push({ - name: '---------' - }, (0, _copy2.default)(this), (0, _cut2.default)(this)); + this.updateDelay(displayDelay); + } + + /** + * Responsible for hiding comment after proper delay. + */ + + + _createClass(DisplaySwitch, [{ + key: 'hide', + value: function hide() { + var _this = this; + + this.wasLastActionShow = false; + + this.hidingTimer = setTimeout(function () { + if (_this.wasLastActionShow === false) { + _this.runLocalHooks('hide'); + } + }, DEFAULT_HIDE_DELAY); } /** - * beforeKeyDown callback. + * Responsible for showing comment after proper delay. * - * @private - * @param {Event} event + * @param {Object} range Coordinates of selected cell. */ }, { - key: 'onBeforeKeyDown', - value: function onBeforeKeyDown(event) { - var _this7 = this; + key: 'show', + value: function show(range) { + this.wasLastActionShow = true; + this.showDebounced(range); + } + }, { + key: 'cancelHiding', - if (!this.hot.getSelected()) { - return; - } - if (this.hot.getActiveEditor() && this.hot.getActiveEditor().isOpened()) { - return; - } - if ((0, _event.isImmediatePropagationStopped)(event)) { - return; - } - if (!this.textarea.isActive() && (0, _element.getSelectionText)()) { - return; - } - if ((0, _unicode.isCtrlKey)(event.keyCode)) { - // When fragmentSelection is enabled and some text is selected then don't blur selection calling 'setCopyableText' - if (this.hot.getSettings().fragmentSelection && (0, _element.getSelectionText)()) { - return; - } + /** + * Cancel hiding comment. + */ + value: function cancelHiding() { + this.wasLastActionShow = true; - // when CTRL is pressed, prepare selectable text in textarea - this.setCopyableText(); - (0, _event.stopImmediatePropagation)(event); + clearTimeout(this.hidingTimer); + this.hidingTimer = null; + } - return; - } + /** + * Update the switch settings. + * + * @param {Number} displayDelay Delay of showing the comments (in milliseconds). + */ - // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL) - var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; + }, { + key: 'updateDelay', + value: function updateDelay() { + var _this2 = this; - if (ctrlDown) { - if (event.keyCode == _unicode.KEY_CODES.A) { - setTimeout(function () { - _this7.setCopyableText(); - }, 0); - } - if (event.keyCode == _unicode.KEY_CODES.X) { - this.cut(); - } - if (event.keyCode == _unicode.KEY_CODES.C) { - this.copy(); - } - if (event.keyCode == _unicode.KEY_CODES.V) { - this.triggerPaste(); + var displayDelay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_DISPLAY_DELAY; + + this.showDebounced = (0, _function.debounce)(function (range) { + if (_this2.wasLastActionShow) { + _this2.runLocalHooks('show', range.from.row, range.from.col); } - } + }, displayDelay); } /** - * Destroy plugin instance. + * Destroy the switcher. */ }, { key: 'destroy', value: function destroy() { - if (this.textarea) { - this.textarea.destroy(); - } - - _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'destroy', this).call(this); + this.clearLocalHooks(); } }]); - return CopyPaste; -}(_base2.default); + return DisplaySwitch; +}(); -(0, _plugins.registerPlugin)('CopyPaste', CopyPaste); +(0, _object.mixin)(DisplaySwitch, _localHooks2.default); -exports.default = CopyPaste; +exports.default = DisplaySwitch; /***/ }), -/* 239 */ +/* 258 */ +/***/ (function(module, exports) { + +// removed by extract-text-webpack-plugin + +/***/ }), +/* 259 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55522,1379 +55416,1380 @@ exports.default = CopyPaste; exports.__esModule = true; +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _base = __webpack_require__(13); + +var _base2 = _interopRequireDefault(_base); + +var _pluginHooks = __webpack_require__(7); + +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + +var _array = __webpack_require__(2); + +var _commandExecutor = __webpack_require__(260); + +var _commandExecutor2 = _interopRequireDefault(_commandExecutor); + +var _eventManager = __webpack_require__(4); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +var _itemsFactory = __webpack_require__(261); + +var _itemsFactory2 = _interopRequireDefault(_itemsFactory); + +var _menu = __webpack_require__(273); + +var _menu2 = _interopRequireDefault(_menu); + +var _plugins = __webpack_require__(5); + +var _event = __webpack_require__(8); + +var _element = __webpack_require__(0); + +var _predefinedItems = __webpack_require__(88); + +__webpack_require__(275); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +_pluginHooks2.default.getSingleton().register('afterContextMenuDefaultOptions'); +_pluginHooks2.default.getSingleton().register('afterContextMenuShow'); +_pluginHooks2.default.getSingleton().register('afterContextMenuHide'); +_pluginHooks2.default.getSingleton().register('afterContextMenuExecute'); + /** - * @class Textarea + * @description + * This plugin creates the Handsontable Context Menu. It allows to create a new row or + * column at any place in the grid among [other features](http://docs.handsontable.com/demo-context-menu.html). + * Possible values: + * * `true` (to enable default options), + * * `false` (to disable completely) * - * @plugin CopyPaste + * or array of any available strings: + * * `["row_above", "row_below", "col_left", "col_right", + * "remove_row", "remove_col", "---------", "undo", "redo"]`. + * + * See [the context menu demo](http://docs.handsontable.com/demo-context-menu.html) for examples. + * + * @example + * ```js + * ... + * // as a boolean + * contextMenu: true + * ... + * // as a array + * contextMenu: ['row_above', 'row_below', '---------', 'undo', 'redo'] + * ... + * ``` + * + * @plugin ContextMenu */ -var Textarea = function () { - _createClass(Textarea, null, [{ - key: 'getSingleton', - value: function getSingleton() { - globalSingleton.append(); - return globalSingleton; +var ContextMenu = function (_BasePlugin) { + _inherits(ContextMenu, _BasePlugin); + + _createClass(ContextMenu, null, [{ + key: 'DEFAULT_ITEMS', + + /** + * Default menu items order when `contextMenu` is enabled by `true`. + * + * @returns {Array} + */ + get: function get() { + return [_predefinedItems.ROW_ABOVE, _predefinedItems.ROW_BELOW, _predefinedItems.SEPARATOR, _predefinedItems.COLUMN_LEFT, _predefinedItems.COLUMN_RIGHT, _predefinedItems.SEPARATOR, _predefinedItems.REMOVE_ROW, _predefinedItems.REMOVE_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.UNDO, _predefinedItems.REDO, _predefinedItems.SEPARATOR, _predefinedItems.READ_ONLY, _predefinedItems.SEPARATOR, _predefinedItems.ALIGNMENT]; } }]); - function Textarea() { - _classCallCheck(this, Textarea); + function ContextMenu(hotInstance) { + _classCallCheck(this, ContextMenu); /** - * Main textarea element. + * Instance of {@link EventManager}. * - * @type {HTMLElement} + * @type {EventManager} */ - this.element = void 0; + var _this = _possibleConstructorReturn(this, (ContextMenu.__proto__ || Object.getPrototypeOf(ContextMenu)).call(this, hotInstance)); + + _this.eventManager = new _eventManager2.default(_this); /** - * Store information about append to the document.body. + * Instance of {@link CommandExecutor}. * - * @type {Boolean} + * @type {CommandExecutor} */ - this.isAppended = false; + _this.commandExecutor = new _commandExecutor2.default(_this.hot); /** - * Reference counter. + * Instance of {@link ItemsFactory}. * - * @type {Number} + * @type {ItemsFactory} */ - this.refCounter = 0; + _this.itemsFactory = null; + /** + * Instance of {@link Menu}. + * + * @type {Menu} + */ + _this.menu = null; + return _this; } /** - * Apends textarea element to the `body` + * Check if the plugin is enabled in the Handsontable settings. + * + * @returns {Boolean} */ - _createClass(Textarea, [{ - key: 'append', - value: function append() { - if (this.hasBeenDestroyed()) { - this.create(); - } - - this.refCounter++; - - if (!this.isAppended && document.body) { - if (document.body) { - this.isAppended = true; - document.body.appendChild(this.element); - } - } + _createClass(ContextMenu, [{ + key: 'isEnabled', + value: function isEnabled() { + return this.hot.getSettings().contextMenu; } /** - * Prepares textarea element with proper attributes. + * Enable plugin for this Handsontable instance. */ }, { - key: 'create', - value: function create() { - this.element = document.createElement('textarea'); - this.element.id = 'HandsontableCopyPaste'; - this.element.className = 'copyPaste'; - this.element.tabIndex = -1; - this.element.autocomplete = 'off'; - this.element.wrap = 'off'; + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; + + if (this.enabled) { + return; + } + this.itemsFactory = new _itemsFactory2.default(this.hot, ContextMenu.DEFAULT_ITEMS); + + var settings = this.hot.getSettings().contextMenu; + var predefinedItems = { + items: this.itemsFactory.getItems(settings) + }; + this.registerEvents(); + + if (typeof settings.callback === 'function') { + this.commandExecutor.setCommonCallback(settings.callback); + } + _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'enablePlugin', this).call(this); + + this.callOnPluginsReady(function () { + _this2.hot.runHooks('afterContextMenuDefaultOptions', predefinedItems); + + _this2.itemsFactory.setPredefinedItems(predefinedItems.items); + var menuItems = _this2.itemsFactory.getItems(settings); + + _this2.menu = new _menu2.default(_this2.hot, { + className: 'htContextMenu', + keepInViewport: true + }); + _this2.hot.runHooks('beforeContextMenuSetItems', menuItems); + + _this2.menu.setMenuItems(menuItems); + + _this2.menu.addLocalHook('afterOpen', function () { + return _this2.onMenuAfterOpen(); + }); + _this2.menu.addLocalHook('afterClose', function () { + return _this2.onMenuAfterClose(); + }); + _this2.menu.addLocalHook('executeCommand', function () { + for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) { + params[_key] = arguments[_key]; + } + + return _this2.executeCommand.apply(_this2, params); + }); + + // Register all commands. Predefined and added by user or by plugins + (0, _array.arrayEach)(menuItems, function (command) { + return _this2.commandExecutor.registerCommand(command.key, command); + }); + }); } /** - * Deselects textarea element if is active. + * Updates the plugin to use the latest options you have specified. */ }, { - key: 'deselect', - value: function deselect() { - if (this.element === document.activeElement) { - document.activeElement.blur(); - } + key: 'updatePlugin', + value: function updatePlugin() { + this.disablePlugin(); + this.enablePlugin(); + + _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'updatePlugin', this).call(this); } /** - * Destroy instance + * Disable plugin for this Handsontable instance. */ }, { - key: 'destroy', - value: function destroy() { - this.refCounter--; - this.refCounter = this.refCounter < 0 ? 0 : this.refCounter; + key: 'disablePlugin', + value: function disablePlugin() { + this.close(); - if (this.hasBeenDestroyed() && this.element && this.element.parentNode) { - this.element.parentNode.removeChild(this.element); - this.element = null; - this.isAppended = false; + if (this.menu) { + this.menu.destroy(); + this.menu = null; } + _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'disablePlugin', this).call(this); } /** - * Getter for the element. + * Register dom listeners. * - * @returns {String} + * @private */ }, { - key: 'getValue', - value: function getValue() { - return this.element.value; + key: 'registerEvents', + value: function registerEvents() { + var _this3 = this; + + this.eventManager.addEventListener(this.hot.rootElement, 'contextmenu', function (event) { + return _this3.onContextMenu(event); + }); } /** - * Check if instance has been destroyed + * Open menu and re-position it based on dom event object. * - * @returns {Boolean} + * @param {Event} event The event object. */ }, { - key: 'hasBeenDestroyed', - value: function hasBeenDestroyed() { - return this.refCounter < 1; + key: 'open', + value: function open(event) { + if (!this.menu) { + return; + } + this.menu.open(); + this.menu.setPosition({ + top: parseInt((0, _event.pageY)(event), 10) - (0, _element.getWindowScrollTop)(), + left: parseInt((0, _event.pageX)(event), 10) - (0, _element.getWindowScrollLeft)() + }); + + // ContextMenu is not detected HotTableEnv correctly because is injected outside hot-table + this.menu.hotMenu.isHotTableEnv = this.hot.isHotTableEnv; + // Handsontable.eventManager.isHotTableEnv = this.hot.isHotTableEnv; } /** - * Check if the element is an active element in frame. - * - * @returns {Boolean} + * Close menu. */ }, { - key: 'isActive', - value: function isActive() { - return this.element === document.activeElement; + key: 'close', + value: function close() { + if (!this.menu) { + return; + } + this.menu.close(); } /** - * Sets focus on the element and select content. + * Execute context menu command. + * + * You can execute all predefined commands: + * * `'row_above'` - Insert row above + * * `'row_below'` - Insert row below + * * `'col_left'` - Insert column on the left + * * `'col_right'` - Insert column on the right + * * `'clear_column'` - Clear selected column + * * `'remove_row'` - Remove row + * * `'remove_col'` - Remove column + * * `'undo'` - Undo last action + * * `'redo'` - Redo last action + * * `'make_read_only'` - Make cell read only + * * `'alignment:left'` - Alignment to the left + * * `'alignment:top'` - Alignment to the top + * * `'alignment:right'` - Alignment to the right + * * `'alignment:bottom'` - Alignment to the bottom + * * `'alignment:middle'` - Alignment to the middle + * * `'alignment:center'` - Alignment to the center (justify) + * + * Or you can execute command registered in settings where `key` is your command name. + * + * @param {String} commandName + * @param {*} params */ }, { - key: 'select', - value: function select() { - this.element.focus(); - this.element.select(); + key: 'executeCommand', + value: function executeCommand() { + for (var _len2 = arguments.length, params = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + params[_key2] = arguments[_key2]; + } + + this.commandExecutor.execute.apply(this.commandExecutor, params); } /** - * Setter for the element. + * On context menu listener. * - * @param {String} data Value which should be insert into the element. + * @private + * @param {Event} event */ }, { - key: 'setValue', - value: function setValue(data) { - this.element.value = data; - } - }]); - - return Textarea; -}(); - -var globalSingleton = new Textarea(); - -exports.default = Textarea; - -/***/ }), -/* 240 */ -/***/ (function(module, exports, __webpack_require__) { + key: 'onContextMenu', + value: function onContextMenu(event) { + var settings = this.hot.getSettings(); + var showRowHeaders = settings.rowHeaders; + var showColHeaders = settings.colHeaders; -"use strict"; + function isValidElement(element) { + return element.nodeName === 'TD' || element.parentNode.nodeName === 'TD'; + } + // if event is from hot-table we must get web component element not element inside him + var element = event.realTarget; + this.close(); + if ((0, _element.hasClass)(element, 'handsontableInput')) { + return; + } -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + event.preventDefault(); + (0, _event.stopPropagation)(event); -var _pluginHooks = __webpack_require__(8); + if (!(showRowHeaders || showColHeaders)) { + if (!isValidElement(element) && !((0, _element.hasClass)(element, 'current') && (0, _element.hasClass)(element, 'wtBorder'))) { + return; + } + } -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + this.open(event); + } -var _plugins = __webpack_require__(5); + /** + * On menu after open listener. + * + * @private + */ -var _object = __webpack_require__(1); + }, { + key: 'onMenuAfterOpen', + value: function onMenuAfterOpen() { + this.hot.runHooks('afterContextMenuShow', this); + } -var _src = __webpack_require__(11); + /** + * On menu after close listener. + * + * @private + */ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + }, { + key: 'onMenuAfterClose', + value: function onMenuAfterClose() { + this.hot.listen(); + this.hot.runHooks('afterContextMenuHide', this); + } -function CustomBorders() {} -/** * - * Current instance (table where borders should be placed) - */ -var instance; + /** + * Destroy instance. + */ -/** - * This plugin enables an option to apply custom borders through the context menu (configurable with context menu key `borders`). - * - * To initialize Handsontable with predefined custom borders, provide cell coordinates and border styles in a form of an array. - * - * See [Custom Borders](http://docs.handsontable.com/demo-custom-borders.html) demo for more examples. - * - * @example - * ```js - * ... - * customBorders: [ - * {range: { - * from: {row: 1, col: 1}, - * to: {row: 3, col: 4}}, - * left: {}, - * right: {}, - * top: {}, - * bottom: {} - * } - * ], - * ... - * - * // or - * ... - * customBorders: [ - * {row: 2, col: 2, left: {width: 2, color: 'red'}, - * right: {width: 1, color: 'green'}, top: '', bottom: ''} - * ], - * ... - * ``` - * @private - * @class CustomBorders - * @plugin CustomBorders - */ + }, { + key: 'destroy', + value: function destroy() { + this.close(); -/** * - * Check if plugin should be enabled. - */ -var checkEnable = function checkEnable(customBorders) { - if (typeof customBorders === 'boolean') { - if (customBorders === true) { - return true; - } - } - if ((typeof customBorders === 'undefined' ? 'undefined' : _typeof(customBorders)) === 'object') { - if (customBorders.length > 0) { - return true; + if (this.menu) { + this.menu.destroy(); + } + _get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'destroy', this).call(this); } - } + }]); + + return ContextMenu; +}(_base2.default); - return false; +ContextMenu.SEPARATOR = { + name: _predefinedItems.SEPARATOR }; -/** * - * Initialize plugin. - */ -var init = function init() { - if (checkEnable(this.getSettings().customBorders)) { - if (!this.customBorders) { - instance = this; - this.customBorders = new CustomBorders(); - } - } -}; +(0, _plugins.registerPlugin)('contextMenu', ContextMenu); -/** * - * Get index of border from the settings. - * - * @param {String} className - * @returns {Number} - */ -var getSettingIndex = function getSettingIndex(className) { - for (var i = 0; i < instance.view.wt.selections.length; i++) { - if (instance.view.wt.selections[i].settings.className == className) { - return i; - } - } +exports.default = ContextMenu; - return -1; -}; +/***/ }), +/* 260 */ +/***/ (function(module, exports, __webpack_require__) { -/** * - * Insert WalkontableSelection instance into Walkontable settings. - * - * @param border - */ -var insertBorderIntoSettings = function insertBorderIntoSettings(border) { - var coordinates = { - row: border.row, - col: border.col - }; - var selection = new _src.Selection(border, new _src.CellRange(coordinates, coordinates, coordinates)); - var index = getSettingIndex(border.className); +"use strict"; - if (index >= 0) { - instance.view.wt.selections[index] = selection; - } else { - instance.view.wt.selections.push(selection); - } -}; -/** * - * Prepare borders from setting (single cell). - * - * @param {Number} row Visual row index. - * @param {Number} col Visual column index. - * @param borderObj - */ -var prepareBorderFromCustomAdded = function prepareBorderFromCustomAdded(row, col, borderObj) { - var border = createEmptyBorders(row, col); - border = extendDefaultBorder(border, borderObj); - this.setCellMeta(row, col, 'borders', border); +exports.__esModule = true; - insertBorderIntoSettings(border); -}; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -/** * - * Prepare borders from setting (object). +var _array = __webpack_require__(2); + +var _object = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Command executor for ContextMenu. * - * @param {Object} rowObj + * @class CommandExecutor + * @plugin ContextMenu */ -var prepareBorderFromCustomAddedRange = function prepareBorderFromCustomAddedRange(rowObj) { - var range = rowObj.range; +var CommandExecutor = function () { + function CommandExecutor(hotInstance) { + _classCallCheck(this, CommandExecutor); - for (var row = range.from.row; row <= range.to.row; row++) { - for (var col = range.from.col; col <= range.to.col; col++) { - var border = createEmptyBorders(row, col); - var add = 0; + this.hot = hotInstance; + this.commands = {}; + this.commonCallback = null; + } - if (row == range.from.row) { - add++; + /** + * Register command. + * + * @param {String} name Command name. + * @param {Object} commandDescriptor Command descriptor object with properties like `key` (command id), + * `callback` (task to execute), `name` (command name), `disabled` (command availability). + */ - if ((0, _object.hasOwnProperty)(rowObj, 'top')) { - border.top = rowObj.top; - } - } - if (row == range.to.row) { - add++; + _createClass(CommandExecutor, [{ + key: 'registerCommand', + value: function registerCommand(name, commandDescriptor) { + this.commands[name] = commandDescriptor; + } - if ((0, _object.hasOwnProperty)(rowObj, 'bottom')) { - border.bottom = rowObj.bottom; - } - } + /** + * Set common callback which will be trigger on every executed command. + * + * @param {Function} callback Function which will be fired on every command execute. + */ - if (col == range.from.col) { - add++; + }, { + key: 'setCommonCallback', + value: function setCommonCallback(callback) { + this.commonCallback = callback; + } - if ((0, _object.hasOwnProperty)(rowObj, 'left')) { - border.left = rowObj.left; - } + /** + * Execute command by its name. + * + * @param {String} commandName Command id. + * @param {*} params Arguments passed to command task. + */ + + }, { + key: 'execute', + value: function execute(commandName) { + var _this = this; + + for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + params[_key - 1] = arguments[_key]; } - if (col == range.to.col) { - add++; + var commandSplit = commandName.split(':'); + commandName = commandSplit[0]; - if ((0, _object.hasOwnProperty)(rowObj, 'right')) { - border.right = rowObj.right; - } + var subCommandName = commandSplit.length === 2 ? commandSplit[1] : null; + var command = this.commands[commandName]; + + if (!command) { + throw new Error('Menu command \'' + commandName + '\' not exists.'); } + if (subCommandName && command.submenu) { + command = findSubCommand(subCommandName, command.submenu.items); + } + if (command.disabled === true) { + return; + } + if (typeof command.disabled == 'function' && command.disabled.call(this.hot) === true) { + return; + } + if ((0, _object.hasOwnProperty)(command, 'submenu')) { + return; + } + var callbacks = []; - if (add > 0) { - this.setCellMeta(row, col, 'borders', border); - insertBorderIntoSettings(border); + if (typeof command.callback === 'function') { + callbacks.push(command.callback); + } + if (typeof this.commonCallback === 'function') { + callbacks.push(this.commonCallback); } + params.unshift(commandSplit.join(':')); + (0, _array.arrayEach)(callbacks, function (callback) { + return callback.apply(_this.hot, params); + }); } - } -}; + }]); -/** * - * Create separated class name for borders for each cell. - * - * @param {Number} row Visual row index. - * @param {Number} col Visual column index. - * @returns {String} - */ -var createClassName = function createClassName(row, col) { - return 'border_row' + row + 'col' + col; -}; + return CommandExecutor; +}(); -/** * - * Create default single border for each position (top/right/bottom/left). - * - * @returns {Object} `{{width: number, color: string}}` - */ -var createDefaultCustomBorder = function createDefaultCustomBorder() { - return { - width: 1, - color: '#000' - }; -}; +function findSubCommand(subCommandName, subCommands) { + var command = void 0; -/** * - * Create default object for empty border. - * - * @returns {Object} `{{hide: boolean}}` - */ -var createSingleEmptyBorder = function createSingleEmptyBorder() { - return { - hide: true - }; -}; + (0, _array.arrayEach)(subCommands, function (cmd) { + var cmds = cmd.key ? cmd.key.split(':') : null; -/** * - * Create default Handsontable border object. - * - * @returns {Object} `{{width: number, color: string, cornerVisible: boolean}}` - */ -var createDefaultHtBorder = function createDefaultHtBorder() { - return { - width: 1, - color: '#000', - cornerVisible: false - }; -}; + if (Array.isArray(cmds) && cmds[1] === subCommandName) { + command = cmd; -/** * - * Prepare empty border for each cell with all custom borders hidden. - * - * @param {Number} row Visual row index. - * @param {Number} col Visual column index. - * @returns {Object} `{{className: *, border: *, row: *, col: *, top: {hide: boolean}, right: {hide: boolean}, bottom: {hide: boolean}, left: {hide: boolean}}}` - */ -var createEmptyBorders = function createEmptyBorders(row, col) { - return { - className: createClassName(row, col), - border: createDefaultHtBorder(), - row: row, - col: col, - top: createSingleEmptyBorder(), - right: createSingleEmptyBorder(), - bottom: createSingleEmptyBorder(), - left: createSingleEmptyBorder() - }; -}; + return false; + } + }); -var extendDefaultBorder = function extendDefaultBorder(defaultBorder, customBorder) { - if ((0, _object.hasOwnProperty)(customBorder, 'border')) { - defaultBorder.border = customBorder.border; - } + return command; +} - if ((0, _object.hasOwnProperty)(customBorder, 'top')) { - defaultBorder.top = customBorder.top; - } +exports.default = CommandExecutor; - if ((0, _object.hasOwnProperty)(customBorder, 'right')) { - defaultBorder.right = customBorder.right; - } +/***/ }), +/* 261 */ +/***/ (function(module, exports, __webpack_require__) { - if ((0, _object.hasOwnProperty)(customBorder, 'bottom')) { - defaultBorder.bottom = customBorder.bottom; - } +"use strict"; - if ((0, _object.hasOwnProperty)(customBorder, 'left')) { - defaultBorder.left = customBorder.left; - } - return defaultBorder; -}; +exports.__esModule = true; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _object = __webpack_require__(1); + +var _array = __webpack_require__(2); + +var _predefinedItems = __webpack_require__(88); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** - * Remove borders divs from DOM. + * Predefined items class factory for menu items. * - * @param borderClassName + * @class ItemsFactory + * @plugin ContextMenu */ -var removeBordersFromDom = function removeBordersFromDom(borderClassName) { - var borders = document.querySelectorAll('.' + borderClassName); +var ItemsFactory = function () { + function ItemsFactory(hotInstance) { + var orderPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - for (var i = 0; i < borders.length; i++) { - if (borders[i]) { - if (borders[i].nodeName != 'TD') { - var parent = borders[i].parentNode; + _classCallCheck(this, ItemsFactory); - if (parent.parentNode) { - parent.parentNode.removeChild(parent); - } - } - } + this.hot = hotInstance; + this.predefinedItems = (0, _predefinedItems.predefinedItems)(); + this.defaultOrderPattern = orderPattern; } -}; -/** * - * Remove border (triggered from context menu). - * - * @param {Number} row Visual row index. - * @param {Number} col Visual column index. - */ -var removeAllBorders = function removeAllBorders(row, col) { - var borderClassName = createClassName(row, col); - removeBordersFromDom(borderClassName); - this.removeCellMeta(row, col, 'borders'); -}; + /** + * Set predefined items. + * + * @param {Array} predefinedItems Array of predefined items. + */ -/** * - * Set borders for each cell re. to border position - * - * @param row Visual row index. - * @param col Visual column index. - * @param place - * @param remove - */ -var setBorder = function setBorder(row, col, place, remove) { - var bordersMeta = this.getCellMeta(row, col).borders; + _createClass(ItemsFactory, [{ + key: 'setPredefinedItems', + value: function setPredefinedItems(predefinedItems) { + var _this = this; - if (!bordersMeta || bordersMeta.border == undefined) { - bordersMeta = createEmptyBorders(row, col); - } + var items = {}; - if (remove) { - bordersMeta[place] = createSingleEmptyBorder(); - } else { - bordersMeta[place] = createDefaultCustomBorder(); - } + this.defaultOrderPattern.length = 0; - this.setCellMeta(row, col, 'borders', bordersMeta); + (0, _object.objectEach)(predefinedItems, function (value, key) { + var menuItemKey = ''; - var borderClassName = createClassName(row, col); - removeBordersFromDom(borderClassName); - insertBorderIntoSettings(bordersMeta); + if (value.name === _predefinedItems.SEPARATOR) { + items[_predefinedItems.SEPARATOR] = value; + menuItemKey = _predefinedItems.SEPARATOR; - this.render(); -}; + // Menu item added as a property to array + } else if (isNaN(parseInt(key, 10))) { + value.key = value.key === void 0 ? key : value.key; + items[key] = value; + menuItemKey = value.key; + } else { + items[value.key] = value; + menuItemKey = value.key; + } + _this.defaultOrderPattern.push(menuItemKey); + }); + this.predefinedItems = items; + } -/** * - * Prepare borders based on cell and border position - * - * @param range - * @param place - * @param remove - */ -var prepareBorder = function prepareBorder(range, place, remove) { + /** + * Get all menu items based on pattern. + * + * @param {Array|Object|Boolean} pattern Pattern which you can define by displaying menu items order. If `true` default + * pattern will be used. + * @returns {Array} + */ - if (range.from.row == range.to.row && range.from.col == range.to.col) { - if (place == 'noBorders') { - removeAllBorders.call(this, range.from.row, range.from.col); - } else { - setBorder.call(this, range.from.row, range.from.col, place, remove); + }, { + key: 'getItems', + value: function getItems() { + var pattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + return _getItems(pattern, this.defaultOrderPattern, this.predefinedItems); } + }]); + + return ItemsFactory; +}(); + +function _getItems() { + var pattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var defaultPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var items = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + var result = []; + + if (pattern && pattern.items) { + pattern = pattern.items; + } else if (!Array.isArray(pattern)) { + pattern = defaultPattern; + } + if ((0, _object.isObject)(pattern)) { + (0, _object.objectEach)(pattern, function (value, key) { + var item = items[typeof value === 'string' ? value : key]; + + if (!item) { + item = value; + } + if ((0, _object.isObject)(value)) { + (0, _object.extend)(item, value); + } else if (typeof item === 'string') { + item = { name: item }; + } + if (item.key === void 0) { + item.key = key; + } + result.push(item); + }); } else { - switch (place) { - case 'noBorders': - for (var column = range.from.col; column <= range.to.col; column++) { - for (var row = range.from.row; row <= range.to.row; row++) { - removeAllBorders.call(this, row, column); - } - } - break; - case 'top': - for (var topCol = range.from.col; topCol <= range.to.col; topCol++) { - setBorder.call(this, range.from.row, topCol, place, remove); - } - break; - case 'right': - for (var rowRight = range.from.row; rowRight <= range.to.row; rowRight++) { - setBorder.call(this, rowRight, range.to.col, place); - } - break; - case 'bottom': - for (var bottomCol = range.from.col; bottomCol <= range.to.col; bottomCol++) { - setBorder.call(this, range.to.row, bottomCol, place); - } - break; - case 'left': - for (var rowLeft = range.from.row; rowLeft <= range.to.row; rowLeft++) { - setBorder.call(this, rowLeft, range.from.col, place); - } - break; - default: - break; - } + (0, _array.arrayEach)(pattern, function (name, key) { + var item = items[name]; + + // Item deleted from settings `allowInsertRow: false` etc. + if (!item && _predefinedItems.ITEMS.indexOf(name) >= 0) { + return; + } + if (!item) { + item = { name: name, key: '' + key }; + } + if ((0, _object.isObject)(name)) { + (0, _object.extend)(item, name); + } + if (item.key === void 0) { + item.key = key; + } + result.push(item); + }); } -}; -/** * - * Check if selection has border by className - * - * @param hot - * @param direction - */ -var checkSelectionBorders = function checkSelectionBorders(hot, direction) { - var atLeastOneHasBorder = false; + return result; +} + +exports.default = ItemsFactory; + +/***/ }), +/* 262 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; - hot.getSelectedRange().forAll(function (r, c) { - var metaBorders = hot.getCellMeta(r, c).borders; - if (metaBorders) { - if (direction) { - if (!(0, _object.hasOwnProperty)(metaBorders[direction], 'hide')) { - atLeastOneHasBorder = true; - return false; // breaks forAll - } - } else { - atLeastOneHasBorder = true; - return false; // breaks forAll - } - } - }); - return atLeastOneHasBorder; -}; +exports.__esModule = true; +exports.KEY = undefined; +exports.default = alignmentItem; -/** * - * Mark label in contextMenu as selected - * - * @param label - * @returns {string} - */ -var markSelected = function markSelected(label) { - return '' + String.fromCharCode(10003) + '' + label; // workaround for https://github.com/handsontable/handsontable/issues/1946 -}; +var _utils = __webpack_require__(19); -/** * - * Add border options to context menu - * - * @param defaultOptions - */ -var addBordersOptionsToContextMenu = function addBordersOptionsToContextMenu(defaultOptions) { - if (!this.getSettings().customBorders) { - return; - } +var _separator = __webpack_require__(86); - defaultOptions.items.push({ - name: '---------' - }); - defaultOptions.items.push({ - key: 'borders', - name: 'Borders', +var KEY = exports.KEY = 'alignment'; + +function alignmentItem() { + return { + key: KEY, + name: 'Alignment', disabled: function disabled() { - return this.selection.selectedHeader.corner; + return !(this.getSelectedRange() && !this.selection.selectedHeader.corner); }, submenu: { items: [{ - key: 'borders:top', + key: KEY + ':left', name: function name() { - var label = 'Top'; - var hasBorder = checkSelectionBorders(this, 'top'); - if (hasBorder) { - label = markSelected(label); - } + var _this = this; - return label; - }, - callback: function callback() { - var hasBorder = checkSelectionBorders(this, 'top'); - prepareBorder.call(this, this.getSelectedRange(), 'top', hasBorder); - } - }, { - key: 'borders:right', - name: function name() { - var label = 'Right'; - var hasBorder = checkSelectionBorders(this, 'right'); - if (hasBorder) { - label = markSelected(label); - } - return label; - }, - callback: function callback() { - var hasBorder = checkSelectionBorders(this, 'right'); - prepareBorder.call(this, this.getSelectedRange(), 'right', hasBorder); - } - }, { - key: 'borders:bottom', - name: function name() { - var label = 'Bottom'; - var hasBorder = checkSelectionBorders(this, 'bottom'); - if (hasBorder) { - label = markSelected(label); - } - return label; - }, - callback: function callback() { - var hasBorder = checkSelectionBorders(this, 'bottom'); - prepareBorder.call(this, this.getSelectedRange(), 'bottom', hasBorder); - } - }, { - key: 'borders:left', - name: function name() { var label = 'Left'; - var hasBorder = checkSelectionBorders(this, 'left'); - if (hasBorder) { - label = markSelected(label); + var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var className = _this.getCellMeta(row, col).className; + + if (className && className.indexOf('htLeft') !== -1) { + return true; + } + }); + + if (hasClass) { + label = (0, _utils.markLabelAsSelected)(label); } return label; }, callback: function callback() { - var hasBorder = checkSelectionBorders(this, 'left'); - prepareBorder.call(this, this.getSelectedRange(), 'left', hasBorder); - } - }, { - key: 'borders:no_borders', - name: 'Remove border(s)', - callback: function callback() { - prepareBorder.call(this, this.getSelectedRange(), 'noBorders'); - }, - disabled: function disabled() { - return !checkSelectionBorders(this); - } - }] - } - }); -}; - -_pluginHooks2.default.getSingleton().add('beforeInit', init); -_pluginHooks2.default.getSingleton().add('afterContextMenuDefaultOptions', addBordersOptionsToContextMenu); -_pluginHooks2.default.getSingleton().add('afterInit', function () { - var customBorders = this.getSettings().customBorders; - - if (customBorders) { - for (var i = 0; i < customBorders.length; i++) { - if (customBorders[i].range) { - prepareBorderFromCustomAddedRange.call(this, customBorders[i]); - } else { - prepareBorderFromCustomAdded.call(this, customBorders[i].row, customBorders[i].col, customBorders[i]); - } - } - - this.render(); - this.view.wt.draw(true); - } -}); - -/***/ }), -/* 241 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + var _this2 = this; + var range = this.getSelectedRange(); + var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { + return _this2.getCellMeta(row, col).className; + }); + var type = 'horizontal'; + var alignment = 'htLeft'; -exports.__esModule = true; + this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); + (0, _utils.align)(range, type, alignment, function (row, col) { + return _this2.getCellMeta(row, col); + }, function (row, col, key, value) { + return _this2.setCellMeta(row, col, key, value); + }); + this.render(); + }, -var _pluginHooks = __webpack_require__(8); + disabled: false + }, { + key: KEY + ':center', + name: function name() { + var _this3 = this; -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + var label = 'Center'; + var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var className = _this3.getCellMeta(row, col).className; -var _eventManager = __webpack_require__(4); + if (className && className.indexOf('htCenter') !== -1) { + return true; + } + }); -var _eventManager2 = _interopRequireDefault(_eventManager); + if (hasClass) { + label = (0, _utils.markLabelAsSelected)(label); + } -var _plugins = __webpack_require__(5); + return label; + }, + callback: function callback() { + var _this4 = this; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + var range = this.getSelectedRange(); + var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { + return _this4.getCellMeta(row, col).className; + }); + var type = 'horizontal'; + var alignment = 'htCenter'; -/** - * @description - * Plugin used to scroll Handsontable by selecting a cell and dragging outside of the visible viewport. - * - * @private - * @class DragToScroll - * @plugin DragToScroll - */ -function DragToScroll() { - this.boundaries = null; - this.callback = null; -} + this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); + (0, _utils.align)(range, type, alignment, function (row, col) { + return _this4.getCellMeta(row, col); + }, function (row, col, key, value) { + return _this4.setCellMeta(row, col, key, value); + }); + this.render(); + }, -/** - * @param boundaries {Object} compatible with getBoundingClientRect - */ -DragToScroll.prototype.setBoundaries = function (boundaries) { - this.boundaries = boundaries; -}; + disabled: false + }, { + key: KEY + ':right', + name: function name() { + var _this5 = this; -/** - * @param callback {Function} - */ -DragToScroll.prototype.setCallback = function (callback) { - this.callback = callback; -}; + var label = 'Right'; + var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var className = _this5.getCellMeta(row, col).className; -/** - * Check if mouse position (x, y) is outside of the viewport - * @param x - * @param y - */ -DragToScroll.prototype.check = function (x, y) { - var diffX = 0; - var diffY = 0; + if (className && className.indexOf('htRight') !== -1) { + return true; + } + }); - if (y < this.boundaries.top) { - // y is less than top - diffY = y - this.boundaries.top; - } else if (y > this.boundaries.bottom) { - // y is more than bottom - diffY = y - this.boundaries.bottom; - } + if (hasClass) { + label = (0, _utils.markLabelAsSelected)(label); + } - if (x < this.boundaries.left) { - // x is less than left - diffX = x - this.boundaries.left; - } else if (x > this.boundaries.right) { - // x is more than right - diffX = x - this.boundaries.right; - } + return label; + }, + callback: function callback() { + var _this6 = this; - this.callback(diffX, diffY); -}; + var range = this.getSelectedRange(); + var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { + return _this6.getCellMeta(row, col).className; + }); + var type = 'horizontal'; + var alignment = 'htRight'; -var dragToScroll; -var instance; + this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); + (0, _utils.align)(range, type, alignment, function (row, col) { + return _this6.getCellMeta(row, col); + }, function (row, col, key, value) { + return _this6.setCellMeta(row, col, key, value); + }); + this.render(); + }, -var setupListening = function setupListening(instance) { - instance.dragToScrollListening = false; - var scrollHandler = instance.view.wt.wtTable.holder; // native scroll - dragToScroll = new DragToScroll(); + disabled: false + }, { + key: KEY + ':justify', + name: function name() { + var _this7 = this; - if (scrollHandler === window) { - // not much we can do currently - return; - } + var label = 'Justify'; + var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var className = _this7.getCellMeta(row, col).className; - dragToScroll.setBoundaries(scrollHandler.getBoundingClientRect()); - dragToScroll.setCallback(function (scrollX, scrollY) { - if (scrollX < 0) { - scrollHandler.scrollLeft -= 50; - } else if (scrollX > 0) { - scrollHandler.scrollLeft += 50; - } + if (className && className.indexOf('htJustify') !== -1) { + return true; + } + }); - if (scrollY < 0) { - scrollHandler.scrollTop -= 20; - } else if (scrollY > 0) { - scrollHandler.scrollTop += 20; - } - }); + if (hasClass) { + label = (0, _utils.markLabelAsSelected)(label); + } - instance.dragToScrollListening = true; -}; + return label; + }, + callback: function callback() { + var _this8 = this; -_pluginHooks2.default.getSingleton().add('afterInit', function () { - var instance = this; - var eventManager = new _eventManager2.default(this); + var range = this.getSelectedRange(); + var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { + return _this8.getCellMeta(row, col).className; + }); + var type = 'horizontal'; + var alignment = 'htJustify'; - eventManager.addEventListener(document, 'mouseup', function () { - instance.dragToScrollListening = false; - }); + this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); + (0, _utils.align)(range, type, alignment, function (row, col) { + return _this8.getCellMeta(row, col); + }, function (row, col, key, value) { + return _this8.setCellMeta(row, col, key, value); + }); + this.render(); + }, - eventManager.addEventListener(document, 'mousemove', function (event) { - if (instance.dragToScrollListening) { - dragToScroll.check(event.clientX, event.clientY); - } - }); -}); + disabled: false + }, { + name: _separator.KEY + }, { + key: KEY + ':top', + name: function name() { + var _this9 = this; -_pluginHooks2.default.getSingleton().add('afterDestroy', function () { - new _eventManager2.default(this).clear(); -}); + var label = 'Top'; + var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var className = _this9.getCellMeta(row, col).className; -_pluginHooks2.default.getSingleton().add('afterOnCellMouseDown', function () { - setupListening(this); -}); + if (className && className.indexOf('htTop') !== -1) { + return true; + } + }); -_pluginHooks2.default.getSingleton().add('afterOnCellCornerMouseDown', function () { - setupListening(this); -}); + if (hasClass) { + label = (0, _utils.markLabelAsSelected)(label); + } + return label; + }, + callback: function callback() { + var _this10 = this; -exports.default = DragToScroll; + var range = this.getSelectedRange(); + var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { + return _this10.getCellMeta(row, col).className; + }); + var type = 'vertical'; + var alignment = 'htTop'; -/***/ }), -/* 242 */ -/***/ (function(module, exports, __webpack_require__) { + this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); + (0, _utils.align)(range, type, alignment, function (row, col) { + return _this10.getCellMeta(row, col); + }, function (row, col, key, value) { + return _this10.setCellMeta(row, col, key, value); + }); + this.render(); + }, -"use strict"; + disabled: false + }, { + key: KEY + ':middle', + name: function name() { + var _this11 = this; + var label = 'Middle'; + var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var className = _this11.getCellMeta(row, col).className; -exports.__esModule = true; -exports.default = freezeColumnItem; -function freezeColumnItem(manualColumnFreezePlugin) { - return { - key: 'freeze_column', - name: 'Freeze this column', - callback: function callback() { - var selectedColumn = this.getSelectedRange().from.col; + if (className && className.indexOf('htMiddle') !== -1) { + return true; + } + }); - manualColumnFreezePlugin.freezeColumn(selectedColumn); + if (hasClass) { + label = (0, _utils.markLabelAsSelected)(label); + } - this.render(); - this.view.wt.wtOverlays.adjustElementsSize(true); - }, - hidden: function hidden() { - var selection = this.getSelectedRange(); - var hide = false; + return label; + }, + callback: function callback() { + var _this12 = this; - if (selection === void 0) { - hide = true; - } else if (selection.from.col !== selection.to.col || selection.from.col <= this.getSettings().fixedColumnsLeft - 1) { - hide = true; - } + var range = this.getSelectedRange(); + var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { + return _this12.getCellMeta(row, col).className; + }); + var type = 'vertical'; + var alignment = 'htMiddle'; - return hide; - } - }; -} + this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); + (0, _utils.align)(range, type, alignment, function (row, col) { + return _this12.getCellMeta(row, col); + }, function (row, col, key, value) { + return _this12.setCellMeta(row, col, key, value); + }); + this.render(); + }, -/***/ }), -/* 243 */ -/***/ (function(module, exports, __webpack_require__) { + disabled: false + }, { + key: KEY + ':bottom', + name: function name() { + var _this13 = this; -"use strict"; + var label = 'Bottom'; + var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + var className = _this13.getCellMeta(row, col).className; + if (className && className.indexOf('htBottom') !== -1) { + return true; + } + }); -exports.__esModule = true; -exports.default = unfreezeColumnItem; -function unfreezeColumnItem(manualColumnFreezePlugin) { - return { - key: 'unfreeze_column', - name: 'Unfreeze this column', - callback: function callback() { - var selectedColumn = this.getSelectedRange().from.col; + if (hasClass) { + label = (0, _utils.markLabelAsSelected)(label); + } - manualColumnFreezePlugin.unfreezeColumn(selectedColumn); + return label; + }, + callback: function callback() { + var _this14 = this; - this.render(); - this.view.wt.wtOverlays.adjustElementsSize(true); - }, - hidden: function hidden() { - var selection = this.getSelectedRange(); - var hide = false; + var range = this.getSelectedRange(); + var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) { + return _this14.getCellMeta(row, col).className; + }); + var type = 'vertical'; + var alignment = 'htBottom'; - if (selection === void 0) { - hide = true; - } else if (selection.from.col !== selection.to.col || selection.from.col >= this.getSettings().fixedColumnsLeft) { - hide = true; - } + this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment); + (0, _utils.align)(range, type, alignment, function (row, col) { + return _this14.getCellMeta(row, col); + }, function (row, col, key, value) { + return _this14.setCellMeta(row, col, key, value); + }); + this.render(); + }, - return hide; + disabled: false + }] } }; } /***/ }), -/* 244 */ +/* 263 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; +exports.KEY = undefined; +exports.default = clearColumnItem; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; +var _utils = __webpack_require__(19); -var _base = __webpack_require__(12); +var KEY = exports.KEY = 'clear_column'; -var _base2 = _interopRequireDefault(_base); +function clearColumnItem() { + return { + key: KEY, + name: 'Clear column', -var _plugins = __webpack_require__(5); + callback: function callback(key, selection) { + var column = selection.start.col; -var _array = __webpack_require__(2); + if (this.countRows()) { + this.populateFromArray(0, column, [[null]], Math.max(selection.start.row, selection.end.row), column, 'ContextMenu.clearColumn'); + } + }, + disabled: function disabled() { + var selected = (0, _utils.getValidSelection)(this); -var _freezeColumn = __webpack_require__(242); + if (!selected) { + return true; + } + var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1]; + var rowSelected = entireRowSelection.join(',') == selected.join(','); -var _freezeColumn2 = _interopRequireDefault(_freezeColumn); + return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || rowSelected; + } + }; +} -var _unfreezeColumn = __webpack_require__(243); +/***/ }), +/* 264 */ +/***/ (function(module, exports, __webpack_require__) { -var _unfreezeColumn2 = _interopRequireDefault(_unfreezeColumn); +"use strict"; -__webpack_require__(301); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +exports.__esModule = true; +exports.KEY = undefined; +exports.default = columnLeftItem; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var _utils = __webpack_require__(19); -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +var KEY = exports.KEY = 'col_left'; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +function columnLeftItem() { + return { + key: KEY, + name: 'Insert column on the left', + callback: function callback(key, selection) { + this.alter('insert_col', selection.start.col, 1, 'ContextMenu.columnLeft'); + }, + disabled: function disabled() { + var selected = (0, _utils.getValidSelection)(this); -var privatePool = new WeakMap(); -/** - * This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu. - * You can turn it on by setting a `manualColumnFreeze` property to `true`. - * - * @plugin ManualColumnFreeze - * @dependencies ManualColumnMove - */ + if (!selected) { + return true; + } + if (!this.isColumnModificationAllowed()) { + return true; + } + var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1]; + var rowSelected = entireRowSelection.join(',') == selected.join(','); + var onlyOneColumn = this.countCols() === 1; -var ManualColumnFreeze = function (_BasePlugin) { - _inherits(ManualColumnFreeze, _BasePlugin); + return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected; + }, + hidden: function hidden() { + return !this.getSettings().allowInsertColumn; + } + }; +} - function ManualColumnFreeze(hotInstance) { - _classCallCheck(this, ManualColumnFreeze); +/***/ }), +/* 265 */ +/***/ (function(module, exports, __webpack_require__) { - var _this = _possibleConstructorReturn(this, (ManualColumnFreeze.__proto__ || Object.getPrototypeOf(ManualColumnFreeze)).call(this, hotInstance)); +"use strict"; - privatePool.set(_this, { - moveByFreeze: false, - afterFirstUse: false - }); - /** - * Original column positions - * - * @type {Array} - */ - _this.frozenColumnsBasePositions = []; - /** - * Reference to the `ManualColumnMove` plugin. - */ - _this.manualColumnMovePlugin = void 0; - return _this; - } - /** - * Check if the plugin is enabled in the Handsontable settings. - * - * @returns {Boolean} - */ +exports.__esModule = true; +exports.KEY = undefined; +exports.default = columnRightItem; +var _utils = __webpack_require__(19); - _createClass(ManualColumnFreeze, [{ - key: 'isEnabled', - value: function isEnabled() { - return !!this.hot.getSettings().manualColumnFreeze; - } +var KEY = exports.KEY = 'col_right'; - /** - * Enable plugin for this Handsontable instance. - */ +function columnRightItem() { + return { + key: KEY, + name: 'Insert column on the right', - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + callback: function callback(key, selection) { + this.alter('insert_col', selection.end.col + 1, 1, 'ContextMenu.columnRight'); + }, + disabled: function disabled() { + var selected = (0, _utils.getValidSelection)(this); - if (this.enabled) { - return; + if (!selected) { + return true; } + if (!this.isColumnModificationAllowed()) { + return true; + } + var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1]; + var rowSelected = entireRowSelection.join(',') == selected.join(','); + var onlyOneColumn = this.countCols() === 1; - this.addHook('afterContextMenuDefaultOptions', function (options) { - return _this2.addContextMenuEntry(options); - }); - this.addHook('afterInit', function () { - return _this2.onAfterInit(); - }); - this.addHook('beforeColumnMove', function (rows, target) { - return _this2.onBeforeColumnMove(rows, target); - }); - - _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'enablePlugin', this).call(this); + return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected; + }, + hidden: function hidden() { + return !this.getSettings().allowInsertColumn; } + }; +} - /** - * Disable plugin for this Handsontable instance. - */ - - }, { - key: 'disablePlugin', - value: function disablePlugin() { - var priv = privatePool.get(this); - - priv.afterFirstUse = false; - priv.moveByFreeze = false; +/***/ }), +/* 266 */ +/***/ (function(module, exports, __webpack_require__) { - _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'disablePlugin', this).call(this); - } +"use strict"; - /** - * Updates the plugin to use the latest options you have specified. - */ - }, { - key: 'updatePlugin', - value: function updatePlugin() { - this.disablePlugin(); - this.enablePlugin(); +exports.__esModule = true; +exports.KEY = undefined; +exports.default = readOnlyItem; - _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'updatePlugin', this).call(this); - } +var _utils = __webpack_require__(19); - /** - * Freeze the given column (add it to fixed columns). - * - * @param {Number} column Visual column index. - */ +var KEY = exports.KEY = 'make_read_only'; - }, { - key: 'freezeColumn', - value: function freezeColumn(column) { - var priv = privatePool.get(this); - var settings = this.hot.getSettings(); +function readOnlyItem() { + return { + key: KEY, + name: function name() { + var _this = this; - if (!priv.afterFirstUse) { - priv.afterFirstUse = true; - } + var label = 'Read only'; + var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) { + return _this.getCellMeta(row, col).readOnly; + }); - if (settings.fixedColumnsLeft === this.hot.countCols() || column <= settings.fixedColumnsLeft - 1) { - return; // already fixed + if (atLeastOneReadOnly) { + label = (0, _utils.markLabelAsSelected)(label); } - priv.moveByFreeze = true; + return label; + }, + callback: function callback() { + var _this2 = this; - if (column !== this.getMovePlugin().columnsMapper.getValueByIndex(column)) { - this.frozenColumnsBasePositions[settings.fixedColumnsLeft] = column; - } + var range = this.getSelectedRange(); + var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(range, function (row, col) { + return _this2.getCellMeta(row, col).readOnly; + }); - this.getMovePlugin().moveColumn(column, settings.fixedColumnsLeft++); + range.forAll(function (row, col) { + _this2.setCellMeta(row, col, 'readOnly', !atLeastOneReadOnly); + }); + this.render(); + }, + disabled: function disabled() { + return !(this.getSelectedRange() && !this.selection.selectedHeader.corner); } + }; +} - /** - * Unfreeze the given column (remove it from fixed columns and bring to it's previous position). - * - * @param {Number} column Visual column index. - */ - - }, { - key: 'unfreezeColumn', - value: function unfreezeColumn(column) { - var priv = privatePool.get(this); - var settings = this.hot.getSettings(); +/***/ }), +/* 267 */ +/***/ (function(module, exports, __webpack_require__) { - if (!priv.afterFirstUse) { - priv.afterFirstUse = true; - } +"use strict"; - if (settings.fixedColumnsLeft <= 0 || column > settings.fixedColumnsLeft - 1) { - return; // not fixed - } - var returnCol = this.getBestColumnReturnPosition(column); +exports.__esModule = true; +exports.default = redoItem; +var KEY = exports.KEY = 'redo'; - priv.moveByFreeze = true; - settings.fixedColumnsLeft--; +function redoItem() { + return { + key: KEY, + name: 'Redo', - this.getMovePlugin().moveColumn(column, returnCol + 1); + callback: function callback() { + this.redo(); + }, + disabled: function disabled() { + return this.undoRedo && !this.undoRedo.isRedoAvailable(); } + }; +} - /** - * Get the reference to the ManualColumnMove plugin. - * - * @private - * @returns {Object} - */ +/***/ }), +/* 268 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'getMovePlugin', - value: function getMovePlugin() { - if (!this.manualColumnMovePlugin) { - this.manualColumnMovePlugin = this.hot.getPlugin('manualColumnMove'); - } +"use strict"; - return this.manualColumnMovePlugin; - } - /** - * Estimates the most fitting return position for unfrozen column. - * - * @private - * @param {Number} column Visual column index. - */ +exports.__esModule = true; +exports.KEY = undefined; +exports.default = removeColumnItem; - }, { - key: 'getBestColumnReturnPosition', - value: function getBestColumnReturnPosition(column) { - var movePlugin = this.getMovePlugin(); - var settings = this.hot.getSettings(); - var i = settings.fixedColumnsLeft; - var j = movePlugin.columnsMapper.getValueByIndex(i); - var initialCol = void 0; +var _utils = __webpack_require__(19); - if (this.frozenColumnsBasePositions[column] == null) { - initialCol = movePlugin.columnsMapper.getValueByIndex(column); +var KEY = exports.KEY = 'remove_col'; - while (j < initialCol) { - i++; - j = movePlugin.columnsMapper.getValueByIndex(i); - } - } else { - initialCol = this.frozenColumnsBasePositions[column]; - this.frozenColumnsBasePositions[column] = void 0; +function removeColumnItem() { + return { + key: KEY, + name: 'Remove column', - while (j <= initialCol) { - i++; - j = movePlugin.columnsMapper.getValueByIndex(i); - } - i = j; - } + callback: function callback(key, selection) { + var amount = selection.end.col - selection.start.col + 1; - return i - 1; - } - /** - * Add the manualColumnFreeze context menu entries. - * - * @private - * @param {Object} options Context menu options. - */ + this.alter('remove_col', selection.start.col, amount, 'ContextMenu.removeColumn'); + }, + disabled: function disabled() { + var selected = (0, _utils.getValidSelection)(this); + var totalColumns = this.countCols(); - }, { - key: 'addContextMenuEntry', - value: function addContextMenuEntry(options) { - options.items.push({ name: '---------' }, (0, _freezeColumn2.default)(this), (0, _unfreezeColumn2.default)(this)); + return !selected || this.selection.selectedHeader.rows || this.selection.selectedHeader.corner || !this.isColumnModificationAllowed() || !totalColumns; + }, + hidden: function hidden() { + return !this.getSettings().allowRemoveColumn; } + }; +} - /** - * Enabling `manualColumnMove` plugin on `afterInit` hook. - * - * @private - */ +/***/ }), +/* 269 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'onAfterInit', - value: function onAfterInit() { - if (!this.getMovePlugin().isEnabled()) { - this.getMovePlugin().enablePlugin(); - } - } +"use strict"; - /** - * Prevent moving the rows from/to fixed area. - * - * @private - * @param {Array} rows - * @param {Number} target - */ - }, { - key: 'onBeforeColumnMove', - value: function onBeforeColumnMove(rows, target) { - var priv = privatePool.get(this); +exports.__esModule = true; +exports.KEY = undefined; +exports.default = removeRowItem; - if (priv.afterFirstUse && !priv.moveByFreeze) { - var frozenLen = this.hot.getSettings().fixedColumnsLeft; - var disallowMoving = target < frozenLen; +var _utils = __webpack_require__(19); - if (!disallowMoving) { - (0, _array.arrayEach)(rows, function (value, index, array) { - if (value < frozenLen) { - disallowMoving = true; - return false; - } - }); - } +var KEY = exports.KEY = 'remove_row'; - if (disallowMoving) { - return false; - } - } +function removeRowItem() { + return { + key: KEY, + name: 'Remove row', - if (priv.moveByFreeze) { - priv.moveByFreeze = false; - } - } + callback: function callback(key, selection) { + var amount = selection.end.row - selection.start.row + 1; - /** - * Destroy plugin instance. - */ + this.alter('remove_row', selection.start.row, amount, 'ContextMenu.removeRow'); + }, + disabled: function disabled() { + var selected = (0, _utils.getValidSelection)(this); + var totalRows = this.countRows(); - }, { - key: 'destroy', - value: function destroy() { - _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'destroy', this).call(this); + return !selected || this.selection.selectedHeader.cols || this.selection.selectedHeader.corner || !totalRows; + }, + hidden: function hidden() { + return !this.getSettings().allowRemoveRow; } - }]); - - return ManualColumnFreeze; -}(_base2.default); - -(0, _plugins.registerPlugin)('manualColumnFreeze', ManualColumnFreeze); - -exports.default = ManualColumnFreeze; + }; +} /***/ }), -/* 245 */ +/* 270 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; +exports.KEY = undefined; +exports.default = rowAboveItem; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _arrayMapper = __webpack_require__(151); - -var _arrayMapper2 = _interopRequireDefault(_arrayMapper); - -var _array = __webpack_require__(2); - -var _object = __webpack_require__(1); - -var _number = __webpack_require__(6); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _utils = __webpack_require__(19); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var KEY = exports.KEY = 'row_above'; -/** - * @class ColumnsMapper - * @plugin ManualColumnMove - */ -var ColumnsMapper = function () { - function ColumnsMapper(manualColumnMove) { - _classCallCheck(this, ColumnsMapper); +function rowAboveItem() { + return { + key: KEY, + name: 'Insert row above', - /** - * Instance of ManualColumnMove plugin. - * - * @type {ManualColumnMove} - */ - this.manualColumnMove = manualColumnMove; - } + callback: function callback(key, selection) { + this.alter('insert_row', selection.start.row, 1, 'ContextMenu.rowAbove'); + }, + disabled: function disabled() { + var selected = (0, _utils.getValidSelection)(this); - /** - * Reset current map array and create new one. - * - * @param {Number} [length] Custom generated map length. - */ + return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows; + }, + hidden: function hidden() { + return !this.getSettings().allowInsertRow; + } + }; +} +/***/ }), +/* 271 */ +/***/ (function(module, exports, __webpack_require__) { - _createClass(ColumnsMapper, [{ - key: 'createMap', - value: function createMap(length) { - var _this = this; +"use strict"; - var originLength = length === void 0 ? this._arrayMap.length : length; - this._arrayMap.length = 0; +exports.__esModule = true; +exports.KEY = undefined; +exports.default = rowBelowItem; - (0, _number.rangeEach)(originLength - 1, function (itemIndex) { - _this._arrayMap[itemIndex] = itemIndex; - }); - } +var _utils = __webpack_require__(19); - /** - * Destroy class. - */ +var KEY = exports.KEY = 'row_below'; - }, { - key: 'destroy', - value: function destroy() { - this._arrayMap = null; - } +function rowBelowItem() { + return { + key: KEY, + name: 'Insert row below', - /** - * Moving elements in columnsMapper. - * - * @param {Number} from Column index to move. - * @param {Number} to Target index. - */ + callback: function callback(key, selection) { + this.alter('insert_row', selection.end.row + 1, 1, 'ContextMenu.rowBelow'); + }, + disabled: function disabled() { + var selected = (0, _utils.getValidSelection)(this); - }, { - key: 'moveColumn', - value: function moveColumn(from, to) { - var indexToMove = this._arrayMap[from]; - this._arrayMap[from] = null; - this._arrayMap.splice(to, 0, indexToMove); + return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows; + }, + hidden: function hidden() { + return !this.getSettings().allowInsertRow; } + }; +} - /** - * Clearing arrayMap from `null` entries. - */ +/***/ }), +/* 272 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'clearNull', - value: function clearNull() { - this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) { - return i !== null; - }); - } - }]); +"use strict"; - return ColumnsMapper; -}(); -(0, _object.mixin)(ColumnsMapper, _arrayMapper2.default); +exports.__esModule = true; +exports.default = undoItem; +var KEY = exports.KEY = 'undo'; -exports.default = ColumnsMapper; +function undoItem() { + return { + key: KEY, + name: 'Undo', + + callback: function callback() { + this.undo(); + }, + disabled: function disabled() { + return this.undoRedo && !this.undoRedo.isUndoAvailable(); + } + }; +} /***/ }), -/* 246 */ +/* 273 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56904,906 +56799,854 @@ exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _base = __webpack_require__(12); - -var _base2 = _interopRequireDefault(_base); +var _core = __webpack_require__(82); -var _pluginHooks = __webpack_require__(8); +var _core2 = _interopRequireDefault(_core); -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); +var _element = __webpack_require__(0); var _array = __webpack_require__(2); -var _element = __webpack_require__(0); +var _cursor = __webpack_require__(274); -var _number = __webpack_require__(6); +var _cursor2 = _interopRequireDefault(_cursor); var _eventManager = __webpack_require__(4); var _eventManager2 = _interopRequireDefault(_eventManager); -var _plugins = __webpack_require__(5); - -var _columnsMapper = __webpack_require__(245); +var _object = __webpack_require__(1); -var _columnsMapper2 = _interopRequireDefault(_columnsMapper); +var _function = __webpack_require__(35); -var _backlight = __webpack_require__(247); +var _utils = __webpack_require__(19); -var _backlight2 = _interopRequireDefault(_backlight); +var _unicode = __webpack_require__(17); -var _guideline = __webpack_require__(248); +var _localHooks = __webpack_require__(87); -var _guideline2 = _interopRequireDefault(_guideline); +var _localHooks2 = _interopRequireDefault(_localHooks); -var _src = __webpack_require__(11); +var _predefinedItems = __webpack_require__(88); -__webpack_require__(302); +var _event = __webpack_require__(8); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -_pluginHooks2.default.getSingleton().register('beforeColumnMove'); -_pluginHooks2.default.getSingleton().register('afterColumnMove'); -_pluginHooks2.default.getSingleton().register('unmodifyCol'); - -var privatePool = new WeakMap(); -var CSS_PLUGIN = 'ht__manualColumnMove'; -var CSS_SHOW_UI = 'show-ui'; -var CSS_ON_MOVING = 'on-moving--columns'; -var CSS_AFTER_SELECTION = 'after-selection--columns'; - /** - * @plugin ManualColumnMove - * - * @description - * This plugin allows to change columns order. - * - * API: - * - moveColumn - move single column to the new position. - * - moveColumns - move many columns (as an array of indexes) to the new position. - * - * If you want apply visual changes, you have to call manually the render() method on the instance of Handsontable. - * - * UI components: - * - backlight - highlight of selected columns. - * - guideline - line which shows where rows has been moved. - * - * @class ManualColumnMove - * @plugin ManualColumnMove + * @class Menu + * @plugin ContextMenu */ +var Menu = function () { + function Menu(hotInstance, options) { + _classCallCheck(this, Menu); -var ManualColumnMove = function (_BasePlugin) { - _inherits(ManualColumnMove, _BasePlugin); - - function ManualColumnMove(hotInstance) { - _classCallCheck(this, ManualColumnMove); - - /** - * Set up WeakMap of plugin to sharing private parameters; - */ - var _this = _possibleConstructorReturn(this, (ManualColumnMove.__proto__ || Object.getPrototypeOf(ManualColumnMove)).call(this, hotInstance)); + this.hot = hotInstance; + this.options = options || { + parent: null, + name: null, + className: '', + keepInViewport: true, + standalone: false + }; + this.eventManager = new _eventManager2.default(this); + this.container = this.createContainer(this.options.name); + this.hotMenu = null; + this.hotSubMenus = {}; + this.parentMenu = this.options.parent || null; + this.menuItems = null; + this.origOutsideClickDeselects = null; + this.keyEvent = false; - privatePool.set(_this, { - columnsToMove: [], - countCols: 0, - fixedColumns: 0, - pressed: void 0, - disallowMoving: void 0, - target: { - eventPageX: void 0, - coords: void 0, - TD: void 0, - col: void 0 - } - }); + this.offset = { + above: 0, + below: 0, + left: 0, + right: 0 + }; + this._afterScrollCallback = null; - /** - * List of last removed row indexes. - * - * @type {Array} - */ - _this.removedColumns = []; - /** - * Object containing visual row indexes mapped to data source indexes. - * - * @type {RowsMapper} - */ - _this.columnsMapper = new _columnsMapper2.default(_this); - /** - * Event Manager object. - * - * @type {Object} - */ - _this.eventManager = new _eventManager2.default(_this); - /** - * Backlight UI object. - * - * @type {Object} - */ - _this.backlight = new _backlight2.default(hotInstance); - /** - * Guideline UI object. - * - * @type {Object} - */ - _this.guideline = new _guideline2.default(hotInstance); - return _this; + this.registerEvents(); } /** - * Check if plugin is enabled. + * Register event listeners. * - * @returns {Boolean} + * @private */ - _createClass(ManualColumnMove, [{ - key: 'isEnabled', - value: function isEnabled() { - return !!this.hot.getSettings().manualColumnMove; - } - - /** - * Enable the plugin. - */ - - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; - - if (this.enabled) { - return; - } + _createClass(Menu, [{ + key: 'registerEvents', + value: function registerEvents() { + var _this = this; - this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) { - return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations); - }); - this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) { - return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations); - }); - this.addHook('afterScrollVertically', function () { - return _this2.onAfterScrollVertically(); - }); - this.addHook('modifyCol', function (row, source) { - return _this2.onModifyCol(row, source); - }); - this.addHook('beforeRemoveCol', function (index, amount) { - return _this2.onBeforeRemoveCol(index, amount); - }); - this.addHook('afterRemoveCol', function (index, amount) { - return _this2.onAfterRemoveCol(index, amount); - }); - this.addHook('afterCreateCol', function (index, amount) { - return _this2.onAfterCreateCol(index, amount); - }); - this.addHook('afterLoadData', function (firstTime) { - return _this2.onAfterLoadData(firstTime); - }); - this.addHook('unmodifyCol', function (column) { - return _this2.onUnmodifyCol(column); + this.eventManager.addEventListener(document.documentElement, 'mousedown', function (event) { + return _this.onDocumentMouseDown(event); }); - - this.registerEvents(); - - // TODO: move adding plugin classname to BasePlugin. - (0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN); - - _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'enablePlugin', this).call(this); } /** - * Updates the plugin to use the latest options you have specified. + * Set array of objects which defines menu items. + * + * @param {Array} menuItems Menu items to display. */ }, { - key: 'updatePlugin', - value: function updatePlugin() { - this.disablePlugin(); - this.enablePlugin(); - - this.onAfterPluginsInitialized(); - - _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'updatePlugin', this).call(this); + key: 'setMenuItems', + value: function setMenuItems(menuItems) { + this.menuItems = menuItems; } /** - * Disable plugin for this Handsontable instance. + * Set offset menu position for specified area (`above`, `below`, `left` or `right`). + * + * @param {String} area Specified area name (`above`, `below`, `left` or `right`). + * @param {Number} offset Offset value. */ }, { - key: 'disablePlugin', - value: function disablePlugin() { - var pluginSettings = this.hot.getSettings().manualColumnMove; - - if (Array.isArray(pluginSettings)) { - this.columnsMapper.clearMap(); - } - - (0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN); - - this.unregisterEvents(); - this.backlight.destroy(); - this.guideline.destroy(); + key: 'setOffset', + value: function setOffset(area) { + var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'disablePlugin', this).call(this); + this.offset[area] = offset; } /** - * Move a single column. + * Check if menu is using as sub-menu. * - * @param {Number} column Visual column index to be moved. - * @param {Number} target Visual column index being a target for the moved column. + * @returns {Boolean} */ }, { - key: 'moveColumn', - value: function moveColumn(column, target) { - this.moveColumns([column], target); + key: 'isSubMenu', + value: function isSubMenu() { + return this.parentMenu !== null; } /** - * Move multiple columns. - * - * @param {Array} columns Array of visual column indexes to be moved. - * @param {Number} target Visual column index being a target for the moved columns. + * Open menu. */ }, { - key: 'moveColumns', - value: function moveColumns(columns, target) { - var _this3 = this; + key: 'open', + value: function open() { + var _this2 = this; - var priv = privatePool.get(this); - var beforeColumnHook = this.hot.runHooks('beforeColumnMove', columns, target); + this.container.removeAttribute('style'); + this.container.style.display = 'block'; - priv.disallowMoving = !beforeColumnHook; + var delayedOpenSubMenu = (0, _function.debounce)(function (row) { + return _this2.openSubMenu(row); + }, 300); - if (beforeColumnHook !== false) { - // first we need to rewrite an visual indexes to physical for save reference after move - (0, _array.arrayEach)(columns, function (column, index, array) { - array[index] = _this3.columnsMapper.getValueByIndex(column); - }); + var filteredItems = (0, _array.arrayFilter)(this.menuItems, function (item) { + return (0, _utils.isItemHidden)(item, _this2.hot); + }); - // next, when we have got an physical indexes, we can move columns - (0, _array.arrayEach)(columns, function (column, index) { - var actualPosition = _this3.columnsMapper.getIndexByValue(column); + filteredItems = (0, _utils.filterSeparators)(filteredItems, _predefinedItems.SEPARATOR); - if (actualPosition !== target) { - _this3.columnsMapper.moveColumn(actualPosition, target + index); + var settings = { + data: filteredItems, + colHeaders: false, + colWidths: [200], + autoRowSize: false, + readOnly: true, + copyPaste: false, + columns: [{ + data: 'name', + renderer: function renderer(hot, TD, row, col, prop, value) { + return _this2.menuItemRenderer(hot, TD, row, col, prop, value); } - }); - - // after moving we have to clear columnsMapper from null entries - this.columnsMapper.clearNull(); - } - - this.hot.runHooks('afterColumnMove', columns, target); + }], + renderAllRows: true, + fragmentSelection: 'cell', + disableVisualSelection: 'area', + beforeKeyDown: function beforeKeyDown(event) { + return _this2.onBeforeKeyDown(event); + }, + afterOnCellMouseOver: function afterOnCellMouseOver(event, coords, TD) { + if (_this2.isAllSubMenusClosed()) { + delayedOpenSubMenu(coords.row); + } else { + _this2.openSubMenu(coords.row); + } + }, + rowHeights: function rowHeights(row) { + return filteredItems[row].name === _predefinedItems.SEPARATOR ? 1 : 23; + } + }; + this.origOutsideClickDeselects = this.hot.getSettings().outsideClickDeselects; + this.hot.getSettings().outsideClickDeselects = false; + this.hotMenu = new _core2.default(this.container, settings); + this.hotMenu.addHook('afterInit', function () { + return _this2.onAfterInit(); + }); + this.hotMenu.addHook('afterSelection', function (r, c, r2, c2, preventScrolling) { + return _this2.onAfterSelection(r, c, r2, c2, preventScrolling); + }); + this.hotMenu.init(); + this.hotMenu.listen(); + this.blockMainTableCallbacks(); + this.runLocalHooks('afterOpen'); } /** - * Correct the cell selection after the move action. Fired only when action was made with a mouse. - * That means that changing the column order using the API won't correct the selection. + * Close menu. * - * @private - * @param {Number} startColumn Visual column index for the start of the selection. - * @param {Number} endColumn Visual column index for the end of the selection. + * @param {Boolean} [closeParent=false] if `true` try to close parent menu if exists. */ }, { - key: 'changeSelection', - value: function changeSelection(startColumn, endColumn) { - var selection = this.hot.selection; - var lastRowIndex = this.hot.countRows() - 1; + key: 'close', + value: function close() { + var closeParent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - selection.setRangeStartOnly(new _src.CellCoords(0, startColumn)); - selection.setRangeEnd(new _src.CellCoords(lastRowIndex, endColumn), false); + if (!this.isOpened()) { + return; + } + if (closeParent && this.parentMenu) { + this.parentMenu.close(); + } else { + this.closeAllSubMenus(); + this.container.style.display = 'none'; + this.releaseMainTableCallbacks(); + this.hotMenu.destroy(); + this.hotMenu = null; + this.hot.getSettings().outsideClickDeselects = this.origOutsideClickDeselects; + this.runLocalHooks('afterClose'); + + if (this.parentMenu) { + this.parentMenu.hotMenu.listen(); + } + } } /** - * Get the sum of the widths of columns in the provided range. + * Open sub menu at the provided row index. * - * @private - * @param {Number} from Visual column index. - * @param {Number} to Visual column index. - * @returns {Number} + * @param {Number} row Row index. + * @returns {Menu|Boolean} Returns created menu or `false` if no one menu was created. */ }, { - key: 'getColumnsWidth', - value: function getColumnsWidth(from, to) { - var width = 0; - - for (var i = from; i < to; i++) { - var columnWidth = 0; + key: 'openSubMenu', + value: function openSubMenu(row) { + if (!this.hotMenu) { + return false; + } + var cell = this.hotMenu.getCell(row, 0); - if (i < 0) { - columnWidth = this.hot.view.wt.wtTable.getColumnWidth(i) || 0; - } else { - columnWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(i) || 0; - } + this.closeAllSubMenus(); - width += columnWidth; + if (!cell || !(0, _utils.hasSubMenu)(cell)) { + return false; } + var dataItem = this.hotMenu.getSourceDataAtRow(row); + var subMenu = new Menu(this.hot, { + parent: this, + name: dataItem.name, + className: this.options.className, + keepInViewport: true + }); + subMenu.setMenuItems(dataItem.submenu.items); + subMenu.open(); + subMenu.setPosition(cell.getBoundingClientRect()); + this.hotSubMenus[dataItem.key] = subMenu; - return width; + return subMenu; } /** - * Load initial settings when persistent state is saved or when plugin was initialized as an array. + * Close sub menu at row index. * - * @private + * @param {Number} row Row index. */ }, { - key: 'initialSettings', - value: function initialSettings() { - var pluginSettings = this.hot.getSettings().manualColumnMove; + key: 'closeSubMenu', + value: function closeSubMenu(row) { + var dataItem = this.hotMenu.getSourceDataAtRow(row); + var menus = this.hotSubMenus[dataItem.key]; - if (Array.isArray(pluginSettings)) { - this.moveColumns(pluginSettings, 0); - } else if (pluginSettings !== void 0) { - this.persistentStateLoad(); + if (menus) { + menus.destroy(); + delete this.hotSubMenus[dataItem.key]; } } /** - * Check if the provided column is in the fixedColumnsLeft section. - * - * @private - * @param {Number} column Visual column index to check. - * @returns {Boolean} + * Close all opened sub menus. */ }, { - key: 'isFixedColumnsLeft', - value: function isFixedColumnsLeft(column) { - return column < this.hot.getSettings().fixedColumnsLeft; + key: 'closeAllSubMenus', + value: function closeAllSubMenus() { + var _this3 = this; + + (0, _array.arrayEach)(this.hotMenu.getData(), function (value, row) { + return _this3.closeSubMenu(row); + }); } /** - * Save the manual column positions to the persistent state. + * Checks if all created and opened sub menus are closed. * - * @private + * @returns {Boolean} */ }, { - key: 'persistentStateSave', - value: function persistentStateSave() { - this.hot.runHooks('persistentStateSave', 'manualColumnMove', this.columnsMapper._arrayMap); + key: 'isAllSubMenusClosed', + value: function isAllSubMenusClosed() { + return Object.keys(this.hotSubMenus).length === 0; } /** - * Load the manual column positions from the persistent state. - * - * @private + * Destroy instance. */ }, { - key: 'persistentStateLoad', - value: function persistentStateLoad() { - var storedState = {}; - - this.hot.runHooks('persistentStateLoad', 'manualColumnMove', storedState); - - if (storedState.value) { - this.columnsMapper._arrayMap = storedState.value; - } + key: 'destroy', + value: function destroy() { + this.clearLocalHooks(); + this.close(); + this.parentMenu = null; + this.eventManager.destroy(); } /** - * Prepare array of indexes based on actual selection. + * Checks if menu was opened. * - * @private - * @returns {Array} + * @returns {Boolean} Returns `true` if menu was opened. */ }, { - key: 'prepareColumnsToMoving', - value: function prepareColumnsToMoving(start, end) { - var selectedColumns = []; - - (0, _number.rangeEach)(start, end, function (i) { - selectedColumns.push(i); - }); - - return selectedColumns; + key: 'isOpened', + value: function isOpened() { + return this.hotMenu !== null; } /** - * Update the UI visual position. + * Execute menu command. * - * @private + * @param {Event} [event] */ }, { - key: 'refreshPositions', - value: function refreshPositions() { - var priv = privatePool.get(this); - var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleColumn(); - var lastVisible = this.hot.view.wt.wtTable.getLastVisibleColumn(); - var wtTable = this.hot.view.wt.wtTable; - var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement; - var scrollLeft = typeof scrollableElement.scrollX === 'number' ? scrollableElement.scrollX : scrollableElement.scrollLeft; - var tdOffsetLeft = this.hot.view.THEAD.offsetLeft + this.getColumnsWidth(0, priv.coordsColumn); - var mouseOffsetLeft = priv.target.eventPageX - (priv.rootElementOffset - (scrollableElement.scrollX === void 0 ? scrollLeft : 0)); - var hiderWidth = wtTable.hider.offsetWidth; - var tbodyOffsetLeft = wtTable.TBODY.offsetLeft; - var backlightElemMarginLeft = this.backlight.getOffset().left; - var backlightElemWidth = this.backlight.getSize().width; - var rowHeaderWidth = 0; - - if (priv.rootElementOffset + wtTable.holder.offsetWidth + scrollLeft < priv.target.eventPageX) { - if (priv.coordsColumn < priv.countCols) { - priv.coordsColumn++; - } - } - - if (priv.hasRowHeaders) { - rowHeaderWidth = this.hot.view.wt.wtOverlays.leftOverlay.clone.wtTable.getColumnHeader(-1).offsetWidth; - } - if (this.isFixedColumnsLeft(priv.coordsColumn)) { - tdOffsetLeft += scrollLeft; + key: 'executeCommand', + value: function executeCommand(event) { + if (!this.isOpened() || !this.hotMenu.getSelected()) { + return; } - tdOffsetLeft += rowHeaderWidth; - - if (priv.coordsColumn < 0) { - // if hover on rowHeader - if (priv.fixedColumns > 0) { - priv.target.col = 0; - } else { - priv.target.col = firstVisible > 0 ? firstVisible - 1 : firstVisible; - } - } else if (priv.target.TD.offsetWidth / 2 + tdOffsetLeft <= mouseOffsetLeft) { - var newCoordsCol = priv.coordsColumn >= priv.countCols ? priv.countCols - 1 : priv.coordsColumn; - // if hover on right part of TD - priv.target.col = newCoordsCol + 1; - // unfortunately first column is bigger than rest - tdOffsetLeft += priv.target.TD.offsetWidth; + var selectedItem = this.hotMenu.getSourceDataAtRow(this.hotMenu.getSelected()[0]); - if (priv.target.col > lastVisible) { - this.hot.scrollViewportTo(void 0, lastVisible + 1, void 0, true); - } - } else { - // elsewhere on table - priv.target.col = priv.coordsColumn; + this.runLocalHooks('select', selectedItem, event); - if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns) { - this.hot.scrollViewportTo(void 0, firstVisible - 1); - } + if (selectedItem.isCommand === false || selectedItem.name === _predefinedItems.SEPARATOR) { + return; } + var selRange = this.hot.getSelectedRange(); + var normalizedSelection = selRange ? (0, _utils.normalizeSelection)(selRange) : {}; + var autoClose = true; - if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns) { - this.hot.scrollViewportTo(void 0, firstVisible - 1); + // Don't close context menu if item is disabled or it has submenu + if (selectedItem.disabled === true || typeof selectedItem.disabled === 'function' && selectedItem.disabled.call(this.hot) === true || selectedItem.submenu) { + autoClose = false; } - var backlightLeft = mouseOffsetLeft; - var guidelineLeft = tdOffsetLeft; + this.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event); - if (mouseOffsetLeft + backlightElemWidth + backlightElemMarginLeft >= hiderWidth) { - // prevent display backlight on the right side of the table - backlightLeft = hiderWidth - backlightElemWidth - backlightElemMarginLeft; - } else if (mouseOffsetLeft + backlightElemMarginLeft < tbodyOffsetLeft + rowHeaderWidth) { - // prevent display backlight on the left side of the table - backlightLeft = tbodyOffsetLeft + rowHeaderWidth + Math.abs(backlightElemMarginLeft); + if (this.isSubMenu()) { + this.parentMenu.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event); } - if (tdOffsetLeft >= hiderWidth - 1) { - // prevent display guideline outside the table - guidelineLeft = hiderWidth - 1; - } else if (guidelineLeft === 0) { - // guideline has got `margin-left: -1px` as default - guidelineLeft = 1; - } else if (scrollableElement.scrollX !== void 0 && priv.coordsColumn < priv.fixedColumns) { - guidelineLeft -= priv.rootElementOffset <= scrollableElement.scrollX ? priv.rootElementOffset : 0; + if (autoClose) { + this.close(true); } - - this.backlight.setPosition(null, backlightLeft); - this.guideline.setPosition(null, guidelineLeft); } /** - * This method checks arrayMap from columnsMapper and updates the columnsMapper if it's necessary. + * Set menu position based on dom event or based on literal object. * - * @private + * @param {Event|Object} coords Event or literal Object with coordinates. */ }, { - key: 'updateColumnsMapper', - value: function updateColumnsMapper() { - var countCols = this.hot.countSourceCols(); - var columnsMapperLen = this.columnsMapper._arrayMap.length; - - if (columnsMapperLen === 0) { - this.columnsMapper.createMap(countCols || this.hot.getSettings().startCols); - } else if (columnsMapperLen < countCols) { - var diff = countCols - columnsMapperLen; - - this.columnsMapper.insertItems(columnsMapperLen, diff); - } else if (columnsMapperLen > countCols) { - var maxIndex = countCols - 1; - var columnsToRemove = []; - - (0, _array.arrayEach)(this.columnsMapper._arrayMap, function (value, index, array) { - if (value > maxIndex) { - columnsToRemove.push(index); - } - }); + key: 'setPosition', + value: function setPosition(coords) { + var cursor = new _cursor2.default(coords); - this.columnsMapper.removeItems(columnsToRemove); + if (this.options.keepInViewport) { + if (cursor.fitsBelow(this.container)) { + this.setPositionBelowCursor(cursor); + } else if (cursor.fitsAbove(this.container)) { + this.setPositionAboveCursor(cursor); + } else { + this.setPositionBelowCursor(cursor); + } + if (cursor.fitsOnRight(this.container)) { + this.setPositionOnRightOfCursor(cursor); + } else { + this.setPositionOnLeftOfCursor(cursor); + } + } else { + this.setPositionBelowCursor(cursor); + this.setPositionOnRightOfCursor(cursor); } } /** - * Bind the events used by the plugin. + * Set menu position above cursor object. * - * @private + * @param {Cursor} cursor `Cursor` object. */ }, { - key: 'registerEvents', - value: function registerEvents() { - var _this4 = this; + key: 'setPositionAboveCursor', + value: function setPositionAboveCursor(cursor) { + var top = this.offset.above + cursor.top - this.container.offsetHeight; - this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) { - return _this4.onMouseMove(event); - }); - this.eventManager.addEventListener(document.documentElement, 'mouseup', function () { - return _this4.onMouseUp(); - }); + if (this.isSubMenu()) { + top = cursor.top + cursor.cellHeight - this.container.offsetHeight + 3; + } + this.container.style.top = top + 'px'; } /** - * Unbind the events used by the plugin. + * Set menu position below cursor object. * - * @private + * @param {Cursor} cursor `Cursor` object. */ }, { - key: 'unregisterEvents', - value: function unregisterEvents() { - this.eventManager.clear(); + key: 'setPositionBelowCursor', + value: function setPositionBelowCursor(cursor) { + var top = this.offset.below + cursor.top; + + if (this.isSubMenu()) { + top = cursor.top - 1; + } + this.container.style.top = top + 'px'; } /** - * Change the behavior of selection / dragging. + * Set menu position on the right of cursor object. * - * @private - * @param {MouseEvent} event `mousedown` event properties. - * @param {CellCoords} coords Visual cell coordinates where was fired event. - * @param {HTMLElement} TD Cell represented as HTMLElement. - * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells. + * @param {Cursor} cursor `Cursor` object. */ }, { - key: 'onBeforeOnCellMouseDown', - value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) { - var wtTable = this.hot.view.wt.wtTable; - var isHeaderSelection = this.hot.selection.selectedHeader.cols; - var selection = this.hot.getSelectedRange(); - var priv = privatePool.get(this); - var isSortingElement = event.realTarget.className.indexOf('columnSorting') > -1; - - if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0 || isSortingElement) { - priv.pressed = false; - priv.columnsToMove.length = 0; - (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]); - return; - } - - var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended(); - var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended(); + key: 'setPositionOnRightOfCursor', + value: function setPositionOnRightOfCursor(cursor) { + var left = void 0; - if (guidelineIsNotReady && backlightIsNotReady) { - this.guideline.appendTo(wtTable.hider); - this.backlight.appendTo(wtTable.hider); + if (this.isSubMenu()) { + left = 1 + cursor.left + cursor.cellWidth; + } else { + left = this.offset.right + 1 + cursor.left; } - var from = selection.from, - to = selection.to; + this.container.style.left = left + 'px'; + } - var start = Math.min(from.col, to.col); - var end = Math.max(from.col, to.col); + /** + * Set menu position on the left of cursor object. + * + * @param {Cursor} cursor `Cursor` object. + */ - if (coords.row < 0 && coords.col >= start && coords.col <= end) { - blockCalculations.column = true; - priv.pressed = true; - priv.target.eventPageX = event.pageX; - priv.coordsColumn = coords.col; - priv.target.TD = TD; - priv.target.col = coords.col; - priv.columnsToMove = this.prepareColumnsToMoving(start, end); - priv.hasRowHeaders = !!this.hot.getSettings().rowHeaders; - priv.countCols = this.hot.countCols(); - priv.fixedColumns = this.hot.getSettings().fixedColumnsLeft; - priv.rootElementOffset = (0, _element.offset)(this.hot.rootElement).left; + }, { + key: 'setPositionOnLeftOfCursor', + value: function setPositionOnLeftOfCursor(cursor) { + var left = this.offset.left + cursor.left - this.container.offsetWidth + (0, _element.getScrollbarWidth)() + 4; - var countColumnsFrom = priv.hasRowHeaders ? -1 : 0; - var topPos = wtTable.holder.scrollTop + wtTable.getColumnHeaderHeight(0) + 1; - var fixedColumns = coords.col < priv.fixedColumns; - var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement; - var wrapperIsWindow = scrollableElement.scrollX ? scrollableElement.scrollX - priv.rootElementOffset : 0; + this.container.style.left = left + 'px'; + } - var mouseOffset = event.layerX - (fixedColumns ? wrapperIsWindow : 0); - var leftOffset = Math.abs(this.getColumnsWidth(start, coords.col) + mouseOffset); + /** + * Select first cell in opened menu. + */ - this.backlight.setPosition(topPos, this.getColumnsWidth(countColumnsFrom, start) + leftOffset); - this.backlight.setSize(this.getColumnsWidth(start, end + 1), wtTable.hider.offsetHeight - topPos); - this.backlight.setOffset(null, leftOffset * -1); + }, { + key: 'selectFirstCell', + value: function selectFirstCell() { + var cell = this.hotMenu.getCell(0, 0); - (0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING); + if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { + this.selectNextCell(0, 0); } else { - (0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION); - priv.pressed = false; - priv.columnsToMove.length = 0; + this.hotMenu.selectCell(0, 0); } } /** - * 'mouseMove' event callback. Fired when pointer move on document.documentElement. - * - * @private - * @param {MouseEvent} event `mousemove` event properties. + * Select last cell in opened menu. */ }, { - key: 'onMouseMove', - value: function onMouseMove(event) { - var priv = privatePool.get(this); - - if (!priv.pressed) { - return; - } - - // callback for browser which doesn't supports CSS pointer-event: none - if (event.realTarget === this.backlight.element) { - var width = this.backlight.getSize().width; - this.backlight.setSize(0); + key: 'selectLastCell', + value: function selectLastCell() { + var lastRow = this.hotMenu.countRows() - 1; + var cell = this.hotMenu.getCell(lastRow, 0); - setTimeout(function () { - this.backlight.setPosition(width); - }); + if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { + this.selectPrevCell(lastRow, 0); + } else { + this.hotMenu.selectCell(lastRow, 0); } - - priv.target.eventPageX = event.pageX; - this.refreshPositions(); } /** - * 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell. + * Select next cell in opened menu. * - * @private - * @param {MouseEvent} event `mouseover` event properties. - * @param {CellCoords} coords Visual cell coordinates where was fired event. - * @param {HTMLElement} TD Cell represented as HTMLElement. - * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells. + * @param {Number} row Row index. + * @param {Number} col Column index. */ }, { - key: 'onBeforeOnCellMouseOver', - value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) { - var selectedRange = this.hot.getSelectedRange(); - var priv = privatePool.get(this); + key: 'selectNextCell', + value: function selectNextCell(row, col) { + var nextRow = row + 1; + var cell = nextRow < this.hotMenu.countRows() ? this.hotMenu.getCell(nextRow, col) : null; - if (!selectedRange || !priv.pressed) { + if (!cell) { return; } - - if (priv.columnsToMove.indexOf(coords.col) > -1) { - (0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI); + if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { + this.selectNextCell(nextRow, col); } else { - (0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI); + this.hotMenu.selectCell(nextRow, col); } - - blockCalculations.row = true; - blockCalculations.column = true; - blockCalculations.cell = true; - priv.coordsColumn = coords.col; - priv.target.TD = TD; } /** - * `onMouseUp` hook callback. + * Select previous cell in opened menu. * - * @private + * @param {Number} row Row index. + * @param {Number} col Column index. */ }, { - key: 'onMouseUp', - value: function onMouseUp() { - var priv = privatePool.get(this); - - priv.coordsColumn = void 0; - priv.pressed = false; - priv.backlightWidth = 0; - - (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]); + key: 'selectPrevCell', + value: function selectPrevCell(row, col) { + var prevRow = row - 1; + var cell = prevRow >= 0 ? this.hotMenu.getCell(prevRow, col) : null; - if (this.hot.selection.selectedHeader.cols) { - (0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION); - } - if (priv.columnsToMove.length < 1 || priv.target.col === void 0 || priv.columnsToMove.indexOf(priv.target.col) > -1) { + if (!cell) { return; } - - this.moveColumns(priv.columnsToMove, priv.target.col); - this.persistentStateSave(); - this.hot.render(); - this.hot.view.wt.wtOverlays.adjustElementsSize(true); - - if (!priv.disallowMoving) { - var selectionStart = this.columnsMapper.getIndexByValue(priv.columnsToMove[0]); - var selectionEnd = this.columnsMapper.getIndexByValue(priv.columnsToMove[priv.columnsToMove.length - 1]); - this.changeSelection(selectionStart, selectionEnd); + if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) { + this.selectPrevCell(prevRow, col); + } else { + this.hotMenu.selectCell(prevRow, col); } - - priv.columnsToMove.length = 0; } /** - * `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally. + * Menu item renderer. * * @private */ }, { - key: 'onAfterScrollVertically', - value: function onAfterScrollVertically() { - var wtTable = this.hot.view.wt.wtTable; - var headerHeight = wtTable.getColumnHeaderHeight(0) + 1; - var scrollTop = wtTable.holder.scrollTop; - var posTop = headerHeight + scrollTop; + key: 'menuItemRenderer', + value: function menuItemRenderer(hot, TD, row, col, prop, value) { + var _this4 = this; - this.backlight.setPosition(posTop); - this.backlight.setSize(null, wtTable.hider.offsetHeight - posTop); - } + var item = hot.getSourceDataAtRow(row); + var wrapper = document.createElement('div'); - /** - * `afterCreateCol` hook callback. - * - * @private - * @param {Number} index Visual index of the created column. - * @param {Number} amount Amount of created columns. - */ + var isSubMenu = function isSubMenu(item) { + return (0, _object.hasOwnProperty)(item, 'submenu'); + }; + var itemIsSeparator = function itemIsSeparator(item) { + return new RegExp(_predefinedItems.SEPARATOR, 'i').test(item.name); + }; + var itemIsDisabled = function itemIsDisabled(item) { + return item.disabled === true || typeof item.disabled == 'function' && item.disabled.call(_this4.hot) === true; + }; + var itemIsSelectionDisabled = function itemIsSelectionDisabled(item) { + return item.disableSelection; + }; - }, { - key: 'onAfterCreateCol', - value: function onAfterCreateCol(index, amount) { - this.columnsMapper.shiftItems(index, amount); + if (typeof value === 'function') { + value = value.call(this.hot); + } + (0, _element.empty)(TD); + (0, _element.addClass)(wrapper, 'htItemWrapper'); + TD.appendChild(wrapper); + + if (itemIsSeparator(item)) { + (0, _element.addClass)(TD, 'htSeparator'); + } else if (typeof item.renderer === 'function') { + (0, _element.addClass)(TD, 'htCustomMenuRenderer'); + TD.appendChild(item.renderer(hot, wrapper, row, col, prop, value)); + } else { + (0, _element.fastInnerHTML)(wrapper, value); + } + if (itemIsDisabled(item)) { + (0, _element.addClass)(TD, 'htDisabled'); + this.eventManager.addEventListener(TD, 'mouseenter', function () { + return hot.deselectCell(); + }); + } else if (itemIsSelectionDisabled(item)) { + (0, _element.addClass)(TD, 'htSelectionDisabled'); + this.eventManager.addEventListener(TD, 'mouseenter', function () { + return hot.deselectCell(); + }); + } else if (isSubMenu(item)) { + (0, _element.addClass)(TD, 'htSubmenu'); + + if (itemIsSelectionDisabled(item)) { + this.eventManager.addEventListener(TD, 'mouseenter', function () { + return hot.deselectCell(); + }); + } else { + this.eventManager.addEventListener(TD, 'mouseenter', function () { + return hot.selectCell(row, col, void 0, void 0, false, false); + }); + } + } else { + (0, _element.removeClass)(TD, 'htSubmenu'); + (0, _element.removeClass)(TD, 'htDisabled'); + + if (itemIsSelectionDisabled(item)) { + this.eventManager.addEventListener(TD, 'mouseenter', function () { + return hot.deselectCell(); + }); + } else { + this.eventManager.addEventListener(TD, 'mouseenter', function () { + return hot.selectCell(row, col, void 0, void 0, false, false); + }); + } + } } /** - * On before remove column listener. + * Create container/wrapper for handsontable. * * @private - * @param {Number} index Visual column index. - * @param {Number} amount Defines how many columns removed. + * @param {String} [name] Class name. + * @returns {HTMLElement} */ }, { - key: 'onBeforeRemoveCol', - value: function onBeforeRemoveCol(index, amount) { - var _this5 = this; + key: 'createContainer', + value: function createContainer() { + var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (name) { + name = name.replace(/[^A-z0-9]/g, '_'); + name = this.options.className + 'Sub_' + name; + } + var container = void 0; - this.removedColumns.length = 0; + if (name) { + container = document.querySelector('.' + this.options.className + '.' + name); + } else { + container = document.querySelector('.' + this.options.className); + } + if (!container) { + container = document.createElement('div'); + (0, _element.addClass)(container, 'htMenu ' + this.options.className); - if (index !== false) { - // Collect physical row index. - (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) { - _this5.removedColumns.push(_this5.hot.runHooks('modifyCol', removedIndex, _this5.pluginName)); - }); + if (name) { + (0, _element.addClass)(container, name); + } + document.getElementsByTagName('body')[0].appendChild(container); } + + return container; } /** - * `afterRemoveCol` hook callback. - * * @private - * @param {Number} index Visual column index of the removed column. - * @param {Number} amount Amount of removed columns. */ }, { - key: 'onAfterRemoveCol', - value: function onAfterRemoveCol(index, amount) { - this.columnsMapper.unshiftItems(this.removedColumns); + key: 'blockMainTableCallbacks', + value: function blockMainTableCallbacks() { + this._afterScrollCallback = function () {}; + this.hot.addHook('afterScrollVertically', this._afterScrollCallback); + this.hot.addHook('afterScrollHorizontally', this._afterScrollCallback); } /** - * `afterLoadData` hook callback. - * * @private - * @param {Boolean} firstTime True if that was loading data during the initialization. */ }, { - key: 'onAfterLoadData', - value: function onAfterLoadData(firstTime) { - this.updateColumnsMapper(); + key: 'releaseMainTableCallbacks', + value: function releaseMainTableCallbacks() { + if (this._afterScrollCallback) { + this.hot.removeHook('afterScrollVertically', this._afterScrollCallback); + this.hot.removeHook('afterScrollHorizontally', this._afterScrollCallback); + this._afterScrollCallback = null; + } } /** - * 'modifyRow' hook callback. + * On before key down listener. * * @private - * @param {Number} column Visual column index. - * @returns {Number} Physical column index. + * @param {Event} event */ }, { - key: 'onModifyCol', - value: function onModifyCol(column, source) { - if (source !== this.pluginName) { - // ugly fix for try to insert new, needed columns after pasting data - var columnInMapper = this.columnsMapper.getValueByIndex(column); - column = columnInMapper === null ? column : columnInMapper; + key: 'onBeforeKeyDown', + value: function onBeforeKeyDown(event) { + var selection = this.hotMenu.getSelected(); + var stopEvent = false; + this.keyEvent = true; + + switch (event.keyCode) { + case _unicode.KEY_CODES.ESCAPE: + this.close(); + stopEvent = true; + break; + + case _unicode.KEY_CODES.ENTER: + if (selection) { + if (this.hotMenu.getSourceDataAtRow(selection[0]).submenu) { + stopEvent = true; + } else { + this.executeCommand(event); + this.close(true); + } + } + break; + + case _unicode.KEY_CODES.ARROW_DOWN: + if (selection) { + this.selectNextCell(selection[0], selection[1]); + } else { + this.selectFirstCell(); + } + stopEvent = true; + break; + + case _unicode.KEY_CODES.ARROW_UP: + if (selection) { + this.selectPrevCell(selection[0], selection[1]); + } else { + this.selectLastCell(); + } + stopEvent = true; + break; + + case _unicode.KEY_CODES.ARROW_RIGHT: + if (selection) { + var menu = this.openSubMenu(selection[0]); + + if (menu) { + menu.selectFirstCell(); + } + } + stopEvent = true; + + break; + + case _unicode.KEY_CODES.ARROW_LEFT: + if (selection && this.isSubMenu()) { + this.close(); + + if (this.parentMenu) { + this.parentMenu.hotMenu.listen(); + } + stopEvent = true; + } + break; + default: + break; + } + if (stopEvent) { + event.preventDefault(); + (0, _event.stopImmediatePropagation)(event); } - return column; + this.keyEvent = false; } /** - * 'unmodifyCol' hook callback. + * On after init listener. * * @private - * @param {Number} column Physical column index. - * @returns {Number} Visual column index. */ }, { - key: 'onUnmodifyCol', - value: function onUnmodifyCol(column) { - var indexInMapper = this.columnsMapper.getIndexByValue(column); + key: 'onAfterInit', + value: function onAfterInit() { + var data = this.hotMenu.getSettings().data; + var hiderStyle = this.hotMenu.view.wt.wtTable.hider.style; + var holderStyle = this.hotMenu.view.wt.wtTable.holder.style; + var currentHiderWidth = parseInt(hiderStyle.width, 10); - return indexInMapper === null ? column : indexInMapper; + var realHeight = (0, _array.arrayReduce)(data, function (accumulator, value) { + return accumulator + (value.name === _predefinedItems.SEPARATOR ? 1 : 26); + }, 0); + + holderStyle.width = currentHiderWidth + 22 + 'px'; + holderStyle.height = realHeight + 4 + 'px'; + hiderStyle.height = holderStyle.height; } /** - * `afterPluginsInitialized` hook callback. + * On after selection listener. * - * @private + * @param {Number} r Selection start row index. + * @param {Number} c Selection start column index. + * @param {Number} r2 Selection end row index. + * @param {Number} c2 Selection end column index. + * @param {Object} preventScrolling Object with `value` property where its value change will be observed. */ }, { - key: 'onAfterPluginsInitialized', - value: function onAfterPluginsInitialized() { - this.updateColumnsMapper(); - this.initialSettings(); - this.backlight.build(); - this.guideline.build(); + key: 'onAfterSelection', + value: function onAfterSelection(r, c, r2, c2, preventScrolling) { + if (this.keyEvent === false) { + preventScrolling.value = true; + } } /** - * Destroy plugin instance. + * Document mouse down listener. + * + * @private + * @param {Event} event */ }, { - key: 'destroy', - value: function destroy() { - this.backlight.destroy(); - this.guideline.destroy(); + key: 'onDocumentMouseDown', + value: function onDocumentMouseDown(event) { + if (!this.isOpened()) { + return; + } + if (this.container && (0, _element.isChildOf)(event.target, this.container)) { + this.executeCommand(event); + } + // Close menu when clicked element is not belongs to menu itself + if (this.options.standalone && this.hotMenu && !(0, _element.isChildOf)(event.target, this.hotMenu.rootElement)) { + this.close(true); - _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'destroy', this).call(this); + // Automatically close menu when clicked element is not belongs to menu or submenu (not necessarily to itself) + } else if ((this.isAllSubMenusClosed() || this.isSubMenu()) && !(0, _element.isChildOf)(event.target, '.htMenu') && (0, _element.isChildOf)(event.target, document)) { + this.close(true); + } } }]); - return ManualColumnMove; -}(_base2.default); + return Menu; +}(); -(0, _plugins.registerPlugin)('ManualColumnMove', ManualColumnMove); +(0, _object.mixin)(Menu, _localHooks2.default); -exports.default = ManualColumnMove; +exports.default = Menu; /***/ }), -/* 247 */ +/* 274 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57813,119 +57656,153 @@ exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - -var _base = __webpack_require__(152); - -var _base2 = _interopRequireDefault(_base); - var _element = __webpack_require__(0); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _event = __webpack_require__(8); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var CSS_CLASSNAME = 'ht__manualColumnMove--backlight'; - /** - * @class BacklightUI - * @util + * Helper class for checking if element will fit at the desired side of cursor. + * + * @class Cursor + * @plugin ContextMenu */ +var Cursor = function () { + function Cursor(object) { + _classCallCheck(this, Cursor); -var BacklightUI = function (_BaseUI) { - _inherits(BacklightUI, _BaseUI); - - function BacklightUI() { - _classCallCheck(this, BacklightUI); - - return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments)); - } - - _createClass(BacklightUI, [{ - key: 'build', + var windowScrollTop = (0, _element.getWindowScrollTop)(); + var windowScrollLeft = (0, _element.getWindowScrollLeft)(); + var top = void 0, + topRelative = void 0; + var left = void 0, + leftRelative = void 0; + var cellHeight = void 0, + cellWidth = void 0; - /** - * Custom className on build process. - */ - value: function build() { - _get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this); + this.type = this.getSourceType(object); - (0, _element.addClass)(this._element, CSS_CLASSNAME); + if (this.type === 'literal') { + top = parseInt(object.top, 10); + left = parseInt(object.left, 10); + cellHeight = object.height || 0; + cellWidth = object.width || 0; + topRelative = top; + leftRelative = left; + top += windowScrollTop; + left += windowScrollLeft; + } else if (this.type === 'event') { + top = parseInt((0, _event.pageY)(object), 10); + left = parseInt((0, _event.pageX)(object), 10); + cellHeight = object.target.clientHeight; + cellWidth = object.target.clientWidth; + topRelative = top - windowScrollTop; + leftRelative = left - windowScrollLeft; } - }]); - - return BacklightUI; -}(_base2.default); - -exports.default = BacklightUI; - -/***/ }), -/* 248 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + this.top = top; + this.topRelative = topRelative; + this.left = left; + this.leftRelative = leftRelative; + this.scrollTop = windowScrollTop; + this.scrollLeft = windowScrollLeft; + this.cellHeight = cellHeight; + this.cellWidth = cellWidth; + } -var _base = __webpack_require__(152); + /** + * Get source type name. + * + * @param {*} object Event or Object with coordinates. + * @returns {String} Returns one of this values: `'literal'`, `'event'`. + */ -var _base2 = _interopRequireDefault(_base); -var _element = __webpack_require__(0); + _createClass(Cursor, [{ + key: 'getSourceType', + value: function getSourceType(object) { + var type = 'literal'; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (object instanceof Event) { + type = 'event'; + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + return type; + } -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + /** + * Checks if element can be placed above the cursor. + * + * @param {HTMLElement} element Element to check if it's size will fit above the cursor. + * @returns {Boolean} + */ -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + }, { + key: 'fitsAbove', + value: function fitsAbove(element) { + return this.topRelative >= element.offsetHeight; + } -var CSS_CLASSNAME = 'ht__manualColumnMove--guideline'; + /** + * Checks if element can be placed below the cursor. + * + * @param {HTMLElement} element Element to check if it's size will fit below the cursor. + * @param {Number} [viewportHeight] The viewport height. + * @returns {Boolean} + */ -/** - * @class GuidelineUI - * @util - */ + }, { + key: 'fitsBelow', + value: function fitsBelow(element) { + var viewportHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window.innerHeight; -var GuidelineUI = function (_BaseUI) { - _inherits(GuidelineUI, _BaseUI); + return this.topRelative + element.offsetHeight <= viewportHeight; + } - function GuidelineUI() { - _classCallCheck(this, GuidelineUI); + /** + * Checks if element can be placed on the right of the cursor. + * + * @param {HTMLElement} element Element to check if it's size will fit on the right of the cursor. + * @param {Number} [viewportWidth] The viewport width. + * @returns {Boolean} + */ - return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments)); - } + }, { + key: 'fitsOnRight', + value: function fitsOnRight(element) { + var viewportWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window.innerWidth; - _createClass(GuidelineUI, [{ - key: 'build', + return this.leftRelative + this.cellWidth + element.offsetWidth <= viewportWidth; + } /** - * Custom className on build process. + * Checks if element can be placed on the left on the cursor. + * + * @param {HTMLElement} element Element to check if it's size will fit on the left of the cursor. + * @returns {Boolean} */ - value: function build() { - _get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this); - (0, _element.addClass)(this._element, CSS_CLASSNAME); + }, { + key: 'fitsOnLeft', + value: function fitsOnLeft(element) { + return this.leftRelative >= element.offsetWidth; } }]); - return GuidelineUI; -}(_base2.default); + return Cursor; +}(); -exports.default = GuidelineUI; +exports.default = Cursor; /***/ }), -/* 249 */ +/* 275 */ +/***/ (function(module, exports) { + +// removed by extract-text-webpack-plugin + +/***/ }), +/* 276 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57933,28 +57810,56 @@ exports.default = GuidelineUI; exports.__esModule = true; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var _base = __webpack_require__(12); +var _base = __webpack_require__(13); var _base2 = _interopRequireDefault(_base); -var _element = __webpack_require__(0); +var _pluginHooks = __webpack_require__(7); -var _eventManager = __webpack_require__(4); +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); -var _eventManager2 = _interopRequireDefault(_eventManager); +var _SheetClip = __webpack_require__(171); + +var _SheetClip2 = _interopRequireDefault(_SheetClip); + +var _src = __webpack_require__(12); -var _event = __webpack_require__(7); +var _unicode = __webpack_require__(17); + +var _element = __webpack_require__(0); var _array = __webpack_require__(2); var _number = __webpack_require__(6); +var _event = __webpack_require__(8); + var _plugins = __webpack_require__(5); +var _textarea = __webpack_require__(277); + +var _textarea2 = _interopRequireDefault(_textarea); + +var _copy = __webpack_require__(278); + +var _copy2 = _interopRequireDefault(_copy); + +var _cut = __webpack_require__(279); + +var _cut2 = _interopRequireDefault(_cut); + +var _eventManager = __webpack_require__(4); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +__webpack_require__(280); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -57963,62 +57868,111 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js +_pluginHooks2.default.getSingleton().register('afterCopyLimit'); +_pluginHooks2.default.getSingleton().register('modifyCopyableRange'); +_pluginHooks2.default.getSingleton().register('beforeCut'); +_pluginHooks2.default.getSingleton().register('afterCut'); +_pluginHooks2.default.getSingleton().register('beforePaste'); +_pluginHooks2.default.getSingleton().register('afterPaste'); +_pluginHooks2.default.getSingleton().register('beforeCopy'); +_pluginHooks2.default.getSingleton().register('afterCopy'); + +var ROWS_LIMIT = 1000; +var COLUMNS_LIMIT = 1000; +var privatePool = new WeakMap(); /** * @description - * ManualColumnResize Plugin. - * - * Has 2 UI components: - * - handle - the draggable element that sets the desired width of the column. - * - guide - the helper guide that shows the desired width as a vertical guide. + * This plugin enables the copy/paste functionality in the Handsontable. * - * @plugin ManualColumnResize + * @example + * ```js + * ... + * copyPaste: true, + * ... + * ``` + * @class CopyPaste + * @plugin CopyPaste */ -var ManualColumnResize = function (_BasePlugin) { - _inherits(ManualColumnResize, _BasePlugin); - function ManualColumnResize(hotInstance) { - _classCallCheck(this, ManualColumnResize); +var CopyPaste = function (_BasePlugin) { + _inherits(CopyPaste, _BasePlugin); - var _this = _possibleConstructorReturn(this, (ManualColumnResize.__proto__ || Object.getPrototypeOf(ManualColumnResize)).call(this, hotInstance)); + function CopyPaste(hotInstance) { + _classCallCheck(this, CopyPaste); + + /** + * Event manager + * + * @type {EventManager} + */ + var _this = _possibleConstructorReturn(this, (CopyPaste.__proto__ || Object.getPrototypeOf(CopyPaste)).call(this, hotInstance)); - _this.currentTH = null; - _this.currentCol = null; - _this.selectedCols = []; - _this.currentWidth = null; - _this.newSize = null; - _this.startY = null; - _this.startWidth = null; - _this.startOffset = null; - _this.handle = document.createElement('DIV'); - _this.guide = document.createElement('DIV'); _this.eventManager = new _eventManager2.default(_this); - _this.pressed = null; - _this.dblclick = 0; - _this.autoresizeTimeout = null; - _this.manualColumnWidths = []; + /** + * Maximum number of columns than can be copied to clipboard using CTRL + C. + * + * @private + * @type {Number} + * @default 1000 + */ + _this.columnsLimit = COLUMNS_LIMIT; + /** + * Ranges of the cells coordinates, which should be used to copy/cut/paste actions. + * + * @private + * @type {Array} + */ + _this.copyableRanges = []; + /** + * Defines paste (CTRL + V) behavior. + * * Default value `"overwrite"` will paste clipboard value over current selection. + * * When set to `"shift_down"`, clipboard data will be pasted in place of current selection, while all selected cells are moved down. + * * When set to `"shift_right"`, clipboard data will be pasted in place of current selection, while all selected cells are moved right. + * + * @private + * @type {String} + * @default 'overwrite' + */ + _this.pasteMode = 'overwrite'; + /** + * Maximum number of rows than can be copied to clipboard using CTRL + C. + * + * @private + * @type {Number} + * @default 1000 + */ + _this.rowsLimit = ROWS_LIMIT; + /** + * The `textarea` element which is necessary to process copying, cutting off and pasting. + * + * @private + * @type {HTMLElement} + * @default undefined + */ + _this.textarea = void 0; - (0, _element.addClass)(_this.handle, 'manualColumnResizer'); - (0, _element.addClass)(_this.guide, 'manualColumnResizerGuide'); + privatePool.set(_this, { + isTriggeredByPaste: false + }); return _this; } /** - * Check if the plugin is enabled in the handsontable settings. + * Check if plugin is enabled. * * @returns {Boolean} */ - _createClass(ManualColumnResize, [{ + _createClass(CopyPaste, [{ key: 'isEnabled', value: function isEnabled() { - return this.hot.getSettings().manualColumnResize; + return !!this.hot.getSettings().copyPaste; } /** - * Enable plugin for this Handsontable instance. + * Enable the plugin. */ }, { @@ -58030,36 +57984,27 @@ var ManualColumnResize = function (_BasePlugin) { return; } - this.manualColumnWidths = []; - var initialColumnWidth = this.hot.getSettings().manualColumnResize; - var loadedManualColumnWidths = this.loadManualColumnWidths(); + var settings = this.hot.getSettings(); - this.addHook('modifyColWidth', function (width, col) { - return _this2.onModifyColWidth(width, col); - }); - this.addHook('beforeStretchingColumnWidth', function (stretchedWidth, column) { - return _this2.onBeforeStretchingColumnWidth(stretchedWidth, column); - }); - this.addHook('beforeColumnResize', function (currentColumn, newSize, isDoubleClick) { - return _this2.onBeforeColumnResize(currentColumn, newSize, isDoubleClick); - }); + this.textarea = _textarea2.default.getSingleton(); - if (typeof loadedManualColumnWidths != 'undefined') { - this.manualColumnWidths = loadedManualColumnWidths; - } else if (Array.isArray(initialColumnWidth)) { - this.manualColumnWidths = initialColumnWidth; - } else { - this.manualColumnWidths = []; + if (_typeof(settings.copyPaste) === 'object') { + this.pasteMode = settings.copyPaste.pasteMode || this.pasteMode; + this.rowsLimit = settings.copyPaste.rowsLimit || this.rowsLimit; + this.columnsLimit = settings.copyPaste.columnsLimit || this.columnsLimit; } - // Handsontable.hooks.register('beforeColumnResize'); - // Handsontable.hooks.register('afterColumnResize'); + this.addHook('afterContextMenuDefaultOptions', function (options) { + return _this2.onAfterContextMenuDefaultOptions(options); + }); + this.addHook('beforeKeyDown', function (event) { + return _this2.onBeforeKeyDown(event); + }); - this.bindEvents(); + this.registerEvents(); - _get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'enablePlugin', this).call(this); + _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'enablePlugin', this).call(this); } - /** * Updates the plugin to use the latest options you have specified. */ @@ -58067,13 +58012,10 @@ var ManualColumnResize = function (_BasePlugin) { }, { key: 'updatePlugin', value: function updatePlugin() { - var initialColumnWidth = this.hot.getSettings().manualColumnResize; + this.disablePlugin(); + this.enablePlugin(); - if (Array.isArray(initialColumnWidth)) { - this.manualColumnWidths = initialColumnWidth; - } else if (!initialColumnWidth) { - this.manualColumnWidths = []; - } + _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'updatePlugin', this).call(this); } /** @@ -58083,1416 +58025,1677 @@ var ManualColumnResize = function (_BasePlugin) { }, { key: 'disablePlugin', value: function disablePlugin() { - _get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'disablePlugin', this).call(this); + if (this.textarea) { + this.textarea.destroy(); + } + + _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'disablePlugin', this).call(this); } /** - * Save the current sizes using the persistentState plugin. + * Prepares copyable text from the cells selection in the invisible textarea. + * + * @function setCopyable + * @memberof CopyPaste# */ }, { - key: 'saveManualColumnWidths', - value: function saveManualColumnWidths() { - this.hot.runHooks('persistentStateSave', 'manualColumnWidths', this.manualColumnWidths); + key: 'setCopyableText', + value: function setCopyableText() { + var selRange = this.hot.getSelectedRange(); + + if (!selRange) { + return; + } + + var topLeft = selRange.getTopLeftCorner(); + var bottomRight = selRange.getBottomRightCorner(); + var startRow = topLeft.row; + var startCol = topLeft.col; + var endRow = bottomRight.row; + var endCol = bottomRight.col; + var finalEndRow = Math.min(endRow, startRow + this.rowsLimit - 1); + var finalEndCol = Math.min(endCol, startCol + this.columnsLimit - 1); + + this.copyableRanges.length = 0; + + this.copyableRanges.push({ + startRow: startRow, + startCol: startCol, + endRow: finalEndRow, + endCol: finalEndCol + }); + + this.copyableRanges = this.hot.runHooks('modifyCopyableRange', this.copyableRanges); + + var copyableData = this.getRangedCopyableData(this.copyableRanges); + + this.textarea.setValue(copyableData); + + if (endRow !== finalEndRow || endCol !== finalEndCol) { + this.hot.runHooks('afterCopyLimit', endRow - startRow + 1, endCol - startCol + 1, this.rowsLimit, this.columnsLimit); + } } /** - * Load the previously saved sizes using the persistentState plugin. + * Create copyable text releated to range objects. * - * @returns {Array} + * @since 0.19.0 + * @param {Array} ranges Array of Objects with properties `startRow`, `endRow`, `startCol` and `endCol`. + * @returns {String} Returns string which will be copied into clipboard. */ }, { - key: 'loadManualColumnWidths', - value: function loadManualColumnWidths() { - var storedState = {}; + key: 'getRangedCopyableData', + value: function getRangedCopyableData(ranges) { + var _this3 = this; - this.hot.runHooks('persistentStateLoad', 'manualColumnWidths', storedState); + var dataSet = []; + var copyableRows = []; + var copyableColumns = []; - return storedState.value; + // Count all copyable rows and columns + (0, _array.arrayEach)(ranges, function (range) { + (0, _number.rangeEach)(range.startRow, range.endRow, function (row) { + if (copyableRows.indexOf(row) === -1) { + copyableRows.push(row); + } + }); + (0, _number.rangeEach)(range.startCol, range.endCol, function (column) { + if (copyableColumns.indexOf(column) === -1) { + copyableColumns.push(column); + } + }); + }); + // Concat all rows and columns data defined in ranges into one copyable string + (0, _array.arrayEach)(copyableRows, function (row) { + var rowSet = []; + + (0, _array.arrayEach)(copyableColumns, function (column) { + rowSet.push(_this3.hot.getCopyableData(row, column)); + }); + + dataSet.push(rowSet); + }); + + return _SheetClip2.default.stringify(dataSet); } /** - * Set the resize handle position. + * Create copyable text releated to range objects. * - * @param {HTMLCellElement} TH TH HTML element. + * @since 0.31.1 + * @param {Array} ranges Array of Objects with properties `startRow`, `startCol`, `endRow` and `endCol`. + * @returns {Array} Returns array of arrays which will be copied into clipboard. */ }, { - key: 'setupHandlePosition', - value: function setupHandlePosition(TH) { - var _this3 = this; + key: 'getRangedData', + value: function getRangedData(ranges) { + var _this4 = this; - if (!TH.parentNode) { - return false; - } + var dataSet = []; + var copyableRows = []; + var copyableColumns = []; - this.currentTH = TH; + // Count all copyable rows and columns + (0, _array.arrayEach)(ranges, function (range) { + (0, _number.rangeEach)(range.startRow, range.endRow, function (row) { + if (copyableRows.indexOf(row) === -1) { + copyableRows.push(row); + } + }); + (0, _number.rangeEach)(range.startCol, range.endCol, function (column) { + if (copyableColumns.indexOf(column) === -1) { + copyableColumns.push(column); + } + }); + }); + // Concat all rows and columns data defined in ranges into one copyable string + (0, _array.arrayEach)(copyableRows, function (row) { + var rowSet = []; - var col = this.hot.view.wt.wtTable.getCoords(TH).col; // getCoords returns CellCoords - var headerHeight = (0, _element.outerHeight)(this.currentTH); + (0, _array.arrayEach)(copyableColumns, function (column) { + rowSet.push(_this4.hot.getCopyableData(row, column)); + }); - if (col >= 0) { - // if not col header - var box = this.currentTH.getBoundingClientRect(); + dataSet.push(rowSet); + }); - this.currentCol = col; - this.selectedCols = []; + return dataSet; + } - if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.cols) { - var _hot$getSelectedRange = this.hot.getSelectedRange(), - from = _hot$getSelectedRange.from, - to = _hot$getSelectedRange.to; + /** + * Copy action. + * + * @param {Boolean} isTriggeredByClick Flag to determine that copy action was executed by the mouse click. + */ - var start = from.col; - var end = to.col; + }, { + key: 'copy', + value: function copy(isTriggeredByClick) { + var rangedData = this.getRangedData(this.copyableRanges); - if (start >= end) { - start = to.col; - end = from.col; - } + var allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges); - if (this.currentCol >= start && this.currentCol <= end) { - (0, _number.rangeEach)(start, end, function (i) { - return _this3.selectedCols.push(i); - }); - } else { - this.selectedCols.push(this.currentCol); - } - } else { - this.selectedCols.push(this.currentCol); + if (allowCopying) { + this.textarea.setValue(_SheetClip2.default.stringify(rangedData)); + this.textarea.select(); + + if (isTriggeredByClick) { + document.execCommand('copy'); } - this.startOffset = box.left - 6; - this.startWidth = parseInt(box.width, 10); - this.handle.style.top = box.top + 'px'; - this.handle.style.left = this.startOffset + this.startWidth + 'px'; - this.handle.style.height = headerHeight + 'px'; - this.hot.rootElement.appendChild(this.handle); + this.hot.runHooks('afterCopy', rangedData, this.copyableRanges); + } else { + this.textarea.setValue(''); } } /** - * Refresh the resize handle position. + * Cut action. + * + * @param {Boolean} isTriggeredByClick Flag to determine that cut action was executed by the mouse click. */ }, { - key: 'refreshHandlePosition', - value: function refreshHandlePosition() { - this.handle.style.left = this.startOffset + this.currentWidth + 'px'; - } + key: 'cut', + value: function cut(isTriggeredByClick) { + var rangedData = this.getRangedData(this.copyableRanges); - /** - * Set the resize guide position. - */ + var allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges); - }, { - key: 'setupGuidePosition', - value: function setupGuidePosition() { - var handleHeight = parseInt((0, _element.outerHeight)(this.handle), 10); - var handleBottomPosition = parseInt(this.handle.style.top, 10) + handleHeight; - var maximumVisibleElementHeight = parseInt(this.hot.view.maximumVisibleElementHeight(0), 10); + if (allowCuttingOut) { + this.textarea.setValue(_SheetClip2.default.stringify(rangedData)); + this.hot.selection.empty(); + this.textarea.select(); - (0, _element.addClass)(this.handle, 'active'); - (0, _element.addClass)(this.guide, 'active'); + if (isTriggeredByClick) { + document.execCommand('cut'); + } - this.guide.style.top = handleBottomPosition + 'px'; - this.guide.style.left = this.handle.style.left; - this.guide.style.height = maximumVisibleElementHeight - handleHeight + 'px'; - this.hot.rootElement.appendChild(this.guide); + this.hot.runHooks('afterCut', rangedData, this.copyableRanges); + } else { + this.textarea.setValue(''); + } } /** - * Refresh the resize guide position. + * Simulated paste action. + * + * @param {String} [value=''] New value, which should be `pasted`. */ }, { - key: 'refreshGuidePosition', - value: function refreshGuidePosition() { - this.guide.style.left = this.handle.style.left; + key: 'paste', + value: function paste() { + var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + + this.textarea.setValue(value); + + this.onPaste(); + this.onInput(); } /** - * Hide both the resize handle and resize guide. + * Register event listeners. + * + * @private */ }, { - key: 'hideHandleAndGuide', - value: function hideHandleAndGuide() { - (0, _element.removeClass)(this.handle, 'active'); - (0, _element.removeClass)(this.guide, 'active'); + key: 'registerEvents', + value: function registerEvents() { + var _this5 = this; + + this.eventManager.addEventListener(this.textarea.element, 'paste', function (event) { + return _this5.onPaste(event); + }); + this.eventManager.addEventListener(this.textarea.element, 'input', function (event) { + return _this5.onInput(event); + }); } /** - * Check if provided element is considered a column header. + * Trigger to make possible observe `onInput` in textarea. * - * @param {HTMLElement} element HTML element. - * @returns {Boolean} + * @private */ }, { - key: 'checkIfColumnHeader', - value: function checkIfColumnHeader(element) { - if (element != this.hot.rootElement) { - var parent = element.parentNode; - - if (parent.tagName === 'THEAD') { - return true; - } - - return this.checkIfColumnHeader(parent); - } + key: 'triggerPaste', + value: function triggerPaste() { + this.textarea.select(); - return false; + this.onPaste(); } /** - * Get the TH element from the provided element. + * `paste` event callback on textarea element. * - * @param {HTMLElement} element HTML element. - * @returns {HTMLElement} + * @private */ }, { - key: 'getTHFromTargetElement', - value: function getTHFromTargetElement(element) { - if (element.tagName != 'TABLE') { - if (element.tagName == 'TH') { - return element; - } - return this.getTHFromTargetElement(element.parentNode); - } + key: 'onPaste', + value: function onPaste() { + var priv = privatePool.get(this); - return null; + priv.isTriggeredByPaste = true; } /** - * 'mouseover' event callback - set the handle position. + * `input` event callback is called after `paste` event callback. * * @private - * @param {MouseEvent} event */ }, { - key: 'onMouseOver', - value: function onMouseOver(event) { - if (this.checkIfColumnHeader(event.target)) { - var th = this.getTHFromTargetElement(event.target); + key: 'onInput', + value: function onInput() { + var _this6 = this; - if (!th) { - return; - } + var priv = privatePool.get(this); - var colspan = th.getAttribute('colspan'); + if (!this.hot.isListening() || !priv.isTriggeredByPaste) { + return; + } - if (th && (colspan === null || colspan === 1)) { - if (!this.pressed) { - this.setupHandlePosition(th); - } - } + priv.isTriggeredByPaste = false; + + var input = void 0, + inputArray = void 0, + selected = void 0, + coordsFrom = void 0, + coordsTo = void 0, + cellRange = void 0, + topLeftCorner = void 0, + bottomRightCorner = void 0, + areaStart = void 0, + areaEnd = void 0; + + input = this.textarea.getValue(); + inputArray = _SheetClip2.default.parse(input); + + var allowPasting = !!this.hot.runHooks('beforePaste', inputArray, this.copyableRanges); + + if (!allowPasting) { + return; } + + selected = this.hot.getSelected(); + coordsFrom = new _src.CellCoords(selected[0], selected[1]); + coordsTo = new _src.CellCoords(selected[2], selected[3]); + cellRange = new _src.CellRange(coordsFrom, coordsFrom, coordsTo); + topLeftCorner = cellRange.getTopLeftCorner(); + bottomRightCorner = cellRange.getBottomRightCorner(); + areaStart = topLeftCorner; + areaEnd = new _src.CellCoords(Math.max(bottomRightCorner.row, inputArray.length - 1 + topLeftCorner.row), Math.max(bottomRightCorner.col, inputArray[0].length - 1 + topLeftCorner.col)); + + var isSelRowAreaCoverInputValue = coordsTo.row - coordsFrom.row >= inputArray.length - 1; + var isSelColAreaCoverInputValue = coordsTo.col - coordsFrom.col >= inputArray[0].length - 1; + + this.hot.addHookOnce('afterChange', function (changes, source) { + var changesLength = changes ? changes.length : 0; + + if (changesLength) { + var offset = { row: 0, col: 0 }; + var highestColumnIndex = -1; + + (0, _array.arrayEach)(changes, function (change, index) { + var nextChange = changesLength > index + 1 ? changes[index + 1] : null; + + if (nextChange) { + if (!isSelRowAreaCoverInputValue) { + offset.row += Math.max(nextChange[0] - change[0] - 1, 0); + } + if (!isSelColAreaCoverInputValue && change[1] > highestColumnIndex) { + highestColumnIndex = change[1]; + offset.col += Math.max(nextChange[1] - change[1] - 1, 0); + } + } + }); + _this6.hot.selectCell(areaStart.row, areaStart.col, areaEnd.row + offset.row, areaEnd.col + offset.col); + } + }); + + this.hot.populateFromArray(areaStart.row, areaStart.col, inputArray, areaEnd.row, areaEnd.col, 'CopyPaste.paste', this.pasteMode); + this.hot.runHooks('afterPaste', inputArray, this.copyableRanges); } /** - * Auto-size row after doubleclick - callback. + * Add copy, cut and paste options to the Context Menu. * * @private + * @param {Object} options Contains default added options of the Context Menu. */ }, { - key: 'afterMouseDownTimeout', - value: function afterMouseDownTimeout() { - var _this4 = this; + key: 'onAfterContextMenuDefaultOptions', + value: function onAfterContextMenuDefaultOptions(options) { + options.items.push({ + name: '---------' + }, (0, _copy2.default)(this), (0, _cut2.default)(this)); + } - var render = function render() { - _this4.hot.forceFullRender = true; - _this4.hot.view.render(); // updates all - _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); - }; - var resize = function resize(selectedCol, forceRender) { - var hookNewSize = _this4.hot.runHooks('beforeColumnResize', selectedCol, _this4.newSize, true); + /** + * beforeKeyDown callback. + * + * @private + * @param {Event} event + */ - if (hookNewSize !== void 0) { - _this4.newSize = hookNewSize; - } + }, { + key: 'onBeforeKeyDown', + value: function onBeforeKeyDown(event) { + var _this7 = this; - if (_this4.hot.getSettings().stretchH === 'all') { - _this4.clearManualSize(selectedCol); - } else { - _this4.setManualSize(selectedCol, _this4.newSize); // double click sets by auto row size plugin - } + if (!this.hot.getSelected()) { + return; + } + if (this.hot.getActiveEditor() && this.hot.getActiveEditor().isOpened()) { + return; + } + if ((0, _event.isImmediatePropagationStopped)(event)) { + return; + } + if (!this.textarea.isActive() && (0, _element.getSelectionText)()) { + return; + } - if (forceRender) { - render(); + if ((0, _unicode.isCtrlKey)(event.keyCode)) { + // When fragmentSelection is enabled and some text is selected then don't blur selection calling 'setCopyableText' + if (this.hot.getSettings().fragmentSelection && (0, _element.getSelectionText)()) { + return; } - _this4.saveManualColumnWidths(); - - _this4.hot.runHooks('afterColumnResize', selectedCol, _this4.newSize, true); - }; + // when CTRL is pressed, prepare selectable text in textarea + this.setCopyableText(); + (0, _event.stopImmediatePropagation)(event); - if (this.dblclick >= 2) { - var selectedColsLength = this.selectedCols.length; + return; + } - if (selectedColsLength > 1) { - (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { - resize(selectedCol); - }); - render(); - } else { - (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { - resize(selectedCol, true); - }); + // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL) + var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; + + if (ctrlDown) { + if (event.keyCode == _unicode.KEY_CODES.A) { + setTimeout(function () { + _this7.setCopyableText(); + }, 0); + } + if (event.keyCode == _unicode.KEY_CODES.X) { + this.cut(); + } + if (event.keyCode == _unicode.KEY_CODES.C) { + this.copy(); + } + if (event.keyCode == _unicode.KEY_CODES.V) { + this.triggerPaste(); } } - this.dblclick = 0; - this.autoresizeTimeout = null; } /** - * 'mousedown' event callback. - * - * @private - * @param {MouseEvent} e + * Destroy plugin instance. */ }, { - key: 'onMouseDown', - value: function onMouseDown(event) { - var _this5 = this; + key: 'destroy', + value: function destroy() { + if (this.textarea) { + this.textarea.destroy(); + } - if ((0, _element.hasClass)(event.target, 'manualColumnResizer')) { - this.setupGuidePosition(); - this.pressed = this.hot; + _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'destroy', this).call(this); + } + }]); - if (this.autoresizeTimeout === null) { - this.autoresizeTimeout = setTimeout(function () { - return _this5.afterMouseDownTimeout(); - }, 500); + return CopyPaste; +}(_base2.default); - this.hot._registerTimeout(this.autoresizeTimeout); - } - this.dblclick++; +(0, _plugins.registerPlugin)('CopyPaste', CopyPaste); - this.startX = (0, _event.pageX)(event); - this.newSize = this.startWidth; - } - } +exports.default = CopyPaste; - /** - * 'mousemove' event callback - refresh the handle and guide positions, cache the new column width. - * - * @private - * @param {MouseEvent} e - */ +/***/ }), +/* 277 */ +/***/ (function(module, exports, __webpack_require__) { - }, { - key: 'onMouseMove', - value: function onMouseMove(event) { - var _this6 = this; +"use strict"; - if (this.pressed) { - this.currentWidth = this.startWidth + ((0, _event.pageX)(event) - this.startX); - (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { - _this6.newSize = _this6.setManualSize(selectedCol, _this6.currentWidth); - }); +exports.__esModule = true; - this.refreshHandlePosition(); - this.refreshGuidePosition(); - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * @class Textarea + * + * @plugin CopyPaste + */ +var Textarea = function () { + _createClass(Textarea, null, [{ + key: 'getSingleton', + value: function getSingleton() { + globalSingleton.append(); + + return globalSingleton; } + }]); + + function Textarea() { + _classCallCheck(this, Textarea); /** - * 'mouseup' event callback - apply the column resizing. + * Main textarea element. * - * @private - * @param {MouseEvent} e + * @type {HTMLElement} */ + this.element = void 0; + /** + * Store information about append to the document.body. + * + * @type {Boolean} + */ + this.isAppended = false; + /** + * Reference counter. + * + * @type {Number} + */ + this.refCounter = 0; + } - }, { - key: 'onMouseUp', - value: function onMouseUp(event) { - var _this7 = this; - - var render = function render() { - _this7.hot.forceFullRender = true; - _this7.hot.view.render(); // updates all - _this7.hot.view.wt.wtOverlays.adjustElementsSize(true); - }; - var resize = function resize(selectedCol, forceRender) { - _this7.hot.runHooks('beforeColumnResize', selectedCol, _this7.newSize); - - if (forceRender) { - render(); - } - - _this7.saveManualColumnWidths(); + /** + * Apends textarea element to the `body` + */ - _this7.hot.runHooks('afterColumnResize', selectedCol, _this7.newSize); - }; - if (this.pressed) { - this.hideHandleAndGuide(); - this.pressed = false; + _createClass(Textarea, [{ + key: 'append', + value: function append() { + if (this.hasBeenDestroyed()) { + this.create(); + } - if (this.newSize != this.startWidth) { - var selectedColsLength = this.selectedCols.length; + this.refCounter++; - if (selectedColsLength > 1) { - (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { - resize(selectedCol); - }); - render(); - } else { - (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { - resize(selectedCol, true); - }); - } + if (!this.isAppended && document.body) { + if (document.body) { + this.isAppended = true; + document.body.appendChild(this.element); } - - this.setupHandlePosition(this.currentTH); } } /** - * Bind the mouse events. - * - * @private + * Prepares textarea element with proper attributes. */ }, { - key: 'bindEvents', - value: function bindEvents() { - var _this8 = this; - - this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) { - return _this8.onMouseOver(e); - }); - this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) { - return _this8.onMouseDown(e); - }); - this.eventManager.addEventListener(window, 'mousemove', function (e) { - return _this8.onMouseMove(e); - }); - this.eventManager.addEventListener(window, 'mouseup', function (e) { - return _this8.onMouseUp(e); - }); + key: 'create', + value: function create() { + this.element = document.createElement('textarea'); + this.element.id = 'HandsontableCopyPaste'; + this.element.className = 'copyPaste'; + this.element.tabIndex = -1; + this.element.autocomplete = 'off'; + this.element.wrap = 'off'; } /** - * Cache the current column width. - * - * @param {Number} column Visual column index. - * @param {Number} width Column width. - * @returns {Number} + * Deselects textarea element if is active. */ }, { - key: 'setManualSize', - value: function setManualSize(column, width) { - width = Math.max(width, 20); + key: 'deselect', + value: function deselect() { + if (this.element === document.activeElement) { + document.activeElement.blur(); + } + } - /** - * We need to run col through modifyCol hook, in case the order of displayed columns is different than the order - * in data source. For instance, this order can be modified by manualColumnMove plugin. - */ - column = this.hot.runHooks('modifyCol', column); + /** + * Destroy instance + */ - this.manualColumnWidths[column] = width; + }, { + key: 'destroy', + value: function destroy() { + this.refCounter--; + this.refCounter = this.refCounter < 0 ? 0 : this.refCounter; - return width; + if (this.hasBeenDestroyed() && this.element && this.element.parentNode) { + this.element.parentNode.removeChild(this.element); + this.element = null; + this.isAppended = false; + } } /** - * Clear cache for the current column index. + * Getter for the element. * - * @param {Number} column Visual column index. + * @returns {String} */ }, { - key: 'clearManualSize', - value: function clearManualSize(column) { - column = this.hot.runHooks('modifyCol', column); - - this.manualColumnWidths[column] = void 0; + key: 'getValue', + value: function getValue() { + return this.element.value; } /** - * Modify the provided column width, based on the plugin settings + * Check if instance has been destroyed * - * @private - * @param {Number} width Column width. - * @param {Number} column Visual column index. - * @returns {Number} + * @returns {Boolean} */ }, { - key: 'onModifyColWidth', - value: function onModifyColWidth(width, column) { - if (this.enabled) { - column = this.hot.runHooks('modifyCol', column); - - if (this.hot.getSettings().manualColumnResize && this.manualColumnWidths[column]) { - return this.manualColumnWidths[column]; - } - } - - return width; + key: 'hasBeenDestroyed', + value: function hasBeenDestroyed() { + return this.refCounter < 1; } /** - * Modify the provided column stretched width. This hook decides if specified column should be stretched or not. + * Check if the element is an active element in frame. * - * @private - * @param {Number} stretchedWidth Stretched width. - * @param {Number} column Physical column index. - * @returns {Number} + * @returns {Boolean} */ }, { - key: 'onBeforeStretchingColumnWidth', - value: function onBeforeStretchingColumnWidth(stretchedWidth, column) { - var width = this.manualColumnWidths[column]; + key: 'isActive', + value: function isActive() { + return this.element === document.activeElement; + } - if (width === void 0) { - width = stretchedWidth; - } + /** + * Sets focus on the element and select content. + */ - return width; + }, { + key: 'select', + value: function select() { + this.element.focus(); + this.element.select(); } /** - * `beforeColumnResize` hook callback. + * Setter for the element. * - * @private - * @param {Number} currentColumn Index of the resized column. - * @param {Number} newSize Calculated new column width. - * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click. + * @param {String} data Value which should be insert into the element. */ }, { - key: 'onBeforeColumnResize', - value: function onBeforeColumnResize() { - // clear the header height cache information - this.hot.view.wt.wtViewport.hasOversizedColumnHeadersMarked = {}; + key: 'setValue', + value: function setValue(data) { + this.element.value = data; } }]); - return ManualColumnResize; -}(_base2.default); + return Textarea; +}(); -(0, _plugins.registerPlugin)('manualColumnResize', ManualColumnResize); +var globalSingleton = new Textarea(); -exports.default = ManualColumnResize; +exports.default = Textarea; /***/ }), -/* 250 */ +/* 278 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; +exports.default = copyItem; +function copyItem(copyPastePlugin) { + return { + key: 'copy', + name: 'Copy', + callback: function callback() { + copyPastePlugin.setCopyableText(); + copyPastePlugin.copy(true); + }, + disabled: function disabled() { + return !copyPastePlugin.hot.getSelected(); + }, -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + hidden: false + }; +} -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; +/***/ }), +/* 279 */ +/***/ (function(module, exports, __webpack_require__) { -var _base = __webpack_require__(12); +"use strict"; -var _base2 = _interopRequireDefault(_base); -var _pluginHooks = __webpack_require__(8); +exports.__esModule = true; +exports.default = cutItem; +function cutItem(copyPastePlugin) { + return { + key: 'cut', + name: 'Cut', + callback: function callback() { + copyPastePlugin.setCopyableText(); + copyPastePlugin.cut(true); + }, + disabled: function disabled() { + return !copyPastePlugin.hot.getSelected(); + }, -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + hidden: false + }; +} -var _array = __webpack_require__(2); +/***/ }), +/* 280 */ +/***/ (function(module, exports) { -var _element = __webpack_require__(0); +// removed by extract-text-webpack-plugin -var _number = __webpack_require__(6); +/***/ }), +/* 281 */ +/***/ (function(module, exports, __webpack_require__) { -var _eventManager = __webpack_require__(4); +"use strict"; -var _eventManager2 = _interopRequireDefault(_eventManager); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _pluginHooks = __webpack_require__(7); + +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); var _plugins = __webpack_require__(5); -var _rowsMapper = __webpack_require__(251); +var _object = __webpack_require__(1); -var _rowsMapper2 = _interopRequireDefault(_rowsMapper); +var _src = __webpack_require__(12); -var _backlight = __webpack_require__(252); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _backlight2 = _interopRequireDefault(_backlight); +function CustomBorders() {} +/** * + * Current instance (table where borders should be placed) + */ +var instance; + +/** + * This plugin enables an option to apply custom borders through the context menu (configurable with context menu key `borders`). + * + * To initialize Handsontable with predefined custom borders, provide cell coordinates and border styles in a form of an array. + * + * See [Custom Borders](http://docs.handsontable.com/demo-custom-borders.html) demo for more examples. + * + * @example + * ```js + * ... + * customBorders: [ + * {range: { + * from: {row: 1, col: 1}, + * to: {row: 3, col: 4}}, + * left: {}, + * right: {}, + * top: {}, + * bottom: {} + * } + * ], + * ... + * + * // or + * ... + * customBorders: [ + * {row: 2, col: 2, left: {width: 2, color: 'red'}, + * right: {width: 1, color: 'green'}, top: '', bottom: ''} + * ], + * ... + * ``` + * @private + * @class CustomBorders + * @plugin CustomBorders + */ + +/** * + * Check if plugin should be enabled. + */ +var checkEnable = function checkEnable(customBorders) { + if (typeof customBorders === 'boolean') { + if (customBorders === true) { + return true; + } + } + if ((typeof customBorders === 'undefined' ? 'undefined' : _typeof(customBorders)) === 'object') { + if (customBorders.length > 0) { + return true; + } + } -var _guideline = __webpack_require__(253); + return false; +}; -var _guideline2 = _interopRequireDefault(_guideline); +/** * + * Initialize plugin. + */ +var init = function init() { + if (checkEnable(this.getSettings().customBorders)) { + if (!this.customBorders) { + instance = this; + this.customBorders = new CustomBorders(); + } + } +}; + +/** * + * Get index of border from the settings. + * + * @param {String} className + * @returns {Number} + */ +var getSettingIndex = function getSettingIndex(className) { + for (var i = 0; i < instance.view.wt.selections.length; i++) { + if (instance.view.wt.selections[i].settings.className == className) { + return i; + } + } + + return -1; +}; + +/** * + * Insert WalkontableSelection instance into Walkontable settings. + * + * @param border + */ +var insertBorderIntoSettings = function insertBorderIntoSettings(border) { + var coordinates = { + row: border.row, + col: border.col + }; + var selection = new _src.Selection(border, new _src.CellRange(coordinates, coordinates, coordinates)); + var index = getSettingIndex(border.className); + + if (index >= 0) { + instance.view.wt.selections[index] = selection; + } else { + instance.view.wt.selections.push(selection); + } +}; + +/** * + * Prepare borders from setting (single cell). + * + * @param {Number} row Visual row index. + * @param {Number} col Visual column index. + * @param borderObj + */ +var prepareBorderFromCustomAdded = function prepareBorderFromCustomAdded(row, col, borderObj) { + var border = createEmptyBorders(row, col); + border = extendDefaultBorder(border, borderObj); + this.setCellMeta(row, col, 'borders', border); + + insertBorderIntoSettings(border); +}; + +/** * + * Prepare borders from setting (object). + * + * @param {Object} rowObj + */ +var prepareBorderFromCustomAddedRange = function prepareBorderFromCustomAddedRange(rowObj) { + var range = rowObj.range; + + for (var row = range.from.row; row <= range.to.row; row++) { + for (var col = range.from.col; col <= range.to.col; col++) { + var border = createEmptyBorders(row, col); + var add = 0; + + if (row == range.from.row) { + add++; -var _src = __webpack_require__(11); + if ((0, _object.hasOwnProperty)(rowObj, 'top')) { + border.top = rowObj.top; + } + } -__webpack_require__(303); + if (row == range.to.row) { + add++; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if ((0, _object.hasOwnProperty)(rowObj, 'bottom')) { + border.bottom = rowObj.bottom; + } + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + if (col == range.from.col) { + add++; -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + if ((0, _object.hasOwnProperty)(rowObj, 'left')) { + border.left = rowObj.left; + } + } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + if (col == range.to.col) { + add++; -_pluginHooks2.default.getSingleton().register('beforeRowMove'); -_pluginHooks2.default.getSingleton().register('afterRowMove'); -_pluginHooks2.default.getSingleton().register('unmodifyRow'); + if ((0, _object.hasOwnProperty)(rowObj, 'right')) { + border.right = rowObj.right; + } + } -var privatePool = new WeakMap(); -var CSS_PLUGIN = 'ht__manualRowMove'; -var CSS_SHOW_UI = 'show-ui'; -var CSS_ON_MOVING = 'on-moving--rows'; -var CSS_AFTER_SELECTION = 'after-selection--rows'; + if (add > 0) { + this.setCellMeta(row, col, 'borders', border); + insertBorderIntoSettings(border); + } + } + } +}; -/** - * @plugin ManualRowMove - * - * @description - * This plugin allows to change rows order. - * - * API: - * - moveRow - move single row to the new position. - * - moveRows - move many rows (as an array of indexes) to the new position. +/** * + * Create separated class name for borders for each cell. * - * If you want apply visual changes, you have to call manually the render() method on the instance of handsontable. + * @param {Number} row Visual row index. + * @param {Number} col Visual column index. + * @returns {String} + */ +var createClassName = function createClassName(row, col) { + return 'border_row' + row + 'col' + col; +}; + +/** * + * Create default single border for each position (top/right/bottom/left). * - * UI components: - * - backlight - highlight of selected rows. - * - guideline - line which shows where rows has been moved. + * @returns {Object} `{{width: number, color: string}}` + */ +var createDefaultCustomBorder = function createDefaultCustomBorder() { + return { + width: 1, + color: '#000' + }; +}; + +/** * + * Create default object for empty border. * - * @class ManualRowMove - * @plugin ManualRowMove + * @returns {Object} `{{hide: boolean}}` */ +var createSingleEmptyBorder = function createSingleEmptyBorder() { + return { + hide: true + }; +}; -var ManualRowMove = function (_BasePlugin) { - _inherits(ManualRowMove, _BasePlugin); +/** * + * Create default Handsontable border object. + * + * @returns {Object} `{{width: number, color: string, cornerVisible: boolean}}` + */ +var createDefaultHtBorder = function createDefaultHtBorder() { + return { + width: 1, + color: '#000', + cornerVisible: false + }; +}; - function ManualRowMove(hotInstance) { - _classCallCheck(this, ManualRowMove); +/** * + * Prepare empty border for each cell with all custom borders hidden. + * + * @param {Number} row Visual row index. + * @param {Number} col Visual column index. + * @returns {Object} `{{className: *, border: *, row: *, col: *, top: {hide: boolean}, right: {hide: boolean}, bottom: {hide: boolean}, left: {hide: boolean}}}` + */ +var createEmptyBorders = function createEmptyBorders(row, col) { + return { + className: createClassName(row, col), + border: createDefaultHtBorder(), + row: row, + col: col, + top: createSingleEmptyBorder(), + right: createSingleEmptyBorder(), + bottom: createSingleEmptyBorder(), + left: createSingleEmptyBorder() + }; +}; - /** - * Set up WeakMap of plugin to sharing private parameters; - */ - var _this = _possibleConstructorReturn(this, (ManualRowMove.__proto__ || Object.getPrototypeOf(ManualRowMove)).call(this, hotInstance)); +var extendDefaultBorder = function extendDefaultBorder(defaultBorder, customBorder) { + if ((0, _object.hasOwnProperty)(customBorder, 'border')) { + defaultBorder.border = customBorder.border; + } - privatePool.set(_this, { - rowsToMove: [], - pressed: void 0, - disallowMoving: void 0, - target: { - eventPageY: void 0, - coords: void 0, - TD: void 0, - row: void 0 - } - }); + if ((0, _object.hasOwnProperty)(customBorder, 'top')) { + defaultBorder.top = customBorder.top; + } - /** - * List of last removed row indexes. - * - * @type {Array} - */ - _this.removedRows = []; - /** - * Object containing visual row indexes mapped to data source indexes. - * - * @type {RowsMapper} - */ - _this.rowsMapper = new _rowsMapper2.default(_this); - /** - * Event Manager object. - * - * @type {Object} - */ - _this.eventManager = new _eventManager2.default(_this); - /** - * Backlight UI object. - * - * @type {Object} - */ - _this.backlight = new _backlight2.default(hotInstance); - /** - * Guideline UI object. - * - * @type {Object} - */ - _this.guideline = new _guideline2.default(hotInstance); - return _this; + if ((0, _object.hasOwnProperty)(customBorder, 'right')) { + defaultBorder.right = customBorder.right; } - /** - * Check if plugin is enabled. - * - * @returns {Boolean} - */ + if ((0, _object.hasOwnProperty)(customBorder, 'bottom')) { + defaultBorder.bottom = customBorder.bottom; + } + if ((0, _object.hasOwnProperty)(customBorder, 'left')) { + defaultBorder.left = customBorder.left; + } - _createClass(ManualRowMove, [{ - key: 'isEnabled', - value: function isEnabled() { - return !!this.hot.getSettings().manualRowMove; - } + return defaultBorder; +}; - /** - * Enable the plugin. - */ +/** + * Remove borders divs from DOM. + * + * @param borderClassName + */ +var removeBordersFromDom = function removeBordersFromDom(borderClassName) { + var borders = document.querySelectorAll('.' + borderClassName); - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + for (var i = 0; i < borders.length; i++) { + if (borders[i]) { + if (borders[i].nodeName != 'TD') { + var parent = borders[i].parentNode; - if (this.enabled) { - return; + if (parent.parentNode) { + parent.parentNode.removeChild(parent); + } } - - this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) { - return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations); - }); - this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) { - return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations); - }); - this.addHook('afterScrollHorizontally', function () { - return _this2.onAfterScrollHorizontally(); - }); - this.addHook('modifyRow', function (row, source) { - return _this2.onModifyRow(row, source); - }); - this.addHook('beforeRemoveRow', function (index, amount) { - return _this2.onBeforeRemoveRow(index, amount); - }); - this.addHook('afterRemoveRow', function (index, amount) { - return _this2.onAfterRemoveRow(index, amount); - }); - this.addHook('afterCreateRow', function (index, amount) { - return _this2.onAfterCreateRow(index, amount); - }); - this.addHook('afterLoadData', function (firstTime) { - return _this2.onAfterLoadData(firstTime); - }); - this.addHook('beforeColumnSort', function (column, order) { - return _this2.onBeforeColumnSort(column, order); - }); - this.addHook('unmodifyRow', function (row) { - return _this2.onUnmodifyRow(row); - }); - - this.registerEvents(); - - // TODO: move adding plugin classname to BasePlugin. - (0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN); - - _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'enablePlugin', this).call(this); } + } +}; - /** - * Updates the plugin to use the latest options you have specified. - */ +/** * + * Remove border (triggered from context menu). + * + * @param {Number} row Visual row index. + * @param {Number} col Visual column index. + */ +var removeAllBorders = function removeAllBorders(row, col) { + var borderClassName = createClassName(row, col); + removeBordersFromDom(borderClassName); + this.removeCellMeta(row, col, 'borders'); +}; - }, { - key: 'updatePlugin', - value: function updatePlugin() { - this.disablePlugin(); - this.enablePlugin(); +/** * + * Set borders for each cell re. to border position + * + * @param row Visual row index. + * @param col Visual column index. + * @param place + * @param remove + */ +var setBorder = function setBorder(row, col, place, remove) { - this.onAfterPluginsInitialized(); + var bordersMeta = this.getCellMeta(row, col).borders; - _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'updatePlugin', this).call(this); - } + if (!bordersMeta || bordersMeta.border == undefined) { + bordersMeta = createEmptyBorders(row, col); + } - /** - * Disable plugin for this Handsontable instance. - */ + if (remove) { + bordersMeta[place] = createSingleEmptyBorder(); + } else { + bordersMeta[place] = createDefaultCustomBorder(); + } - }, { - key: 'disablePlugin', - value: function disablePlugin() { - var pluginSettings = this.hot.getSettings().manualRowMove; + this.setCellMeta(row, col, 'borders', bordersMeta); - if (Array.isArray(pluginSettings)) { - this.rowsMapper.clearMap(); - } + var borderClassName = createClassName(row, col); + removeBordersFromDom(borderClassName); + insertBorderIntoSettings(bordersMeta); - (0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN); + this.render(); +}; - this.unregisterEvents(); - this.backlight.destroy(); - this.guideline.destroy(); +/** * + * Prepare borders based on cell and border position + * + * @param range + * @param place + * @param remove + */ +var prepareBorder = function prepareBorder(range, place, remove) { - _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'disablePlugin', this).call(this); + if (range.from.row == range.to.row && range.from.col == range.to.col) { + if (place == 'noBorders') { + removeAllBorders.call(this, range.from.row, range.from.col); + } else { + setBorder.call(this, range.from.row, range.from.col, place, remove); } - - /** - * Move a single row. - * - * @param {Number} row Visual row index to be moved. - * @param {Number} target Visual row index being a target for the moved row. - */ - - }, { - key: 'moveRow', - value: function moveRow(row, target) { - this.moveRows([row], target); + } else { + switch (place) { + case 'noBorders': + for (var column = range.from.col; column <= range.to.col; column++) { + for (var row = range.from.row; row <= range.to.row; row++) { + removeAllBorders.call(this, row, column); + } + } + break; + case 'top': + for (var topCol = range.from.col; topCol <= range.to.col; topCol++) { + setBorder.call(this, range.from.row, topCol, place, remove); + } + break; + case 'right': + for (var rowRight = range.from.row; rowRight <= range.to.row; rowRight++) { + setBorder.call(this, rowRight, range.to.col, place); + } + break; + case 'bottom': + for (var bottomCol = range.from.col; bottomCol <= range.to.col; bottomCol++) { + setBorder.call(this, range.to.row, bottomCol, place); + } + break; + case 'left': + for (var rowLeft = range.from.row; rowLeft <= range.to.row; rowLeft++) { + setBorder.call(this, rowLeft, range.from.col, place); + } + break; + default: + break; } + } +}; - /** - * Move multiple rows. - * - * @param {Array} rows Array of visual row indexes to be moved. - * @param {Number} target Visual row index being a target for the moved rows. - */ +/** * + * Check if selection has border by className + * + * @param hot + * @param direction + */ +var checkSelectionBorders = function checkSelectionBorders(hot, direction) { + var atLeastOneHasBorder = false; - }, { - key: 'moveRows', - value: function moveRows(rows, target) { - var _this3 = this; + hot.getSelectedRange().forAll(function (r, c) { + var metaBorders = hot.getCellMeta(r, c).borders; - var priv = privatePool.get(this); - var beforeMoveHook = this.hot.runHooks('beforeRowMove', rows, target); + if (metaBorders) { + if (direction) { + if (!(0, _object.hasOwnProperty)(metaBorders[direction], 'hide')) { + atLeastOneHasBorder = true; + return false; // breaks forAll + } + } else { + atLeastOneHasBorder = true; + return false; // breaks forAll + } + } + }); + return atLeastOneHasBorder; +}; - priv.disallowMoving = beforeMoveHook === false; +/** * + * Mark label in contextMenu as selected + * + * @param label + * @returns {string} + */ +var markSelected = function markSelected(label) { + return '' + String.fromCharCode(10003) + '' + label; // workaround for https://github.com/handsontable/handsontable/issues/1946 +}; - if (!priv.disallowMoving) { - // first we need to rewrite an visual indexes to physical for save reference after move - (0, _array.arrayEach)(rows, function (row, index, array) { - array[index] = _this3.rowsMapper.getValueByIndex(row); - }); +/** * + * Add border options to context menu + * + * @param defaultOptions + */ +var addBordersOptionsToContextMenu = function addBordersOptionsToContextMenu(defaultOptions) { + if (!this.getSettings().customBorders) { + return; + } - // next, when we have got an physical indexes, we can move rows - (0, _array.arrayEach)(rows, function (row, index) { - var actualPosition = _this3.rowsMapper.getIndexByValue(row); + defaultOptions.items.push({ + name: '---------' + }); + defaultOptions.items.push({ + key: 'borders', + name: 'Borders', + disabled: function disabled() { + return this.selection.selectedHeader.corner; + }, - if (actualPosition !== target) { - _this3.rowsMapper.moveRow(actualPosition, target + index); + submenu: { + items: [{ + key: 'borders:top', + name: function name() { + var label = 'Top'; + var hasBorder = checkSelectionBorders(this, 'top'); + if (hasBorder) { + label = markSelected(label); } - }); - // after moving we have to clear rowsMapper from null entries - this.rowsMapper.clearNull(); - } + return label; + }, + callback: function callback() { + var hasBorder = checkSelectionBorders(this, 'top'); + prepareBorder.call(this, this.getSelectedRange(), 'top', hasBorder); + } + }, { + key: 'borders:right', + name: function name() { + var label = 'Right'; + var hasBorder = checkSelectionBorders(this, 'right'); + if (hasBorder) { + label = markSelected(label); + } + return label; + }, + callback: function callback() { + var hasBorder = checkSelectionBorders(this, 'right'); + prepareBorder.call(this, this.getSelectedRange(), 'right', hasBorder); + } + }, { + key: 'borders:bottom', + name: function name() { + var label = 'Bottom'; + var hasBorder = checkSelectionBorders(this, 'bottom'); + if (hasBorder) { + label = markSelected(label); + } + return label; + }, + callback: function callback() { + var hasBorder = checkSelectionBorders(this, 'bottom'); + prepareBorder.call(this, this.getSelectedRange(), 'bottom', hasBorder); + } + }, { + key: 'borders:left', + name: function name() { + var label = 'Left'; + var hasBorder = checkSelectionBorders(this, 'left'); + if (hasBorder) { + label = markSelected(label); + } + + return label; + }, + callback: function callback() { + var hasBorder = checkSelectionBorders(this, 'left'); + prepareBorder.call(this, this.getSelectedRange(), 'left', hasBorder); + } + }, { + key: 'borders:no_borders', + name: 'Remove border(s)', + callback: function callback() { + prepareBorder.call(this, this.getSelectedRange(), 'noBorders'); + }, + disabled: function disabled() { + return !checkSelectionBorders(this); + } + }] + } + }); +}; + +_pluginHooks2.default.getSingleton().add('beforeInit', init); +_pluginHooks2.default.getSingleton().add('afterContextMenuDefaultOptions', addBordersOptionsToContextMenu); +_pluginHooks2.default.getSingleton().add('afterInit', function () { + var customBorders = this.getSettings().customBorders; - this.hot.runHooks('afterRowMove', rows, target); + if (customBorders) { + for (var i = 0; i < customBorders.length; i++) { + if (customBorders[i].range) { + prepareBorderFromCustomAddedRange.call(this, customBorders[i]); + } else { + prepareBorderFromCustomAdded.call(this, customBorders[i].row, customBorders[i].col, customBorders[i]); + } } - /** - * Correct the cell selection after the move action. Fired only when action was made with a mouse. - * That means that changing the row order using the API won't correct the selection. - * - * @private - * @param {Number} startRow Visual row index for the start of the selection. - * @param {Number} endRow Visual row index for the end of the selection. - */ + this.render(); + this.view.wt.draw(true); + } +}); - }, { - key: 'changeSelection', - value: function changeSelection(startRow, endRow) { - var selection = this.hot.selection; - var lastColIndex = this.hot.countCols() - 1; +/***/ }), +/* 282 */ +/***/ (function(module, exports, __webpack_require__) { - selection.setRangeStartOnly(new _src.CellCoords(startRow, 0)); - selection.setRangeEnd(new _src.CellCoords(endRow, lastColIndex), false); - } +"use strict"; - /** - * Get the sum of the heights of rows in the provided range. - * - * @private - * @param {Number} from Visual row index. - * @param {Number} to Visual row index. - * @returns {Number} - */ - }, { - key: 'getRowsHeight', - value: function getRowsHeight(from, to) { - var height = 0; +exports.__esModule = true; - for (var i = from; i < to; i++) { - var rowHeight = this.hot.view.wt.wtTable.getRowHeight(i) || 23; +var _pluginHooks = __webpack_require__(7); - height += rowHeight; - } +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - return height; - } +var _eventManager = __webpack_require__(4); - /** - * Load initial settings when persistent state is saved or when plugin was initialized as an array. - * - * @private - */ +var _eventManager2 = _interopRequireDefault(_eventManager); - }, { - key: 'initialSettings', - value: function initialSettings() { - var pluginSettings = this.hot.getSettings().manualRowMove; +var _plugins = __webpack_require__(5); - if (Array.isArray(pluginSettings)) { - this.moveRows(pluginSettings, 0); - } else if (pluginSettings !== void 0) { - var persistentState = this.persistentStateLoad(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (persistentState.length) { - this.moveRows(persistentState, 0); - } - } - } +/** + * @description + * Plugin used to scroll Handsontable by selecting a cell and dragging outside of the visible viewport. + * + * @private + * @class DragToScroll + * @plugin DragToScroll + */ +function DragToScroll() { + this.boundaries = null; + this.callback = null; +} - /** - * Check if the provided row is in the fixedRowsTop section. - * - * @private - * @param {Number} row Visual row index to check. - * @returns {Boolean} - */ +/** + * @param boundaries {Object} compatible with getBoundingClientRect + */ +DragToScroll.prototype.setBoundaries = function (boundaries) { + this.boundaries = boundaries; +}; - }, { - key: 'isFixedRowTop', - value: function isFixedRowTop(row) { - return row < this.hot.getSettings().fixedRowsTop; - } +/** + * @param callback {Function} + */ +DragToScroll.prototype.setCallback = function (callback) { + this.callback = callback; +}; - /** - * Check if the provided row is in the fixedRowsBottom section. - * - * @private - * @param {Number} row Visual row index to check. - * @returns {Boolean} - */ +/** + * Check if mouse position (x, y) is outside of the viewport + * @param x + * @param y + */ +DragToScroll.prototype.check = function (x, y) { + var diffX = 0; + var diffY = 0; - }, { - key: 'isFixedRowBottom', - value: function isFixedRowBottom(row) { - return row > this.hot.getSettings().fixedRowsBottom; - } + if (y < this.boundaries.top) { + // y is less than top + diffY = y - this.boundaries.top; + } else if (y > this.boundaries.bottom) { + // y is more than bottom + diffY = y - this.boundaries.bottom; + } - /** - * Save the manual row positions to the persistent state. - * - * @private - */ + if (x < this.boundaries.left) { + // x is less than left + diffX = x - this.boundaries.left; + } else if (x > this.boundaries.right) { + // x is more than right + diffX = x - this.boundaries.right; + } - }, { - key: 'persistentStateSave', - value: function persistentStateSave() { - this.hot.runHooks('persistentStateSave', 'manualRowMove', this.rowsMapper._arrayMap); - } + this.callback(diffX, diffY); +}; - /** - * Load the manual row positions from the persistent state. - * - * @private - * @returns {Array} Stored state. - */ +var dragToScroll; +var instance; - }, { - key: 'persistentStateLoad', - value: function persistentStateLoad() { - var storedState = {}; +var setupListening = function setupListening(instance) { + instance.dragToScrollListening = false; + var scrollHandler = instance.view.wt.wtTable.holder; // native scroll + dragToScroll = new DragToScroll(); - this.hot.runHooks('persistentStateLoad', 'manualRowMove', storedState); + if (scrollHandler === window) { + // not much we can do currently + return; + } - return storedState.value ? storedState.value : []; + dragToScroll.setBoundaries(scrollHandler.getBoundingClientRect()); + dragToScroll.setCallback(function (scrollX, scrollY) { + if (scrollX < 0) { + scrollHandler.scrollLeft -= 50; + } else if (scrollX > 0) { + scrollHandler.scrollLeft += 50; } - /** - * Prepare array of indexes based on actual selection. - * - * @private - * @returns {Array} - */ - - }, { - key: 'prepareRowsToMoving', - value: function prepareRowsToMoving() { - var selection = this.hot.getSelectedRange(); - var selectedRows = []; - - if (!selection) { - return selectedRows; - } + if (scrollY < 0) { + scrollHandler.scrollTop -= 20; + } else if (scrollY > 0) { + scrollHandler.scrollTop += 20; + } + }); - var from = selection.from, - to = selection.to; + instance.dragToScrollListening = true; +}; - var start = Math.min(from.row, to.row); - var end = Math.max(from.row, to.row); +_pluginHooks2.default.getSingleton().add('afterInit', function () { + var instance = this; + var eventManager = new _eventManager2.default(this); - (0, _number.rangeEach)(start, end, function (i) { - selectedRows.push(i); - }); + eventManager.addEventListener(document, 'mouseup', function () { + instance.dragToScrollListening = false; + }); - return selectedRows; + eventManager.addEventListener(document, 'mousemove', function (event) { + if (instance.dragToScrollListening) { + dragToScroll.check(event.clientX, event.clientY); } + }); +}); - /** - * Update the UI visual position. - * - * @private - */ +_pluginHooks2.default.getSingleton().add('afterDestroy', function () { + new _eventManager2.default(this).clear(); +}); - }, { - key: 'refreshPositions', - value: function refreshPositions() { - var priv = privatePool.get(this); - var coords = priv.target.coords; - var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleRow(); - var lastVisible = this.hot.view.wt.wtTable.getLastVisibleRow(); - var fixedRows = this.hot.getSettings().fixedRowsTop; - var countRows = this.hot.countRows(); +_pluginHooks2.default.getSingleton().add('afterOnCellMouseDown', function () { + setupListening(this); +}); - if (coords.row < fixedRows && firstVisible > 0) { - this.hot.scrollViewportTo(firstVisible - 1); - } - if (coords.row >= lastVisible && lastVisible < countRows) { - this.hot.scrollViewportTo(lastVisible + 1, undefined, true); - } +_pluginHooks2.default.getSingleton().add('afterOnCellCornerMouseDown', function () { + setupListening(this); +}); - var wtTable = this.hot.view.wt.wtTable; - var TD = priv.target.TD; - var rootElementOffset = (0, _element.offset)(this.hot.rootElement); - var tdOffsetTop = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row); - var mouseOffsetTop = priv.target.eventPageY - rootElementOffset.top + wtTable.holder.scrollTop; - var hiderHeight = wtTable.hider.offsetHeight; - var tbodyOffsetTop = wtTable.TBODY.offsetTop; - var backlightElemMarginTop = this.backlight.getOffset().top; - var backlightElemHeight = this.backlight.getSize().height; +exports.default = DragToScroll; - if (this.isFixedRowTop(coords.row)) { - tdOffsetTop += wtTable.holder.scrollTop; - } +/***/ }), +/* 283 */ +/***/ (function(module, exports, __webpack_require__) { - // todo: fixedRowsBottom - // if (this.isFixedRowBottom(coords.row)) { - // - // } +"use strict"; - if (coords.row < 0) { - // if hover on colHeader - priv.target.row = firstVisible > 0 ? firstVisible - 1 : firstVisible; - } else if (TD.offsetHeight / 2 + tdOffsetTop <= mouseOffsetTop) { - // if hover on lower part of TD - priv.target.row = coords.row + 1; - // unfortunately first row is bigger than rest - tdOffsetTop += coords.row === 0 ? TD.offsetHeight - 1 : TD.offsetHeight; - } else { - // elsewhere on table - priv.target.row = coords.row; - } - var backlightTop = mouseOffsetTop; - var guidelineTop = tdOffsetTop; +exports.__esModule = true; - if (mouseOffsetTop + backlightElemHeight + backlightElemMarginTop >= hiderHeight) { - // prevent display backlight below table - backlightTop = hiderHeight - backlightElemHeight - backlightElemMarginTop; - } else if (mouseOffsetTop + backlightElemMarginTop < tbodyOffsetTop) { - // prevent display above below table - backlightTop = tbodyOffsetTop + Math.abs(backlightElemMarginTop); - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (tdOffsetTop >= hiderHeight - 1) { - // prevent display guideline below table - guidelineTop = hiderHeight - 1; - } +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var topOverlayHeight = 0; - if (this.hot.view.wt.wtOverlays.topOverlay) { - topOverlayHeight = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.TABLE.offsetHeight; - } +var _base = __webpack_require__(13); - if (coords.row >= fixedRows && guidelineTop - wtTable.holder.scrollTop < topOverlayHeight) { - this.hot.scrollViewportTo(coords.row); - } +var _base2 = _interopRequireDefault(_base); - this.backlight.setPosition(backlightTop); - this.guideline.setPosition(guidelineTop); - } +var _plugins = __webpack_require__(5); - /** - * This method checks arrayMap from rowsMapper and updates the rowsMapper if it's necessary. - * - * @private - */ +var _array = __webpack_require__(2); - }, { - key: 'updateRowsMapper', - value: function updateRowsMapper() { - var countRows = this.hot.countSourceRows(); - var rowsMapperLen = this.rowsMapper._arrayMap.length; +var _freezeColumn = __webpack_require__(284); - if (rowsMapperLen === 0) { - this.rowsMapper.createMap(countRows || this.hot.getSettings().startRows); - } else if (rowsMapperLen < countRows) { - var diff = countRows - rowsMapperLen; +var _freezeColumn2 = _interopRequireDefault(_freezeColumn); - this.rowsMapper.insertItems(rowsMapperLen, diff); - } else if (rowsMapperLen > countRows) { - var maxIndex = countRows - 1; - var rowsToRemove = []; +var _unfreezeColumn = __webpack_require__(285); - (0, _array.arrayEach)(this.rowsMapper._arrayMap, function (value, index, array) { - if (value > maxIndex) { - rowsToRemove.push(index); - } - }); +var _unfreezeColumn2 = _interopRequireDefault(_unfreezeColumn); - this.rowsMapper.removeItems(rowsToRemove); - } - } +__webpack_require__(286); - /** - * Bind the events used by the plugin. - * - * @private - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - }, { - key: 'registerEvents', - value: function registerEvents() { - var _this4 = this; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) { - return _this4.onMouseMove(event); - }); - this.eventManager.addEventListener(document.documentElement, 'mouseup', function () { - return _this4.onMouseUp(); - }); - } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - /** - * Unbind the events used by the plugin. - * - * @private - */ +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - }, { - key: 'unregisterEvents', - value: function unregisterEvents() { - this.eventManager.clear(); - } +var privatePool = new WeakMap(); +/** + * This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu. + * You can turn it on by setting a `manualColumnFreeze` property to `true`. + * + * @plugin ManualColumnFreeze + * @dependencies ManualColumnMove + */ - /** - * `beforeColumnSort` hook callback. If user uses the sorting, manual row moving is disabled. - * - * @private - * @param {Number} column Column index where soring is present - * @param {*} order State of sorting. ASC/DESC/None - */ +var ManualColumnFreeze = function (_BasePlugin) { + _inherits(ManualColumnFreeze, _BasePlugin); - }, { - key: 'onBeforeColumnSort', - value: function onBeforeColumnSort(column, order) { - var priv = privatePool.get(this); + function ManualColumnFreeze(hotInstance) { + _classCallCheck(this, ManualColumnFreeze); - priv.disallowMoving = order !== void 0; - } + var _this = _possibleConstructorReturn(this, (ManualColumnFreeze.__proto__ || Object.getPrototypeOf(ManualColumnFreeze)).call(this, hotInstance)); + privatePool.set(_this, { + moveByFreeze: false, + afterFirstUse: false + }); /** - * Change the behavior of selection / dragging. + * Original column positions * - * @private - * @param {MouseEvent} event - * @param {CellCoords} coords Visual coordinates. - * @param {HTMLElement} TD - * @param {Object} blockCalculations + * @type {Array} */ + _this.frozenColumnsBasePositions = []; + /** + * Reference to the `ManualColumnMove` plugin. + */ + _this.manualColumnMovePlugin = void 0; + return _this; + } - }, { - key: 'onBeforeOnCellMouseDown', - value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) { - var wtTable = this.hot.view.wt.wtTable; - var isHeaderSelection = this.hot.selection.selectedHeader.rows; - var selection = this.hot.getSelectedRange(); - var priv = privatePool.get(this); - - if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0) { - priv.pressed = false; - priv.rowsToMove.length = 0; - (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]); - return; - } - - var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended(); - var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended(); - - if (guidelineIsNotReady && backlightIsNotReady) { - this.guideline.appendTo(wtTable.hider); - this.backlight.appendTo(wtTable.hider); - } - - var from = selection.from, - to = selection.to; - - var start = Math.min(from.row, to.row); - var end = Math.max(from.row, to.row); - - if (coords.col < 0 && coords.row >= start && coords.row <= end) { - blockCalculations.row = true; - priv.pressed = true; - priv.target.eventPageY = event.pageY; - priv.target.coords = coords; - priv.target.TD = TD; - priv.rowsToMove = this.prepareRowsToMoving(); - - var leftPos = wtTable.holder.scrollLeft + wtTable.getColumnWidth(-1); - - this.backlight.setPosition(null, leftPos); - this.backlight.setSize(wtTable.hider.offsetWidth - leftPos, this.getRowsHeight(start, end + 1)); - this.backlight.setOffset((this.getRowsHeight(start, coords.row) + event.layerY) * -1, null); + /** + * Check if the plugin is enabled in the Handsontable settings. + * + * @returns {Boolean} + */ - (0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING); - this.refreshPositions(); - } else { - (0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION); - priv.pressed = false; - priv.rowsToMove.length = 0; - } + _createClass(ManualColumnFreeze, [{ + key: 'isEnabled', + value: function isEnabled() { + return !!this.hot.getSettings().manualColumnFreeze; } /** - * 'mouseMove' event callback. Fired when pointer move on document.documentElement. - * - * @private - * @param {MouseEvent} event `mousemove` event properties. + * Enable plugin for this Handsontable instance. */ }, { - key: 'onMouseMove', - value: function onMouseMove(event) { - var priv = privatePool.get(this); + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; - if (!priv.pressed) { + if (this.enabled) { return; } - // callback for browser which doesn't supports CSS pointer-event: none - if (event.realTarget === this.backlight.element) { - var height = this.backlight.getSize().height; - this.backlight.setSize(null, 0); - - setTimeout(function () { - this.backlight.setPosition(null, height); - }); - } + this.addHook('afterContextMenuDefaultOptions', function (options) { + return _this2.addContextMenuEntry(options); + }); + this.addHook('afterInit', function () { + return _this2.onAfterInit(); + }); + this.addHook('beforeColumnMove', function (rows, target) { + return _this2.onBeforeColumnMove(rows, target); + }); - priv.target.eventPageY = event.pageY; - this.refreshPositions(); + _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'enablePlugin', this).call(this); } /** - * 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell. - * - * @private - * @param {MouseEvent} event `mouseover` event properties. - * @param {CellCoords} coords Visual cell coordinates where was fired event. - * @param {HTMLElement} TD Cell represented as HTMLElement. - * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells. + * Disable plugin for this Handsontable instance. */ }, { - key: 'onBeforeOnCellMouseOver', - value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) { - var selectedRange = this.hot.getSelectedRange(); + key: 'disablePlugin', + value: function disablePlugin() { var priv = privatePool.get(this); - if (!selectedRange || !priv.pressed) { - return; - } + priv.afterFirstUse = false; + priv.moveByFreeze = false; - if (priv.rowsToMove.indexOf(coords.row) > -1) { - (0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI); - } else { - (0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI); - } + _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'disablePlugin', this).call(this); + } - blockCalculations.row = true; - blockCalculations.column = true; - blockCalculations.cell = true; - priv.target.coords = coords; - priv.target.TD = TD; + /** + * Updates the plugin to use the latest options you have specified. + */ + + }, { + key: 'updatePlugin', + value: function updatePlugin() { + this.disablePlugin(); + this.enablePlugin(); + + _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'updatePlugin', this).call(this); } /** - * `onMouseUp` hook callback. + * Freeze the given column (add it to fixed columns). * - * @private + * @param {Number} column Visual column index. */ }, { - key: 'onMouseUp', - value: function onMouseUp() { + key: 'freezeColumn', + value: function freezeColumn(column) { var priv = privatePool.get(this); - var target = priv.target.row; - var rowsLen = priv.rowsToMove.length; - - priv.pressed = false; - priv.backlightHeight = 0; - - (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]); + var settings = this.hot.getSettings(); - if (this.hot.selection.selectedHeader.rows) { - (0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION); + if (!priv.afterFirstUse) { + priv.afterFirstUse = true; } - if (rowsLen < 1 || target === void 0 || priv.rowsToMove.indexOf(target) > -1 || priv.rowsToMove[rowsLen - 1] === target - 1) { - return; + if (settings.fixedColumnsLeft === this.hot.countCols() || column <= settings.fixedColumnsLeft - 1) { + return; // already fixed } - this.moveRows(priv.rowsToMove, target); - - this.persistentStateSave(); - this.hot.render(); + priv.moveByFreeze = true; - if (!priv.disallowMoving) { - var selectionStart = this.rowsMapper.getIndexByValue(priv.rowsToMove[0]); - var selectionEnd = this.rowsMapper.getIndexByValue(priv.rowsToMove[rowsLen - 1]); - this.changeSelection(selectionStart, selectionEnd); + if (column !== this.getMovePlugin().columnsMapper.getValueByIndex(column)) { + this.frozenColumnsBasePositions[settings.fixedColumnsLeft] = column; } - priv.rowsToMove.length = 0; + this.getMovePlugin().moveColumn(column, settings.fixedColumnsLeft++); } /** - * `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally. + * Unfreeze the given column (remove it from fixed columns and bring to it's previous position). * - * @private + * @param {Number} column Visual column index. */ }, { - key: 'onAfterScrollHorizontally', - value: function onAfterScrollHorizontally() { - var wtTable = this.hot.view.wt.wtTable; - var headerWidth = wtTable.getColumnWidth(-1); - var scrollLeft = wtTable.holder.scrollLeft; - var posLeft = headerWidth + scrollLeft; + key: 'unfreezeColumn', + value: function unfreezeColumn(column) { + var priv = privatePool.get(this); + var settings = this.hot.getSettings(); - this.backlight.setPosition(null, posLeft); - this.backlight.setSize(wtTable.hider.offsetWidth - posLeft); + if (!priv.afterFirstUse) { + priv.afterFirstUse = true; + } + + if (settings.fixedColumnsLeft <= 0 || column > settings.fixedColumnsLeft - 1) { + return; // not fixed + } + + var returnCol = this.getBestColumnReturnPosition(column); + + priv.moveByFreeze = true; + settings.fixedColumnsLeft--; + + this.getMovePlugin().moveColumn(column, returnCol + 1); } /** - * `afterCreateRow` hook callback. + * Get the reference to the ManualColumnMove plugin. * * @private - * @param {Number} index Visual index of the created row. - * @param {Number} amount Amount of created rows. + * @returns {Object} */ }, { - key: 'onAfterCreateRow', - value: function onAfterCreateRow(index, amount) { - this.rowsMapper.shiftItems(index, amount); + key: 'getMovePlugin', + value: function getMovePlugin() { + if (!this.manualColumnMovePlugin) { + this.manualColumnMovePlugin = this.hot.getPlugin('manualColumnMove'); + } + + return this.manualColumnMovePlugin; } /** - * On before remove row listener. + * Estimates the most fitting return position for unfrozen column. * * @private - * @param {Number} index Visual row index. - * @param {Number} amount Defines how many rows removed. + * @param {Number} column Visual column index. */ }, { - key: 'onBeforeRemoveRow', - value: function onBeforeRemoveRow(index, amount) { - var _this5 = this; + key: 'getBestColumnReturnPosition', + value: function getBestColumnReturnPosition(column) { + var movePlugin = this.getMovePlugin(); + var settings = this.hot.getSettings(); + var i = settings.fixedColumnsLeft; + var j = movePlugin.columnsMapper.getValueByIndex(i); + var initialCol = void 0; - this.removedRows.length = 0; + if (this.frozenColumnsBasePositions[column] == null) { + initialCol = movePlugin.columnsMapper.getValueByIndex(column); - if (index !== false) { - // Collect physical row index. - (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) { - _this5.removedRows.push(_this5.hot.runHooks('modifyRow', removedIndex, _this5.pluginName)); - }); - } - } + while (j < initialCol) { + i++; + j = movePlugin.columnsMapper.getValueByIndex(i); + } + } else { + initialCol = this.frozenColumnsBasePositions[column]; + this.frozenColumnsBasePositions[column] = void 0; - /** - * `afterRemoveRow` hook callback. - * - * @private - * @param {Number} index Visual index of the removed row. - * @param {Number} amount Amount of removed rows. - */ + while (j <= initialCol) { + i++; + j = movePlugin.columnsMapper.getValueByIndex(i); + } + i = j; + } - }, { - key: 'onAfterRemoveRow', - value: function onAfterRemoveRow(index, amount) { - this.rowsMapper.unshiftItems(this.removedRows); + return i - 1; } - /** - * `afterLoadData` hook callback. + * Add the manualColumnFreeze context menu entries. * * @private - * @param {Boolean} firstTime True if that was loading data during the initialization. + * @param {Object} options Context menu options. */ }, { - key: 'onAfterLoadData', - value: function onAfterLoadData(firstTime) { - this.updateRowsMapper(); + key: 'addContextMenuEntry', + value: function addContextMenuEntry(options) { + options.items.push({ name: '---------' }, (0, _freezeColumn2.default)(this), (0, _unfreezeColumn2.default)(this)); } /** - * 'modifyRow' hook callback. + * Enabling `manualColumnMove` plugin on `afterInit` hook. * * @private - * @param {Number} row Visual Row index. - * @returns {Number} Physical row index. */ }, { - key: 'onModifyRow', - value: function onModifyRow(row, source) { - if (source !== this.pluginName) { - var rowInMapper = this.rowsMapper.getValueByIndex(row); - row = rowInMapper === null ? row : rowInMapper; + key: 'onAfterInit', + value: function onAfterInit() { + if (!this.getMovePlugin().isEnabled()) { + this.getMovePlugin().enablePlugin(); } - - return row; } /** - * 'unmodifyRow' hook callback. + * Prevent moving the rows from/to fixed area. * * @private - * @param {Number} row Physical row index. - * @returns {Number} Visual row index. + * @param {Array} rows + * @param {Number} target */ }, { - key: 'onUnmodifyRow', - value: function onUnmodifyRow(row) { - var indexInMapper = this.rowsMapper.getIndexByValue(row); + key: 'onBeforeColumnMove', + value: function onBeforeColumnMove(rows, target) { + var priv = privatePool.get(this); - return indexInMapper === null ? row : indexInMapper; - } + if (priv.afterFirstUse && !priv.moveByFreeze) { + var frozenLen = this.hot.getSettings().fixedColumnsLeft; + var disallowMoving = target < frozenLen; - /** - * `afterPluginsInitialized` hook callback. - * - * @private - */ + if (!disallowMoving) { + (0, _array.arrayEach)(rows, function (value, index, array) { + if (value < frozenLen) { + disallowMoving = true; + return false; + } + }); + } - }, { - key: 'onAfterPluginsInitialized', - value: function onAfterPluginsInitialized() { - this.updateRowsMapper(); - this.initialSettings(); - this.backlight.build(); - this.guideline.build(); + if (disallowMoving) { + return false; + } + } + + if (priv.moveByFreeze) { + priv.moveByFreeze = false; + } } /** @@ -59502,22 +59705,97 @@ var ManualRowMove = function (_BasePlugin) { }, { key: 'destroy', value: function destroy() { - this.backlight.destroy(); - this.guideline.destroy(); - - _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'destroy', this).call(this); + _get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'destroy', this).call(this); } }]); - return ManualRowMove; + return ManualColumnFreeze; }(_base2.default); -(0, _plugins.registerPlugin)('ManualRowMove', ManualRowMove); +(0, _plugins.registerPlugin)('manualColumnFreeze', ManualColumnFreeze); -exports.default = ManualRowMove; +exports.default = ManualColumnFreeze; /***/ }), -/* 251 */ +/* 284 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; +exports.default = freezeColumnItem; +function freezeColumnItem(manualColumnFreezePlugin) { + return { + key: 'freeze_column', + name: 'Freeze this column', + callback: function callback() { + var selectedColumn = this.getSelectedRange().from.col; + + manualColumnFreezePlugin.freezeColumn(selectedColumn); + + this.render(); + this.view.wt.wtOverlays.adjustElementsSize(true); + }, + hidden: function hidden() { + var selection = this.getSelectedRange(); + var hide = false; + + if (selection === void 0) { + hide = true; + } else if (selection.from.col !== selection.to.col || selection.from.col <= this.getSettings().fixedColumnsLeft - 1) { + hide = true; + } + + return hide; + } + }; +} + +/***/ }), +/* 285 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; +exports.default = unfreezeColumnItem; +function unfreezeColumnItem(manualColumnFreezePlugin) { + return { + key: 'unfreeze_column', + name: 'Unfreeze this column', + callback: function callback() { + var selectedColumn = this.getSelectedRange().from.col; + + manualColumnFreezePlugin.unfreezeColumn(selectedColumn); + + this.render(); + this.view.wt.wtOverlays.adjustElementsSize(true); + }, + hidden: function hidden() { + var selection = this.getSelectedRange(); + var hide = false; + + if (selection === void 0) { + hide = true; + } else if (selection.from.col !== selection.to.col || selection.from.col >= this.getSettings().fixedColumnsLeft) { + hide = true; + } + + return hide; + } + }; +} + +/***/ }), +/* 286 */ +/***/ (function(module, exports) { + +// removed by extract-text-webpack-plugin + +/***/ }), +/* 287 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59527,811 +59805,1010 @@ exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _arrayMapper = __webpack_require__(151); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var _arrayMapper2 = _interopRequireDefault(_arrayMapper); +var _base = __webpack_require__(13); + +var _base2 = _interopRequireDefault(_base); + +var _pluginHooks = __webpack_require__(7); + +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); var _array = __webpack_require__(2); -var _object = __webpack_require__(1); +var _element = __webpack_require__(0); var _number = __webpack_require__(6); +var _eventManager = __webpack_require__(4); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +var _plugins = __webpack_require__(5); + +var _columnsMapper = __webpack_require__(288); + +var _columnsMapper2 = _interopRequireDefault(_columnsMapper); + +var _backlight = __webpack_require__(289); + +var _backlight2 = _interopRequireDefault(_backlight); + +var _guideline = __webpack_require__(290); + +var _guideline2 = _interopRequireDefault(_guideline); + +var _src = __webpack_require__(12); + +__webpack_require__(291); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +_pluginHooks2.default.getSingleton().register('beforeColumnMove'); +_pluginHooks2.default.getSingleton().register('afterColumnMove'); +_pluginHooks2.default.getSingleton().register('unmodifyCol'); + +var privatePool = new WeakMap(); +var CSS_PLUGIN = 'ht__manualColumnMove'; +var CSS_SHOW_UI = 'show-ui'; +var CSS_ON_MOVING = 'on-moving--columns'; +var CSS_AFTER_SELECTION = 'after-selection--columns'; + /** - * @class RowsMapper - * @plugin ManualRowMove + * @plugin ManualColumnMove + * + * @description + * This plugin allows to change columns order. + * + * API: + * - moveColumn - move single column to the new position. + * - moveColumns - move many columns (as an array of indexes) to the new position. + * + * If you want apply visual changes, you have to call manually the render() method on the instance of Handsontable. + * + * UI components: + * - backlight - highlight of selected columns. + * - guideline - line which shows where rows has been moved. + * + * @class ManualColumnMove + * @plugin ManualColumnMove */ -var RowsMapper = function () { - function RowsMapper(manualRowMove) { - _classCallCheck(this, RowsMapper); + +var ManualColumnMove = function (_BasePlugin) { + _inherits(ManualColumnMove, _BasePlugin); + + function ManualColumnMove(hotInstance) { + _classCallCheck(this, ManualColumnMove); /** - * Instance of ManualRowMove plugin. + * Set up WeakMap of plugin to sharing private parameters; + */ + var _this = _possibleConstructorReturn(this, (ManualColumnMove.__proto__ || Object.getPrototypeOf(ManualColumnMove)).call(this, hotInstance)); + + privatePool.set(_this, { + columnsToMove: [], + countCols: 0, + fixedColumns: 0, + pressed: void 0, + disallowMoving: void 0, + target: { + eventPageX: void 0, + coords: void 0, + TD: void 0, + col: void 0 + } + }); + + /** + * List of last removed row indexes. * - * @type {ManualRowMove} + * @type {Array} */ - this.manualRowMove = manualRowMove; + _this.removedColumns = []; + /** + * Object containing visual row indexes mapped to data source indexes. + * + * @type {RowsMapper} + */ + _this.columnsMapper = new _columnsMapper2.default(_this); + /** + * Event Manager object. + * + * @type {Object} + */ + _this.eventManager = new _eventManager2.default(_this); + /** + * Backlight UI object. + * + * @type {Object} + */ + _this.backlight = new _backlight2.default(hotInstance); + /** + * Guideline UI object. + * + * @type {Object} + */ + _this.guideline = new _guideline2.default(hotInstance); + return _this; } /** - * Reset current map array and create new one. + * Check if plugin is enabled. * - * @param {Number} [length] Custom generated map length. + * @returns {Boolean} */ - _createClass(RowsMapper, [{ - key: 'createMap', - value: function createMap(length) { - var _this = this; + _createClass(ManualColumnMove, [{ + key: 'isEnabled', + value: function isEnabled() { + return !!this.hot.getSettings().manualColumnMove; + } + + /** + * Enable the plugin. + */ + + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; + + if (this.enabled) { + return; + } + + this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) { + return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations); + }); + this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) { + return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations); + }); + this.addHook('afterScrollVertically', function () { + return _this2.onAfterScrollVertically(); + }); + this.addHook('modifyCol', function (row, source) { + return _this2.onModifyCol(row, source); + }); + this.addHook('beforeRemoveCol', function (index, amount) { + return _this2.onBeforeRemoveCol(index, amount); + }); + this.addHook('afterRemoveCol', function () { + return _this2.onAfterRemoveCol(); + }); + this.addHook('afterCreateCol', function (index, amount) { + return _this2.onAfterCreateCol(index, amount); + }); + this.addHook('afterLoadData', function () { + return _this2.onAfterLoadData(); + }); + this.addHook('unmodifyCol', function (column) { + return _this2.onUnmodifyCol(column); + }); + + this.registerEvents(); + + // TODO: move adding plugin classname to BasePlugin. + (0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN); + + _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'enablePlugin', this).call(this); + } + + /** + * Updates the plugin to use the latest options you have specified. + */ - var originLength = length === void 0 ? this._arrayMap.length : length; + }, { + key: 'updatePlugin', + value: function updatePlugin() { + this.disablePlugin(); + this.enablePlugin(); - this._arrayMap.length = 0; + this.onAfterPluginsInitialized(); - (0, _number.rangeEach)(originLength - 1, function (itemIndex) { - _this._arrayMap[itemIndex] = itemIndex; - }); + _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'updatePlugin', this).call(this); } /** - * Destroy class. + * Disable plugin for this Handsontable instance. */ }, { - key: 'destroy', - value: function destroy() { - this._arrayMap = null; + key: 'disablePlugin', + value: function disablePlugin() { + var pluginSettings = this.hot.getSettings().manualColumnMove; + + if (Array.isArray(pluginSettings)) { + this.columnsMapper.clearMap(); + } + + (0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN); + + this.unregisterEvents(); + this.backlight.destroy(); + this.guideline.destroy(); + + _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'disablePlugin', this).call(this); } /** - * Moving elements in rowsMapper. + * Move a single column. * - * @param {Number} from Row index to move. - * @param {Number} to Target index. + * @param {Number} column Visual column index to be moved. + * @param {Number} target Visual column index being a target for the moved column. */ }, { - key: 'moveRow', - value: function moveRow(from, to) { - var indexToMove = this._arrayMap[from]; - this._arrayMap[from] = null; - this._arrayMap.splice(to, 0, indexToMove); + key: 'moveColumn', + value: function moveColumn(column, target) { + this.moveColumns([column], target); } /** - * Clearing arrayMap from `null` entries. + * Move multiple columns. + * + * @param {Array} columns Array of visual column indexes to be moved. + * @param {Number} target Visual column index being a target for the moved columns. */ }, { - key: 'clearNull', - value: function clearNull() { - this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) { - return i !== null; - }); - } - }]); - - return RowsMapper; -}(); + key: 'moveColumns', + value: function moveColumns(columns, target) { + var _this3 = this; -(0, _object.mixin)(RowsMapper, _arrayMapper2.default); + var priv = privatePool.get(this); + var beforeColumnHook = this.hot.runHooks('beforeColumnMove', columns, target); -exports.default = RowsMapper; + priv.disallowMoving = !beforeColumnHook; -/***/ }), -/* 252 */ -/***/ (function(module, exports, __webpack_require__) { + if (beforeColumnHook !== false) { + // first we need to rewrite an visual indexes to physical for save reference after move + (0, _array.arrayEach)(columns, function (column, index, array) { + array[index] = _this3.columnsMapper.getValueByIndex(column); + }); -"use strict"; + // next, when we have got an physical indexes, we can move columns + (0, _array.arrayEach)(columns, function (column, index) { + var actualPosition = _this3.columnsMapper.getIndexByValue(column); + if (actualPosition !== target) { + _this3.columnsMapper.moveColumn(actualPosition, target + index); + } + }); -exports.__esModule = true; + // after moving we have to clear columnsMapper from null entries + this.columnsMapper.clearNull(); + } -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + this.hot.runHooks('afterColumnMove', columns, target); + } -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + /** + * Correct the cell selection after the move action. Fired only when action was made with a mouse. + * That means that changing the column order using the API won't correct the selection. + * + * @private + * @param {Number} startColumn Visual column index for the start of the selection. + * @param {Number} endColumn Visual column index for the end of the selection. + */ -var _base = __webpack_require__(153); + }, { + key: 'changeSelection', + value: function changeSelection(startColumn, endColumn) { + var selection = this.hot.selection; + var lastRowIndex = this.hot.countRows() - 1; -var _base2 = _interopRequireDefault(_base); + selection.setRangeStartOnly(new _src.CellCoords(0, startColumn)); + selection.setRangeEnd(new _src.CellCoords(lastRowIndex, endColumn), false); + } -var _element = __webpack_require__(0); + /** + * Get the sum of the widths of columns in the provided range. + * + * @private + * @param {Number} from Visual column index. + * @param {Number} to Visual column index. + * @returns {Number} + */ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + }, { + key: 'getColumnsWidth', + value: function getColumnsWidth(from, to) { + var width = 0; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + for (var i = from; i < to; i++) { + var columnWidth = 0; -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + if (i < 0) { + columnWidth = this.hot.view.wt.wtViewport.getRowHeaderWidth() || 0; + } else { + columnWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(i) || 0; + } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + width += columnWidth; + } -var CSS_CLASSNAME = 'ht__manualRowMove--backlight'; + return width; + } -/** - * @class BacklightUI - * @util - */ + /** + * Load initial settings when persistent state is saved or when plugin was initialized as an array. + * + * @private + */ -var BacklightUI = function (_BaseUI) { - _inherits(BacklightUI, _BaseUI); + }, { + key: 'initialSettings', + value: function initialSettings() { + var pluginSettings = this.hot.getSettings().manualColumnMove; - function BacklightUI() { - _classCallCheck(this, BacklightUI); + if (Array.isArray(pluginSettings)) { + this.moveColumns(pluginSettings, 0); + } else if (pluginSettings !== void 0) { + this.persistentStateLoad(); + } + } - return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments)); - } + /** + * Check if the provided column is in the fixedColumnsLeft section. + * + * @private + * @param {Number} column Visual column index to check. + * @returns {Boolean} + */ - _createClass(BacklightUI, [{ - key: 'build', + }, { + key: 'isFixedColumnsLeft', + value: function isFixedColumnsLeft(column) { + return column < this.hot.getSettings().fixedColumnsLeft; + } /** - * Custom className on build process. + * Save the manual column positions to the persistent state. + * + * @private */ - value: function build() { - _get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this); - (0, _element.addClass)(this._element, CSS_CLASSNAME); + }, { + key: 'persistentStateSave', + value: function persistentStateSave() { + this.hot.runHooks('persistentStateSave', 'manualColumnMove', this.columnsMapper._arrayMap); } - }]); - return BacklightUI; -}(_base2.default); - -exports.default = BacklightUI; + /** + * Load the manual column positions from the persistent state. + * + * @private + */ -/***/ }), -/* 253 */ -/***/ (function(module, exports, __webpack_require__) { + }, { + key: 'persistentStateLoad', + value: function persistentStateLoad() { + var storedState = {}; -"use strict"; + this.hot.runHooks('persistentStateLoad', 'manualColumnMove', storedState); + if (storedState.value) { + this.columnsMapper._arrayMap = storedState.value; + } + } -exports.__esModule = true; + /** + * Prepare array of indexes based on actual selection. + * + * @private + * @returns {Array} + */ -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + }, { + key: 'prepareColumnsToMoving', + value: function prepareColumnsToMoving(start, end) { + var selectedColumns = []; -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + (0, _number.rangeEach)(start, end, function (i) { + selectedColumns.push(i); + }); -var _base = __webpack_require__(153); + return selectedColumns; + } -var _base2 = _interopRequireDefault(_base); + /** + * Update the UI visual position. + * + * @private + */ -var _element = __webpack_require__(0); + }, { + key: 'refreshPositions', + value: function refreshPositions() { + var priv = privatePool.get(this); + var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleColumn(); + var lastVisible = this.hot.view.wt.wtTable.getLastVisibleColumn(); + var wtTable = this.hot.view.wt.wtTable; + var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement; + var scrollLeft = typeof scrollableElement.scrollX === 'number' ? scrollableElement.scrollX : scrollableElement.scrollLeft; + var tdOffsetLeft = this.hot.view.THEAD.offsetLeft + this.getColumnsWidth(0, priv.coordsColumn); + var mouseOffsetLeft = priv.target.eventPageX - (priv.rootElementOffset - (scrollableElement.scrollX === void 0 ? scrollLeft : 0)); + var hiderWidth = wtTable.hider.offsetWidth; + var tbodyOffsetLeft = wtTable.TBODY.offsetLeft; + var backlightElemMarginLeft = this.backlight.getOffset().left; + var backlightElemWidth = this.backlight.getSize().width; + var rowHeaderWidth = 0; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (priv.rootElementOffset + wtTable.holder.offsetWidth + scrollLeft < priv.target.eventPageX) { + if (priv.coordsColumn < priv.countCols) { + priv.coordsColumn++; + } + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + if (priv.hasRowHeaders) { + rowHeaderWidth = this.hot.view.wt.wtOverlays.leftOverlay.clone.wtTable.getColumnHeader(-1).offsetWidth; + } + if (this.isFixedColumnsLeft(priv.coordsColumn)) { + tdOffsetLeft += scrollLeft; + } + tdOffsetLeft += rowHeaderWidth; -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + if (priv.coordsColumn < 0) { + // if hover on rowHeader + if (priv.fixedColumns > 0) { + priv.target.col = 0; + } else { + priv.target.col = firstVisible > 0 ? firstVisible - 1 : firstVisible; + } + } else if (priv.target.TD.offsetWidth / 2 + tdOffsetLeft <= mouseOffsetLeft) { + var newCoordsCol = priv.coordsColumn >= priv.countCols ? priv.countCols - 1 : priv.coordsColumn; + // if hover on right part of TD + priv.target.col = newCoordsCol + 1; + // unfortunately first column is bigger than rest + tdOffsetLeft += priv.target.TD.offsetWidth; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + if (priv.target.col > lastVisible) { + this.hot.scrollViewportTo(void 0, lastVisible + 1, void 0, true); + } + } else { + // elsewhere on table + priv.target.col = priv.coordsColumn; -var CSS_CLASSNAME = 'ht__manualRowMove--guideline'; + if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns) { + this.hot.scrollViewportTo(void 0, firstVisible - 1); + } + } -/** - * @class GuidelineUI - * @util - */ + if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns) { + this.hot.scrollViewportTo(void 0, firstVisible - 1); + } -var GuidelineUI = function (_BaseUI) { - _inherits(GuidelineUI, _BaseUI); + var backlightLeft = mouseOffsetLeft; + var guidelineLeft = tdOffsetLeft; - function GuidelineUI() { - _classCallCheck(this, GuidelineUI); + if (mouseOffsetLeft + backlightElemWidth + backlightElemMarginLeft >= hiderWidth) { + // prevent display backlight on the right side of the table + backlightLeft = hiderWidth - backlightElemWidth - backlightElemMarginLeft; + } else if (mouseOffsetLeft + backlightElemMarginLeft < tbodyOffsetLeft + rowHeaderWidth) { + // prevent display backlight on the left side of the table + backlightLeft = tbodyOffsetLeft + rowHeaderWidth + Math.abs(backlightElemMarginLeft); + } - return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments)); - } + if (tdOffsetLeft >= hiderWidth - 1) { + // prevent display guideline outside the table + guidelineLeft = hiderWidth - 1; + } else if (guidelineLeft === 0) { + // guideline has got `margin-left: -1px` as default + guidelineLeft = 1; + } else if (scrollableElement.scrollX !== void 0 && priv.coordsColumn < priv.fixedColumns) { + guidelineLeft -= priv.rootElementOffset <= scrollableElement.scrollX ? priv.rootElementOffset : 0; + } - _createClass(GuidelineUI, [{ - key: 'build', + this.backlight.setPosition(null, backlightLeft); + this.guideline.setPosition(null, guidelineLeft); + } /** - * Custom className on build process. + * This method checks arrayMap from columnsMapper and updates the columnsMapper if it's necessary. + * + * @private */ - value: function build() { - _get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this); - - (0, _element.addClass)(this._element, CSS_CLASSNAME); - } - }]); - - return GuidelineUI; -}(_base2.default); - -exports.default = GuidelineUI; - -/***/ }), -/* 254 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var _base = __webpack_require__(12); + }, { + key: 'updateColumnsMapper', + value: function updateColumnsMapper() { + var countCols = this.hot.countSourceCols(); + var columnsMapperLen = this.columnsMapper._arrayMap.length; -var _base2 = _interopRequireDefault(_base); + if (columnsMapperLen === 0) { + this.columnsMapper.createMap(countCols || this.hot.getSettings().startCols); + } else if (columnsMapperLen < countCols) { + var diff = countCols - columnsMapperLen; -var _element = __webpack_require__(0); + this.columnsMapper.insertItems(columnsMapperLen, diff); + } else if (columnsMapperLen > countCols) { + var maxIndex = countCols - 1; + var columnsToRemove = []; -var _eventManager = __webpack_require__(4); + (0, _array.arrayEach)(this.columnsMapper._arrayMap, function (value, index) { + if (value > maxIndex) { + columnsToRemove.push(index); + } + }); -var _eventManager2 = _interopRequireDefault(_eventManager); + this.columnsMapper.removeItems(columnsToRemove); + } + } -var _event = __webpack_require__(7); + /** + * Bind the events used by the plugin. + * + * @private + */ -var _array = __webpack_require__(2); + }, { + key: 'registerEvents', + value: function registerEvents() { + var _this4 = this; -var _number = __webpack_require__(6); + this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) { + return _this4.onMouseMove(event); + }); + this.eventManager.addEventListener(document.documentElement, 'mouseup', function () { + return _this4.onMouseUp(); + }); + } -var _plugins = __webpack_require__(5); + /** + * Unbind the events used by the plugin. + * + * @private + */ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + }, { + key: 'unregisterEvents', + value: function unregisterEvents() { + this.eventManager.clear(); + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** + * Change the behavior of selection / dragging. + * + * @private + * @param {MouseEvent} event `mousedown` event properties. + * @param {CellCoords} coords Visual cell coordinates where was fired event. + * @param {HTMLElement} TD Cell represented as HTMLElement. + * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells. + */ -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + }, { + key: 'onBeforeOnCellMouseDown', + value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) { + var wtTable = this.hot.view.wt.wtTable; + var isHeaderSelection = this.hot.selection.selectedHeader.cols; + var selection = this.hot.getSelectedRange(); + var priv = privatePool.get(this); + var isSortingElement = event.realTarget.className.indexOf('columnSorting') > -1; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0 || isSortingElement) { + priv.pressed = false; + priv.columnsToMove.length = 0; + (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]); + return; + } -// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js + var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended(); + var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended(); -/** - * @description - * ManualRowResize Plugin. - * - * Has 2 UI components: - * - handle - the draggable element that sets the desired height of the row. - * - guide - the helper guide that shows the desired height as a horizontal guide. - * - * @plugin ManualRowResize - */ -var ManualRowResize = function (_BasePlugin) { - _inherits(ManualRowResize, _BasePlugin); + if (guidelineIsNotReady && backlightIsNotReady) { + this.guideline.appendTo(wtTable.hider); + this.backlight.appendTo(wtTable.hider); + } - function ManualRowResize(hotInstance) { - _classCallCheck(this, ManualRowResize); + var from = selection.from, + to = selection.to; - var _this = _possibleConstructorReturn(this, (ManualRowResize.__proto__ || Object.getPrototypeOf(ManualRowResize)).call(this, hotInstance)); + var start = Math.min(from.col, to.col); + var end = Math.max(from.col, to.col); - _this.currentTH = null; - _this.currentRow = null; - _this.selectedRows = []; - _this.currentHeight = null; - _this.newSize = null; - _this.startY = null; - _this.startHeight = null; - _this.startOffset = null; - _this.handle = document.createElement('DIV'); - _this.guide = document.createElement('DIV'); - _this.eventManager = new _eventManager2.default(_this); - _this.pressed = null; - _this.dblclick = 0; - _this.autoresizeTimeout = null; - _this.manualRowHeights = []; + if (coords.row < 0 && coords.col >= start && coords.col <= end) { + blockCalculations.column = true; + priv.pressed = true; + priv.target.eventPageX = event.pageX; + priv.coordsColumn = coords.col; + priv.target.TD = TD; + priv.target.col = coords.col; + priv.columnsToMove = this.prepareColumnsToMoving(start, end); + priv.hasRowHeaders = !!this.hot.getSettings().rowHeaders; + priv.countCols = this.hot.countCols(); + priv.fixedColumns = this.hot.getSettings().fixedColumnsLeft; + priv.rootElementOffset = (0, _element.offset)(this.hot.rootElement).left; - (0, _element.addClass)(_this.handle, 'manualRowResizer'); - (0, _element.addClass)(_this.guide, 'manualRowResizerGuide'); - return _this; - } + var countColumnsFrom = priv.hasRowHeaders ? -1 : 0; + var topPos = wtTable.holder.scrollTop + wtTable.getColumnHeaderHeight(0) + 1; + var fixedColumns = coords.col < priv.fixedColumns; + var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement; + var wrapperIsWindow = scrollableElement.scrollX ? scrollableElement.scrollX - priv.rootElementOffset : 0; - /** - * Check if the plugin is enabled in the handsontable settings. - * - * @returns {Boolean} - */ + var mouseOffset = event.layerX - (fixedColumns ? wrapperIsWindow : 0); + var leftOffset = Math.abs(this.getColumnsWidth(start, coords.col) + mouseOffset); + this.backlight.setPosition(topPos, this.getColumnsWidth(countColumnsFrom, start) + leftOffset); + this.backlight.setSize(this.getColumnsWidth(start, end + 1), wtTable.hider.offsetHeight - topPos); + this.backlight.setOffset(null, leftOffset * -1); - _createClass(ManualRowResize, [{ - key: 'isEnabled', - value: function isEnabled() { - return this.hot.getSettings().manualRowResize; + (0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING); + } else { + (0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION); + priv.pressed = false; + priv.columnsToMove.length = 0; + } } /** - * Enable plugin for this Handsontable instance. + * 'mouseMove' event callback. Fired when pointer move on document.documentElement. + * + * @private + * @param {MouseEvent} event `mousemove` event properties. */ }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + key: 'onMouseMove', + value: function onMouseMove(event) { + var priv = privatePool.get(this); - if (this.enabled) { + if (!priv.pressed) { return; } - this.manualRowHeights = []; - - var initialRowHeights = this.hot.getSettings().manualRowResize; - var loadedManualRowHeights = this.loadManualRowHeights(); + // callback for browser which doesn't supports CSS pointer-event: none + if (event.realTarget === this.backlight.element) { + var width = this.backlight.getSize().width; + this.backlight.setSize(0); - if (typeof loadedManualRowHeights != 'undefined') { - this.manualRowHeights = loadedManualRowHeights; - } else if (Array.isArray(initialRowHeights)) { - this.manualRowHeights = initialRowHeights; - } else { - this.manualRowHeights = []; + setTimeout(function () { + this.backlight.setPosition(width); + }); } - this.addHook('modifyRowHeight', function (height, row) { - return _this2.onModifyRowHeight(height, row); - }); - - // Handsontable.hooks.register('beforeRowResize'); - // Handsontable.hooks.register('afterRowResize'); - - this.bindEvents(); - - _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'enablePlugin', this).call(this); + priv.target.eventPageX = event.pageX; + this.refreshPositions(); } /** - * Updates the plugin to use the latest options you have specified. + * 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell. + * + * @private + * @param {MouseEvent} event `mouseover` event properties. + * @param {CellCoords} coords Visual cell coordinates where was fired event. + * @param {HTMLElement} TD Cell represented as HTMLElement. + * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells. */ }, { - key: 'updatePlugin', - value: function updatePlugin() { - var initialRowHeights = this.hot.getSettings().manualRowResize; + key: 'onBeforeOnCellMouseOver', + value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) { + var selectedRange = this.hot.getSelectedRange(); + var priv = privatePool.get(this); - if (Array.isArray(initialRowHeights)) { - this.manualRowHeights = initialRowHeights; - } else if (!initialRowHeights) { - this.manualRowHeights = []; + if (!selectedRange || !priv.pressed) { + return; } - } - /** - * Disable plugin for this Handsontable instance. - */ + if (priv.columnsToMove.indexOf(coords.col) > -1) { + (0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI); + } else { + (0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI); + } - }, { - key: 'disablePlugin', - value: function disablePlugin() { - _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'disablePlugin', this).call(this); + blockCalculations.row = true; + blockCalculations.column = true; + blockCalculations.cell = true; + priv.coordsColumn = coords.col; + priv.target.TD = TD; } /** - * Save the current sizes using the persistentState plugin. + * `onMouseUp` hook callback. + * + * @private */ }, { - key: 'saveManualRowHeights', - value: function saveManualRowHeights() { - this.hot.runHooks('persistentStateSave', 'manualRowHeights', this.manualRowHeights); - } + key: 'onMouseUp', + value: function onMouseUp() { + var priv = privatePool.get(this); - /** - * Load the previously saved sizes using the persistentState plugin. - * - * @returns {Array} - */ + priv.coordsColumn = void 0; + priv.pressed = false; + priv.backlightWidth = 0; - }, { - key: 'loadManualRowHeights', - value: function loadManualRowHeights() { - var storedState = {}; + (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]); - this.hot.runHooks('persistentStateLoad', 'manualRowHeights', storedState); + if (this.hot.selection.selectedHeader.cols) { + (0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION); + } + if (priv.columnsToMove.length < 1 || priv.target.col === void 0 || priv.columnsToMove.indexOf(priv.target.col) > -1) { + return; + } - return storedState.value; + this.moveColumns(priv.columnsToMove, priv.target.col); + this.persistentStateSave(); + this.hot.render(); + this.hot.view.wt.wtOverlays.adjustElementsSize(true); + + if (!priv.disallowMoving) { + var selectionStart = this.columnsMapper.getIndexByValue(priv.columnsToMove[0]); + var selectionEnd = this.columnsMapper.getIndexByValue(priv.columnsToMove[priv.columnsToMove.length - 1]); + this.changeSelection(selectionStart, selectionEnd); + } + + priv.columnsToMove.length = 0; } /** - * Set the resize handle position. + * `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally. * - * @param {HTMLCellElement} TH TH HTML element. + * @private */ }, { - key: 'setupHandlePosition', - value: function setupHandlePosition(TH) { - var _this3 = this; - - this.currentTH = TH; - var row = this.hot.view.wt.wtTable.getCoords(TH).row; // getCoords returns CellCoords - var headerWidth = (0, _element.outerWidth)(this.currentTH); - - if (row >= 0) { - // if not col header - var box = this.currentTH.getBoundingClientRect(); - - this.currentRow = row; - this.selectedRows = []; - - if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.rows) { - var _hot$getSelectedRange = this.hot.getSelectedRange(), - from = _hot$getSelectedRange.from, - to = _hot$getSelectedRange.to; - - var start = from.row; - var end = to.row; - - if (start >= end) { - start = to.row; - end = from.row; - } - - if (this.currentRow >= start && this.currentRow <= end) { - (0, _number.rangeEach)(start, end, function (i) { - return _this3.selectedRows.push(i); - }); - } else { - this.selectedRows.push(this.currentRow); - } - } else { - this.selectedRows.push(this.currentRow); - } + key: 'onAfterScrollVertically', + value: function onAfterScrollVertically() { + var wtTable = this.hot.view.wt.wtTable; + var headerHeight = wtTable.getColumnHeaderHeight(0) + 1; + var scrollTop = wtTable.holder.scrollTop; + var posTop = headerHeight + scrollTop; - this.startOffset = box.top - 6; - this.startHeight = parseInt(box.height, 10); - this.handle.style.left = box.left + 'px'; - this.handle.style.top = this.startOffset + this.startHeight + 'px'; - this.handle.style.width = headerWidth + 'px'; - this.hot.rootElement.appendChild(this.handle); - } + this.backlight.setPosition(posTop); + this.backlight.setSize(null, wtTable.hider.offsetHeight - posTop); } /** - * Refresh the resize handle position. + * `afterCreateCol` hook callback. + * + * @private + * @param {Number} index Visual index of the created column. + * @param {Number} amount Amount of created columns. */ }, { - key: 'refreshHandlePosition', - value: function refreshHandlePosition() { - this.handle.style.top = this.startOffset + this.currentHeight + 'px'; + key: 'onAfterCreateCol', + value: function onAfterCreateCol(index, amount) { + this.columnsMapper.shiftItems(index, amount); } /** - * Set the resize guide position. + * On before remove column listener. + * + * @private + * @param {Number} index Visual column index. + * @param {Number} amount Defines how many columns removed. */ }, { - key: 'setupGuidePosition', - value: function setupGuidePosition() { - var handleWidth = parseInt((0, _element.outerWidth)(this.handle), 10); - var handleRightPosition = parseInt(this.handle.style.left, 10) + handleWidth; - var maximumVisibleElementWidth = parseInt(this.hot.view.maximumVisibleElementWidth(0), 10); - (0, _element.addClass)(this.handle, 'active'); - (0, _element.addClass)(this.guide, 'active'); + key: 'onBeforeRemoveCol', + value: function onBeforeRemoveCol(index, amount) { + var _this5 = this; - this.guide.style.top = this.handle.style.top; - this.guide.style.left = handleRightPosition + 'px'; - this.guide.style.width = maximumVisibleElementWidth - handleWidth + 'px'; - this.hot.rootElement.appendChild(this.guide); + this.removedColumns.length = 0; + + if (index !== false) { + // Collect physical row index. + (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) { + _this5.removedColumns.push(_this5.hot.runHooks('modifyCol', removedIndex, _this5.pluginName)); + }); + } } /** - * Refresh the resize guide position. + * `afterRemoveCol` hook callback. + * + * @private */ }, { - key: 'refreshGuidePosition', - value: function refreshGuidePosition() { - this.guide.style.top = this.handle.style.top; + key: 'onAfterRemoveCol', + value: function onAfterRemoveCol() { + this.columnsMapper.unshiftItems(this.removedColumns); } /** - * Hide both the resize handle and resize guide. + * `afterLoadData` hook callback. + * + * @private */ }, { - key: 'hideHandleAndGuide', - value: function hideHandleAndGuide() { - (0, _element.removeClass)(this.handle, 'active'); - (0, _element.removeClass)(this.guide, 'active'); + key: 'onAfterLoadData', + value: function onAfterLoadData() { + this.updateColumnsMapper(); } /** - * Check if provided element is considered as a row header. + * 'modifyRow' hook callback. * - * @param {HTMLElement} element HTML element. - * @returns {Boolean} + * @private + * @param {Number} column Visual column index. + * @returns {Number} Physical column index. */ }, { - key: 'checkIfRowHeader', - value: function checkIfRowHeader(element) { - if (element != this.hot.rootElement) { - var parent = element.parentNode; - - if (parent.tagName === 'TBODY') { - return true; - } - - return this.checkIfRowHeader(parent); + key: 'onModifyCol', + value: function onModifyCol(column, source) { + if (source !== this.pluginName) { + // ugly fix for try to insert new, needed columns after pasting data + var columnInMapper = this.columnsMapper.getValueByIndex(column); + column = columnInMapper === null ? column : columnInMapper; } - return false; + return column; } /** - * Get the TH element from the provided element. + * 'unmodifyCol' hook callback. * - * @param {HTMLElement} element HTML element. - * @returns {HTMLElement} + * @private + * @param {Number} column Physical column index. + * @returns {Number} Visual column index. */ }, { - key: 'getTHFromTargetElement', - value: function getTHFromTargetElement(element) { - if (element.tagName != 'TABLE') { - if (element.tagName == 'TH') { - return element; - } - return this.getTHFromTargetElement(element.parentNode); - } + key: 'onUnmodifyCol', + value: function onUnmodifyCol(column) { + var indexInMapper = this.columnsMapper.getIndexByValue(column); - return null; + return indexInMapper === null ? column : indexInMapper; } /** - * 'mouseover' event callback - set the handle position. + * `afterPluginsInitialized` hook callback. * * @private - * @param {MouseEvent} event */ }, { - key: 'onMouseOver', - value: function onMouseOver(event) { - if (this.checkIfRowHeader(event.target)) { - var th = this.getTHFromTargetElement(event.target); - - if (th) { - if (!this.pressed) { - this.setupHandlePosition(th); - } - } - } + key: 'onAfterPluginsInitialized', + value: function onAfterPluginsInitialized() { + this.updateColumnsMapper(); + this.initialSettings(); + this.backlight.build(); + this.guideline.build(); } /** - * Auto-size row after doubleclick - callback. - * - * @private + * Destroy plugin instance. */ }, { - key: 'afterMouseDownTimeout', - value: function afterMouseDownTimeout() { - var _this4 = this; - - var render = function render() { - _this4.hot.forceFullRender = true; - _this4.hot.view.render(); // updates all - _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); - }; - var resize = function resize(selectedRow, forceRender) { - var hookNewSize = _this4.hot.runHooks('beforeRowResize', selectedRow, _this4.newSize, true); + key: 'destroy', + value: function destroy() { + this.backlight.destroy(); + this.guideline.destroy(); - if (hookNewSize !== void 0) { - _this4.newSize = hookNewSize; - } + _get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'destroy', this).call(this); + } + }]); - _this4.setManualSize(selectedRow, _this4.newSize); // double click sets auto row size + return ManualColumnMove; +}(_base2.default); - if (forceRender) { - render(); - } +(0, _plugins.registerPlugin)('ManualColumnMove', ManualColumnMove); - _this4.hot.runHooks('afterRowResize', selectedRow, _this4.newSize, true); - }; +exports.default = ManualColumnMove; - if (this.dblclick >= 2) { - var selectedRowsLength = this.selectedRows.length; +/***/ }), +/* 288 */ +/***/ (function(module, exports, __webpack_require__) { - if (selectedRowsLength > 1) { - (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { - resize(selectedRow); - }); - render(); - } else { - (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { - resize(selectedRow, true); - }); - } - } - this.dblclick = 0; - this.autoresizeTimeout = null; - } +"use strict"; - /** - * 'mousedown' event callback. - * - * @private - * @param {MouseEvent} event - */ - }, { - key: 'onMouseDown', - value: function onMouseDown(event) { - var _this5 = this; +exports.__esModule = true; - if ((0, _element.hasClass)(event.target, 'manualRowResizer')) { - this.setupGuidePosition(); - this.pressed = this.hot; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (this.autoresizeTimeout == null) { - this.autoresizeTimeout = setTimeout(function () { - return _this5.afterMouseDownTimeout(); - }, 500); +var _arrayMapper = __webpack_require__(176); - this.hot._registerTimeout(this.autoresizeTimeout); - } - this.dblclick++; +var _arrayMapper2 = _interopRequireDefault(_arrayMapper); - this.startY = (0, _event.pageY)(event); - this.newSize = this.startHeight; - } - } +var _array = __webpack_require__(2); - /** - * 'mousemove' event callback - refresh the handle and guide positions, cache the new row height. - * - * @private - * @param {MouseEvent} event - */ +var _object = __webpack_require__(1); - }, { - key: 'onMouseMove', - value: function onMouseMove(event) { - var _this6 = this; +var _number = __webpack_require__(6); - if (this.pressed) { - this.currentHeight = this.startHeight + ((0, _event.pageY)(event) - this.startY); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { - _this6.newSize = _this6.setManualSize(selectedRow, _this6.currentHeight); - }); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - this.refreshHandlePosition(); - this.refreshGuidePosition(); - } - } +/** + * @class ColumnsMapper + * @plugin ManualColumnMove + */ +var ColumnsMapper = function () { + function ColumnsMapper(manualColumnMove) { + _classCallCheck(this, ColumnsMapper); /** - * 'mouseup' event callback - apply the row resizing. + * Instance of ManualColumnMove plugin. * - * @private - * @param {MouseEvent} event + * @type {ManualColumnMove} */ + this.manualColumnMove = manualColumnMove; + } - }, { - key: 'onMouseUp', - value: function onMouseUp(event) { - var _this7 = this; - - var render = function render() { - _this7.hot.forceFullRender = true; - _this7.hot.view.render(); // updates all - _this7.hot.view.wt.wtOverlays.adjustElementsSize(true); - }; - var runHooks = function runHooks(selectedRow, forceRender) { - _this7.hot.runHooks('beforeRowResize', selectedRow, _this7.newSize); - - if (forceRender) { - render(); - } + /** + * Reset current map array and create new one. + * + * @param {Number} [length] Custom generated map length. + */ - _this7.saveManualRowHeights(); - _this7.hot.runHooks('afterRowResize', selectedRow, _this7.newSize); - }; - if (this.pressed) { - this.hideHandleAndGuide(); - this.pressed = false; + _createClass(ColumnsMapper, [{ + key: 'createMap', + value: function createMap(length) { + var _this = this; - if (this.newSize != this.startHeight) { - var selectedRowsLength = this.selectedRows.length; + var originLength = length === void 0 ? this._arrayMap.length : length; - if (selectedRowsLength > 1) { - (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { - runHooks(selectedRow); - }); - render(); - } else { - (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { - runHooks(selectedRow, true); - }); - } - } + this._arrayMap.length = 0; - this.setupHandlePosition(this.currentTH); - } + (0, _number.rangeEach)(originLength - 1, function (itemIndex) { + _this._arrayMap[itemIndex] = itemIndex; + }); } /** - * Bind the mouse events. - * - * @private + * Destroy class. */ }, { - key: 'bindEvents', - value: function bindEvents() { - var _this8 = this; - - this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) { - return _this8.onMouseOver(e); - }); - this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) { - return _this8.onMouseDown(e); - }); - this.eventManager.addEventListener(window, 'mousemove', function (e) { - return _this8.onMouseMove(e); - }); - this.eventManager.addEventListener(window, 'mouseup', function (e) { - return _this8.onMouseUp(e); - }); + key: 'destroy', + value: function destroy() { + this._arrayMap = null; } /** - * Cache the current row height. + * Moving elements in columnsMapper. * - * @param {Number} row Visual row index. - * @param {Number} height Row height. - * @returns {Number} + * @param {Number} from Column index to move. + * @param {Number} to Target index. */ }, { - key: 'setManualSize', - value: function setManualSize(row, height) { - row = this.hot.runHooks('modifyRow', row); - this.manualRowHeights[row] = height; - - return height; + key: 'moveColumn', + value: function moveColumn(from, to) { + var indexToMove = this._arrayMap[from]; + this._arrayMap[from] = null; + this._arrayMap.splice(to, 0, indexToMove); } /** - * Modify the provided row height, based on the plugin settings. - * - * @private - * @param {Number} height Row height. - * @param {Number} row Visual row index. - * @returns {Number} + * Clearing arrayMap from `null` entries. */ }, { - key: 'onModifyRowHeight', - value: function onModifyRowHeight(height, row) { - if (this.enabled) { - var autoRowSizePlugin = this.hot.getPlugin('autoRowSize'); - var autoRowHeightResult = autoRowSizePlugin ? autoRowSizePlugin.heights[row] : null; - - row = this.hot.runHooks('modifyRow', row); - - var manualRowHeight = this.manualRowHeights[row]; - - if (manualRowHeight !== void 0 && (manualRowHeight === autoRowHeightResult || manualRowHeight > (height || 0))) { - return manualRowHeight; - } - } - - return height; + key: 'clearNull', + value: function clearNull() { + this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) { + return i !== null; + }); } }]); - return ManualRowResize; -}(_base2.default); + return ColumnsMapper; +}(); -(0, _plugins.registerPlugin)('manualRowResize', ManualRowResize); +(0, _object.mixin)(ColumnsMapper, _arrayMapper2.default); -exports.default = ManualRowResize; +exports.default = ColumnsMapper; /***/ }), -/* 255 */ +/* 289 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60339,1073 +60816,789 @@ exports.default = ManualRowResize; exports.__esModule = true; -var _pluginHooks = __webpack_require__(8); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var _plugins = __webpack_require__(5); +var _base = __webpack_require__(177); -var _event = __webpack_require__(7); +var _base2 = _interopRequireDefault(_base); -var _src = __webpack_require__(11); +var _element = __webpack_require__(0); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function CellInfoCollection() { - var collection = []; - - collection.getInfo = function (row, col) { - for (var i = 0, ilen = this.length; i < ilen; i++) { - if (this[i].row <= row && this[i].row + this[i].rowspan - 1 >= row && this[i].col <= col && this[i].col + this[i].colspan - 1 >= col) { - return this[i]; - } - } - }; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - collection.setInfo = function (info) { - for (var i = 0, ilen = this.length; i < ilen; i++) { - if (this[i].row === info.row && this[i].col === info.col) { - this[i] = info; - return; - } - } - this.push(info); - }; +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - collection.removeInfo = function (row, col) { - for (var i = 0, ilen = this.length; i < ilen; i++) { - if (this[i].row === row && this[i].col === col) { - this.splice(i, 1); - break; - } - } - }; +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - return collection; -} +var CSS_CLASSNAME = 'ht__manualColumnMove--backlight'; /** - * Plugin used to merge cells in Handsontable. - * - * @private - * @plugin MergeCells - * @class MergeCells + * @class BacklightUI + * @util */ -function MergeCells(mergeCellsSetting) { - this.mergedCellInfoCollection = new CellInfoCollection(); - if (Array.isArray(mergeCellsSetting)) { - for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) { - this.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]); - } - } -} +var BacklightUI = function (_BaseUI) { + _inherits(BacklightUI, _BaseUI); -/** - * @param cellRange (CellRange) - */ -MergeCells.prototype.canMergeRange = function (cellRange) { - // is more than one cell selected - return !cellRange.isSingle(); -}; + function BacklightUI() { + _classCallCheck(this, BacklightUI); -MergeCells.prototype.mergeRange = function (cellRange) { - if (!this.canMergeRange(cellRange)) { - return; + return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments)); } - // normalize top left corner - var topLeft = cellRange.getTopLeftCorner(); - var bottomRight = cellRange.getBottomRightCorner(); + _createClass(BacklightUI, [{ + key: 'build', - var mergeParent = {}; - mergeParent.row = topLeft.row; - mergeParent.col = topLeft.col; - // TD has rowspan == 1 by default. rowspan == 2 means spread over 2 cells - mergeParent.rowspan = bottomRight.row - topLeft.row + 1; - mergeParent.colspan = bottomRight.col - topLeft.col + 1; - this.mergedCellInfoCollection.setInfo(mergeParent); -}; + /** + * Custom className on build process. + */ + value: function build() { + _get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this); -MergeCells.prototype.mergeOrUnmergeSelection = function (cellRange) { - var info = this.mergedCellInfoCollection.getInfo(cellRange.from.row, cellRange.from.col); - if (info) { - // unmerge - this.unmergeSelection(cellRange.from); - } else { - // merge - this.mergeSelection(cellRange); - } -}; + (0, _element.addClass)(this._element, CSS_CLASSNAME); + } + }]); -MergeCells.prototype.mergeSelection = function (cellRange) { - this.mergeRange(cellRange); -}; + return BacklightUI; +}(_base2.default); -MergeCells.prototype.unmergeSelection = function (cellRange) { - var info = this.mergedCellInfoCollection.getInfo(cellRange.row, cellRange.col); - this.mergedCellInfoCollection.removeInfo(info.row, info.col); -}; +exports.default = BacklightUI; -MergeCells.prototype.applySpanProperties = function (TD, row, col) { - var info = this.mergedCellInfoCollection.getInfo(row, col); +/***/ }), +/* 290 */ +/***/ (function(module, exports, __webpack_require__) { - if (info) { - if (info.row === row && info.col === col) { - TD.setAttribute('rowspan', info.rowspan); - TD.setAttribute('colspan', info.colspan); - } else { - TD.removeAttribute('rowspan'); - TD.removeAttribute('colspan'); +"use strict"; - TD.style.display = 'none'; - } - } else { - TD.removeAttribute('rowspan'); - TD.removeAttribute('colspan'); - } -}; -MergeCells.prototype.modifyTransform = function (hook, currentSelectedRange, delta) { - var sameRowspan = function sameRowspan(merged, coords) { - if (coords.row >= merged.row && coords.row <= merged.row + merged.rowspan - 1) { - return true; - } - return false; - }, - sameColspan = function sameColspan(merged, coords) { - if (coords.col >= merged.col && coords.col <= merged.col + merged.colspan - 1) { - return true; - } - return false; - }, - getNextPosition = function getNextPosition(newDelta) { - return new _src.CellCoords(currentSelectedRange.to.row + newDelta.row, currentSelectedRange.to.col + newDelta.col); - }; +exports.__esModule = true; - var newDelta = { - row: delta.row, - col: delta.col - }; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (hook == 'modifyTransformStart') { - /* eslint-disable block-scoped-var */ - var nextPosition; +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - if (!this.lastDesiredCoords) { - this.lastDesiredCoords = new _src.CellCoords(null, null); - } - var currentPosition = new _src.CellCoords(currentSelectedRange.highlight.row, currentSelectedRange.highlight.col), +var _base = __webpack_require__(177); - // if current position's parent is a merged range, returns it - mergedParent = this.mergedCellInfoCollection.getInfo(currentPosition.row, currentPosition.col), - currentRangeContainsMerge; // if current range contains a merged range +var _base2 = _interopRequireDefault(_base); - for (var i = 0, mergesLength = this.mergedCellInfoCollection.length; i < mergesLength; i++) { - var range = this.mergedCellInfoCollection[i]; - range = new _src.CellCoords(range.row + range.rowspan - 1, range.col + range.colspan - 1); - if (currentSelectedRange.includes(range)) { - currentRangeContainsMerge = true; - break; - } - } +var _element = __webpack_require__(0); - if (mergedParent) { - // only merge selected - var mergeTopLeft = new _src.CellCoords(mergedParent.row, mergedParent.col); - var mergeBottomRight = new _src.CellCoords(mergedParent.row + mergedParent.rowspan - 1, mergedParent.col + mergedParent.colspan - 1); - var mergeRange = new _src.CellRange(mergeTopLeft, mergeTopLeft, mergeBottomRight); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (!mergeRange.includes(this.lastDesiredCoords)) { - this.lastDesiredCoords = new _src.CellCoords(null, null); // reset outdated version of lastDesiredCoords - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - newDelta.row = this.lastDesiredCoords.row ? this.lastDesiredCoords.row - currentPosition.row : newDelta.row; - newDelta.col = this.lastDesiredCoords.col ? this.lastDesiredCoords.col - currentPosition.col : newDelta.col; +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - if (delta.row > 0) { - // moving down - newDelta.row = mergedParent.row + mergedParent.rowspan - 1 - currentPosition.row + delta.row; - } else if (delta.row < 0) { - // moving up - newDelta.row = currentPosition.row - mergedParent.row + delta.row; - } - if (delta.col > 0) { - // moving right - newDelta.col = mergedParent.col + mergedParent.colspan - 1 - currentPosition.col + delta.col; - } else if (delta.col < 0) { - // moving left - newDelta.col = currentPosition.col - mergedParent.col + delta.col; - } - } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - nextPosition = new _src.CellCoords(currentSelectedRange.highlight.row + newDelta.row, currentSelectedRange.highlight.col + newDelta.col); +var CSS_CLASSNAME = 'ht__manualColumnMove--guideline'; - var nextParentIsMerged = this.mergedCellInfoCollection.getInfo(nextPosition.row, nextPosition.col); +/** + * @class GuidelineUI + * @util + */ - if (nextParentIsMerged) { - // skipping the invisible cells in the merge range - this.lastDesiredCoords = nextPosition; - newDelta = { - row: nextParentIsMerged.row - currentPosition.row, - col: nextParentIsMerged.col - currentPosition.col - }; - } - } else if (hook == 'modifyTransformEnd') { - for (var _i = 0, _mergesLength = this.mergedCellInfoCollection.length; _i < _mergesLength; _i++) { - var currentMerge = this.mergedCellInfoCollection[_i]; - var _mergeTopLeft = new _src.CellCoords(currentMerge.row, currentMerge.col); - var _mergeBottomRight = new _src.CellCoords(currentMerge.row + currentMerge.rowspan - 1, currentMerge.col + currentMerge.colspan - 1); - var mergedRange = new _src.CellRange(_mergeTopLeft, _mergeTopLeft, _mergeBottomRight); - var sharedBorders = currentSelectedRange.getBordersSharedWith(mergedRange); +var GuidelineUI = function (_BaseUI) { + _inherits(GuidelineUI, _BaseUI); - if (mergedRange.isEqual(currentSelectedRange)) { - // only the merged range is selected - currentSelectedRange.setDirection('NW-SE'); - } else if (sharedBorders.length > 0) { - var mergeHighlighted = currentSelectedRange.highlight.isEqual(mergedRange.from); + function GuidelineUI() { + _classCallCheck(this, GuidelineUI); - if (sharedBorders.indexOf('top') > -1) { - // if range shares a border with the merged section, change range direction accordingly - if (currentSelectedRange.to.isSouthEastOf(mergedRange.from) && mergeHighlighted) { - currentSelectedRange.setDirection('NW-SE'); - } else if (currentSelectedRange.to.isSouthWestOf(mergedRange.from) && mergeHighlighted) { - currentSelectedRange.setDirection('NE-SW'); - } - } else if (sharedBorders.indexOf('bottom') > -1) { - if (currentSelectedRange.to.isNorthEastOf(mergedRange.from) && mergeHighlighted) { - currentSelectedRange.setDirection('SW-NE'); - } else if (currentSelectedRange.to.isNorthWestOf(mergedRange.from) && mergeHighlighted) { - currentSelectedRange.setDirection('SE-NW'); - } - } - } + return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments)); + } - nextPosition = getNextPosition(newDelta); - var withinRowspan = sameRowspan(currentMerge, nextPosition), - withinColspan = sameColspan(currentMerge, nextPosition); + _createClass(GuidelineUI, [{ + key: 'build', - if (currentSelectedRange.includesRange(mergedRange) && (mergedRange.includes(nextPosition) || withinRowspan || withinColspan)) { - // if next step overlaps a merged range, jump past it - if (withinRowspan) { - if (newDelta.row < 0) { - newDelta.row -= currentMerge.rowspan - 1; - } else if (newDelta.row > 0) { - newDelta.row += currentMerge.rowspan - 1; - } - } - if (withinColspan) { - if (newDelta.col < 0) { - newDelta.col -= currentMerge.colspan - 1; - } else if (newDelta.col > 0) { - newDelta.col += currentMerge.colspan - 1; - } - } - } + /** + * Custom className on build process. + */ + value: function build() { + _get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this); + + (0, _element.addClass)(this._element, CSS_CLASSNAME); } - } + }]); - if (newDelta.row !== 0) { - delta.row = newDelta.row; - } - if (newDelta.col !== 0) { - delta.col = newDelta.col; - } -}; + return GuidelineUI; +}(_base2.default); -MergeCells.prototype.shiftCollection = function (direction, index, count) { - var shiftVector = [0, 0]; +exports.default = GuidelineUI; - switch (direction) { - case 'right': - shiftVector[0] += 1; +/***/ }), +/* 291 */ +/***/ (function(module, exports) { - break; - case 'left': - shiftVector[0] -= 1; +// removed by extract-text-webpack-plugin - break; - case 'down': - shiftVector[1] += 1; +/***/ }), +/* 292 */ +/***/ (function(module, exports, __webpack_require__) { - break; - case 'up': - shiftVector[1] -= 1; +"use strict"; - break; - default: - break; - } - for (var i = 0; i < this.mergedCellInfoCollection.length; i++) { - var currentMerge = this.mergedCellInfoCollection[i]; +exports.__esModule = true; - if (direction === 'right' || direction === 'left') { - if (index <= currentMerge.col) { - currentMerge.col += shiftVector[0]; - } - } else if (index <= currentMerge.row) { - currentMerge.row += shiftVector[1]; - } - } -}; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var beforeInit = function beforeInit() { - var instance = this; - var mergeCellsSetting = instance.getSettings().mergeCells; +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - if (mergeCellsSetting) { - if (!instance.mergeCells) { - instance.mergeCells = new MergeCells(mergeCellsSetting); - } - } -}; +var _base = __webpack_require__(13); -var afterInit = function afterInit() { - var instance = this; - if (instance.mergeCells) { - /** - * Monkey patch Table.prototype.getCell to return TD for merged cell parent if asked for TD of a cell that is - * invisible due to the merge. This is not the cleanest solution but there is a test case for it (merged cells scroll) so feel free to refactor it! - */ - instance.view.wt.wtTable.getCell = function (coords) { - if (instance.getSettings().mergeCells) { - var mergeParent = instance.mergeCells.mergedCellInfoCollection.getInfo(coords.row, coords.col); - if (mergeParent) { - coords = mergeParent; - } - } - return _src.Table.prototype.getCell.call(this, coords); - }; - } -}; +var _base2 = _interopRequireDefault(_base); -var afterUpdateSettings = function afterUpdateSettings() { - var instance = this; - var mergeCellsSetting = instance.getSettings().mergeCells; +var _element = __webpack_require__(0); - if (mergeCellsSetting) { - if (instance.mergeCells) { - instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection(); +var _eventManager = __webpack_require__(4); - if (Array.isArray(mergeCellsSetting)) { - for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) { - instance.mergeCells.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]); - } - } - } else { - instance.mergeCells = new MergeCells(mergeCellsSetting); - } - } else if (instance.mergeCells) { - // it doesn't actually turn off the plugin, just resets the settings. Need to refactor. - instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection(); - } -}; +var _eventManager2 = _interopRequireDefault(_eventManager); -var onBeforeKeyDown = function onBeforeKeyDown(event) { - if (!this.mergeCells) { - return; - } +var _event = __webpack_require__(8); - var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; +var _array = __webpack_require__(2); - if (ctrlDown) { - if (event.keyCode === 77) { - // CTRL + M - this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange()); - this.render(); - (0, _event.stopImmediatePropagation)(event); - } - } -}; +var _number = __webpack_require__(6); -var addMergeActionsToContextMenu = function addMergeActionsToContextMenu(defaultOptions) { - if (!this.getSettings().mergeCells) { - return; - } +var _plugins = __webpack_require__(5); - defaultOptions.items.push({ name: '---------' }); - defaultOptions.items.push({ - key: 'mergeCells', - name: function name() { - var sel = this.getSelected(); - var info = this.mergeCells.mergedCellInfoCollection.getInfo(sel[0], sel[1]); - if (info) { - return 'Unmerge cells'; - } - return 'Merge cells'; - }, - callback: function callback() { - this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange()); - this.render(); - }, - disabled: function disabled() { - return this.selection.selectedHeader.corner; - } - }); -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js + +/** + * @description + * ManualColumnResize Plugin. + * + * Has 2 UI components: + * - handle - the draggable element that sets the desired width of the column. + * - guide - the helper guide that shows the desired width as a vertical guide. + * + * @plugin ManualColumnResize + */ +var ManualColumnResize = function (_BasePlugin) { + _inherits(ManualColumnResize, _BasePlugin); + + function ManualColumnResize(hotInstance) { + _classCallCheck(this, ManualColumnResize); + + var _this = _possibleConstructorReturn(this, (ManualColumnResize.__proto__ || Object.getPrototypeOf(ManualColumnResize)).call(this, hotInstance)); + + _this.currentTH = null; + _this.currentCol = null; + _this.selectedCols = []; + _this.currentWidth = null; + _this.newSize = null; + _this.startY = null; + _this.startWidth = null; + _this.startOffset = null; + _this.handle = document.createElement('DIV'); + _this.guide = document.createElement('DIV'); + _this.eventManager = new _eventManager2.default(_this); + _this.pressed = null; + _this.dblclick = 0; + _this.autoresizeTimeout = null; + _this.manualColumnWidths = []; -var afterRenderer = function afterRenderer(TD, row, col, prop, value, cellProperties) { - if (this.mergeCells) { - this.mergeCells.applySpanProperties(TD, row, col); + (0, _element.addClass)(_this.handle, 'manualColumnResizer'); + (0, _element.addClass)(_this.guide, 'manualColumnResizerGuide'); + return _this; } -}; -var modifyTransformFactory = function modifyTransformFactory(hook) { - return function (delta) { - var mergeCellsSetting = this.getSettings().mergeCells; - if (mergeCellsSetting) { - var currentSelectedRange = this.getSelectedRange(); - this.mergeCells.modifyTransform(hook, currentSelectedRange, delta); + /** + * Check if the plugin is enabled in the handsontable settings. + * + * @returns {Boolean} + */ - if (hook === 'modifyTransformEnd') { - // sanitize "from" (core.js will sanitize to) - var totalRows = this.countRows(); - var totalCols = this.countCols(); - if (currentSelectedRange.from.row < 0) { - currentSelectedRange.from.row = 0; - } else if (currentSelectedRange.from.row > 0 && currentSelectedRange.from.row >= totalRows) { - currentSelectedRange.from.row = currentSelectedRange.from - 1; - } - if (currentSelectedRange.from.col < 0) { - currentSelectedRange.from.col = 0; - } else if (currentSelectedRange.from.col > 0 && currentSelectedRange.from.col >= totalCols) { - currentSelectedRange.from.col = totalCols - 1; - } - } + _createClass(ManualColumnResize, [{ + key: 'isEnabled', + value: function isEnabled() { + return this.hot.getSettings().manualColumnResize; } - }; -}; -/** - * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell - * @param coords - */ -var beforeSetRangeEnd = function beforeSetRangeEnd(coords) { + /** + * Enable plugin for this Handsontable instance. + */ - this.lastDesiredCoords = null; // unset lastDesiredCoords when selection is changed with mouse - var mergeCellsSetting = this.getSettings().mergeCells; - if (mergeCellsSetting) { - var selRange = this.getSelectedRange(); - selRange.highlight = new _src.CellCoords(selRange.highlight.row, selRange.highlight.col); // clone in case we will modify its reference - selRange.to = coords; + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; - var rangeExpanded = false; - do { - rangeExpanded = false; + if (this.enabled) { + return; + } - for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) { - var cellInfo = this.mergeCells.mergedCellInfoCollection[i]; - var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col); - var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1); + this.manualColumnWidths = []; + var initialColumnWidth = this.hot.getSettings().manualColumnResize; + var loadedManualColumnWidths = this.loadManualColumnWidths(); - var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight); - if (selRange.expandByRange(mergedCellRange)) { - coords.row = selRange.to.row; - coords.col = selRange.to.col; + this.addHook('modifyColWidth', function (width, col) { + return _this2.onModifyColWidth(width, col); + }); + this.addHook('beforeStretchingColumnWidth', function (stretchedWidth, column) { + return _this2.onBeforeStretchingColumnWidth(stretchedWidth, column); + }); + this.addHook('beforeColumnResize', function (currentColumn, newSize, isDoubleClick) { + return _this2.onBeforeColumnResize(currentColumn, newSize, isDoubleClick); + }); - rangeExpanded = true; - } + if (typeof loadedManualColumnWidths != 'undefined') { + this.manualColumnWidths = loadedManualColumnWidths; + } else if (Array.isArray(initialColumnWidth)) { + this.manualColumnWidths = initialColumnWidth; + } else { + this.manualColumnWidths = []; } - } while (rangeExpanded); - } -}; - -/** - * Returns correct coordinates for merged start / end cells in selection for area borders - * @param corners - * @param className - */ -var beforeDrawAreaBorders = function beforeDrawAreaBorders(corners, className) { - if (className && className == 'area') { - var mergeCellsSetting = this.getSettings().mergeCells; - if (mergeCellsSetting) { - var selRange = this.getSelectedRange(); - var startRange = new _src.CellRange(selRange.from, selRange.from, selRange.from); - var stopRange = new _src.CellRange(selRange.to, selRange.to, selRange.to); - for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) { - var cellInfo = this.mergeCells.mergedCellInfoCollection[i]; - var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col); - var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1); - var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight); + // Handsontable.hooks.register('beforeColumnResize'); + // Handsontable.hooks.register('afterColumnResize'); - if (startRange.expandByRange(mergedCellRange)) { - corners[0] = startRange.from.row; - corners[1] = startRange.from.col; - } + this.bindEvents(); - if (stopRange.expandByRange(mergedCellRange)) { - corners[2] = stopRange.from.row; - corners[3] = stopRange.from.col; - } - } + _get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'enablePlugin', this).call(this); } - } -}; -var afterGetCellMeta = function afterGetCellMeta(row, col, cellProperties) { - var mergeCellsSetting = this.getSettings().mergeCells; - if (mergeCellsSetting) { - var mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(row, col); - if (mergeParent && (mergeParent.row != row || mergeParent.col != col)) { - cellProperties.copyable = false; - } - } -}; + /** + * Updates the plugin to use the latest options you have specified. + */ -var afterViewportRowCalculatorOverride = function afterViewportRowCalculatorOverride(calc) { - var mergeCellsSetting = this.getSettings().mergeCells; - if (mergeCellsSetting) { - var colCount = this.countCols(); - var mergeParent; - for (var c = 0; c < colCount; c++) { - mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.startRow, c); - if (mergeParent) { - if (mergeParent.row < calc.startRow) { - calc.startRow = mergeParent.row; - return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards - } - } - mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.endRow, c); - if (mergeParent) { - var mergeEnd = mergeParent.row + mergeParent.rowspan - 1; - if (mergeEnd > calc.endRow) { - calc.endRow = mergeEnd; - return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards - } + }, { + key: 'updatePlugin', + value: function updatePlugin() { + var initialColumnWidth = this.hot.getSettings().manualColumnResize; + + if (Array.isArray(initialColumnWidth)) { + this.manualColumnWidths = initialColumnWidth; + } else if (!initialColumnWidth) { + this.manualColumnWidths = []; } } - } -}; -var afterViewportColumnCalculatorOverride = function afterViewportColumnCalculatorOverride(calc) { - var mergeCellsSetting = this.getSettings().mergeCells; - if (mergeCellsSetting) { - var rowCount = this.countRows(); - var mergeParent; - for (var r = 0; r < rowCount; r++) { - mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.startColumn); + /** + * Disable plugin for this Handsontable instance. + */ - if (mergeParent) { - if (mergeParent.col < calc.startColumn) { - calc.startColumn = mergeParent.col; - return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards - } - } - mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.endColumn); - if (mergeParent) { - var mergeEnd = mergeParent.col + mergeParent.colspan - 1; - if (mergeEnd > calc.endColumn) { - calc.endColumn = mergeEnd; - return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards - } - } + }, { + key: 'disablePlugin', + value: function disablePlugin() { + _get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'disablePlugin', this).call(this); } - } -}; -var isMultipleSelection = function isMultipleSelection(isMultiple) { - if (isMultiple && this.mergeCells) { - var mergedCells = this.mergeCells.mergedCellInfoCollection, - selectionRange = this.getSelectedRange(); + /** + * Save the current sizes using the persistentState plugin. + */ - for (var group in mergedCells) { - if (selectionRange.highlight.row == mergedCells[group].row && selectionRange.highlight.col == mergedCells[group].col && selectionRange.to.row == mergedCells[group].row + mergedCells[group].rowspan - 1 && selectionRange.to.col == mergedCells[group].col + mergedCells[group].colspan - 1) { - return false; - } + }, { + key: 'saveManualColumnWidths', + value: function saveManualColumnWidths() { + this.hot.runHooks('persistentStateSave', 'manualColumnWidths', this.manualColumnWidths); } - } - return isMultiple; -}; - -function modifyAutofillRange(select, drag) { - var mergeCellsSetting = this.getSettings().mergeCells; - if (!mergeCellsSetting || this.selection.isMultiple()) { - return; - } - var info = this.mergeCells.mergedCellInfoCollection.getInfo(select[0], select[1]); + /** + * Load the previously saved sizes using the persistentState plugin. + * + * @returns {Array} + */ - if (info) { - select[0] = info.row; - select[1] = info.col; - select[2] = info.row + info.rowspan - 1; - select[3] = info.col + info.colspan - 1; - } -} + }, { + key: 'loadManualColumnWidths', + value: function loadManualColumnWidths() { + var storedState = {}; -function onAfterCreateCol(col, count) { - if (this.mergeCells) { - this.mergeCells.shiftCollection('right', col, count); - } -} + this.hot.runHooks('persistentStateLoad', 'manualColumnWidths', storedState); -function onAfterRemoveCol(col, count) { - if (this.mergeCells) { - this.mergeCells.shiftCollection('left', col, count); - } -} + return storedState.value; + } -function onAfterCreateRow(row, count) { - if (this.mergeCells) { - this.mergeCells.shiftCollection('down', row, count); - } -} + /** + * Set the resize handle position. + * + * @param {HTMLCellElement} TH TH HTML element. + */ -function onAfterRemoveRow(row, count) { - if (this.mergeCells) { - this.mergeCells.shiftCollection('up', row, count); - } -} + }, { + key: 'setupHandlePosition', + value: function setupHandlePosition(TH) { + var _this3 = this; -var hook = _pluginHooks2.default.getSingleton(); + if (!TH.parentNode) { + return false; + } -hook.add('beforeInit', beforeInit); -hook.add('afterInit', afterInit); -hook.add('afterUpdateSettings', afterUpdateSettings); -hook.add('beforeKeyDown', onBeforeKeyDown); -hook.add('modifyTransformStart', modifyTransformFactory('modifyTransformStart')); -hook.add('modifyTransformEnd', modifyTransformFactory('modifyTransformEnd')); -hook.add('beforeSetRangeEnd', beforeSetRangeEnd); -hook.add('beforeDrawBorders', beforeDrawAreaBorders); -hook.add('afterIsMultipleSelection', isMultipleSelection); -hook.add('afterRenderer', afterRenderer); -hook.add('afterContextMenuDefaultOptions', addMergeActionsToContextMenu); -hook.add('afterGetCellMeta', afterGetCellMeta); -hook.add('afterViewportRowCalculatorOverride', afterViewportRowCalculatorOverride); -hook.add('afterViewportColumnCalculatorOverride', afterViewportColumnCalculatorOverride); -hook.add('modifyAutofillRange', modifyAutofillRange); -hook.add('afterCreateCol', onAfterCreateCol); -hook.add('afterRemoveCol', onAfterRemoveCol); -hook.add('afterCreateRow', onAfterCreateRow); -hook.add('afterRemoveRow', onAfterRemoveRow); + this.currentTH = TH; -exports.default = MergeCells; + var col = this.hot.view.wt.wtTable.getCoords(TH).col; // getCoords returns CellCoords + var headerHeight = (0, _element.outerHeight)(this.currentTH); -/***/ }), -/* 256 */ -/***/ (function(module, exports, __webpack_require__) { + if (col >= 0) { + // if not col header + var box = this.currentTH.getBoundingClientRect(); -"use strict"; + this.currentCol = col; + this.selectedCols = []; + if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.cols) { + var _hot$getSelectedRange = this.hot.getSelectedRange(), + from = _hot$getSelectedRange.from, + to = _hot$getSelectedRange.to; -exports.__esModule = true; + var start = from.col; + var end = to.col; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + if (start >= end) { + start = to.col; + end = from.col; + } -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + if (this.currentCol >= start && this.currentCol <= end) { + (0, _number.rangeEach)(start, end, function (i) { + return _this3.selectedCols.push(i); + }); + } else { + this.selectedCols.push(this.currentCol); + } + } else { + this.selectedCols.push(this.currentCol); + } -var _pluginHooks = __webpack_require__(8); + this.startOffset = box.left - 6; + this.startWidth = parseInt(box.width, 10); + this.handle.style.top = box.top + 'px'; + this.handle.style.left = this.startOffset + this.startWidth + 'px'; + this.handle.style.height = headerHeight + 'px'; + this.hot.rootElement.appendChild(this.handle); + } + } -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + /** + * Refresh the resize handle position. + */ -var _element = __webpack_require__(0); + }, { + key: 'refreshHandlePosition', + value: function refreshHandlePosition() { + this.handle.style.left = this.startOffset + this.currentWidth + 'px'; + } -var _browser = __webpack_require__(25); + /** + * Set the resize guide position. + */ -var _base = __webpack_require__(12); + }, { + key: 'setupGuidePosition', + value: function setupGuidePosition() { + var handleHeight = parseInt((0, _element.outerHeight)(this.handle), 10); + var handleBottomPosition = parseInt(this.handle.style.top, 10) + handleHeight; + var maximumVisibleElementHeight = parseInt(this.hot.view.maximumVisibleElementHeight(0), 10); -var _base2 = _interopRequireDefault(_base); + (0, _element.addClass)(this.handle, 'active'); + (0, _element.addClass)(this.guide, 'active'); -var _eventManager = __webpack_require__(4); + this.guide.style.top = handleBottomPosition + 'px'; + this.guide.style.left = this.handle.style.left; + this.guide.style.height = maximumVisibleElementHeight - handleHeight + 'px'; + this.hot.rootElement.appendChild(this.guide); + } -var _eventManager2 = _interopRequireDefault(_eventManager); + /** + * Refresh the resize guide position. + */ -var _plugins = __webpack_require__(5); + }, { + key: 'refreshGuidePosition', + value: function refreshGuidePosition() { + this.guide.style.left = this.handle.style.left; + } -var _src = __webpack_require__(11); + /** + * Hide both the resize handle and resize guide. + */ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + }, { + key: 'hideHandleAndGuide', + value: function hideHandleAndGuide() { + (0, _element.removeClass)(this.handle, 'active'); + (0, _element.removeClass)(this.guide, 'active'); + } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** + * Check if provided element is considered a column header. + * + * @param {HTMLElement} element HTML element. + * @returns {Boolean} + */ -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + }, { + key: 'checkIfColumnHeader', + value: function checkIfColumnHeader(element) { + if (element != this.hot.rootElement) { + var parent = element.parentNode; -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + if (parent.tagName === 'THEAD') { + return true; + } -/** - * @private - * @plugin MultipleSelectionHandles - */ -var MultipleSelectionHandles = function (_BasePlugin) { - _inherits(MultipleSelectionHandles, _BasePlugin); + return this.checkIfColumnHeader(parent); + } - /** - * @param {Object} hotInstance - */ - function MultipleSelectionHandles(hotInstance) { - _classCallCheck(this, MultipleSelectionHandles); + return false; + } /** - * @type {Array} + * Get the TH element from the provided element. + * + * @param {HTMLElement} element HTML element. + * @returns {HTMLElement} */ - var _this2 = _possibleConstructorReturn(this, (MultipleSelectionHandles.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles)).call(this, hotInstance)); - _this2.dragged = []; + }, { + key: 'getTHFromTargetElement', + value: function getTHFromTargetElement(element) { + if (element.tagName != 'TABLE') { + if (element.tagName == 'TH') { + return element; + } + return this.getTHFromTargetElement(element.parentNode); + } + + return null; + } + /** - * Instance of EventManager. + * 'mouseover' event callback - set the handle position. * - * @type {EventManager} + * @private + * @param {MouseEvent} event */ - _this2.eventManager = null; + + }, { + key: 'onMouseOver', + value: function onMouseOver(event) { + if (this.checkIfColumnHeader(event.target)) { + var th = this.getTHFromTargetElement(event.target); + + if (!th) { + return; + } + + var colspan = th.getAttribute('colspan'); + + if (th && (colspan === null || colspan === 1)) { + if (!this.pressed) { + this.setupHandlePosition(th); + } + } + } + } + /** - * @type {null} + * Auto-size row after doubleclick - callback. + * + * @private */ - _this2.lastSetCell = null; - return _this2; - } - /** - * Check if the plugin is enabled in the handsontable settings. - * - * @returns {Boolean} - */ + }, { + key: 'afterMouseDownTimeout', + value: function afterMouseDownTimeout() { + var _this4 = this; + + var render = function render() { + _this4.hot.forceFullRender = true; + _this4.hot.view.render(); // updates all + _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); + }; + var resize = function resize(selectedCol, forceRender) { + var hookNewSize = _this4.hot.runHooks('beforeColumnResize', selectedCol, _this4.newSize, true); + + if (hookNewSize !== void 0) { + _this4.newSize = hookNewSize; + } + + if (_this4.hot.getSettings().stretchH === 'all') { + _this4.clearManualSize(selectedCol); + } else { + _this4.setManualSize(selectedCol, _this4.newSize); // double click sets by auto row size plugin + } + + if (forceRender) { + render(); + } + + _this4.saveManualColumnWidths(); + + _this4.hot.runHooks('afterColumnResize', selectedCol, _this4.newSize, true); + }; + if (this.dblclick >= 2) { + var selectedColsLength = this.selectedCols.length; - _createClass(MultipleSelectionHandles, [{ - key: 'isEnabled', - value: function isEnabled() { - return (0, _browser.isMobileBrowser)(); + if (selectedColsLength > 1) { + (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { + resize(selectedCol); + }); + render(); + } else { + (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { + resize(selectedCol, true); + }); + } + } + this.dblclick = 0; + this.autoresizeTimeout = null; } /** - * Enable plugin for this Handsontable instance. + * 'mousedown' event callback. + * + * @private + * @param {MouseEvent} e */ }, { - key: 'enablePlugin', - value: function enablePlugin() { - if (this.enabled) { - return; - } - if (!this.eventManager) { - this.eventManager = new _eventManager2.default(this); + key: 'onMouseDown', + value: function onMouseDown(event) { + var _this5 = this; + + if ((0, _element.hasClass)(event.target, 'manualColumnResizer')) { + this.setupGuidePosition(); + this.pressed = this.hot; + + if (this.autoresizeTimeout === null) { + this.autoresizeTimeout = setTimeout(function () { + return _this5.afterMouseDownTimeout(); + }, 500); + + this.hot._registerTimeout(this.autoresizeTimeout); + } + this.dblclick++; + + this.startX = (0, _event.pageX)(event); + this.newSize = this.startWidth; } - this.registerListeners(); - _get(MultipleSelectionHandles.prototype.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles.prototype), 'enablePlugin', this).call(this); } /** - * Bind the touch events + * 'mousemove' event callback - refresh the handle and guide positions, cache the new column width. + * * @private + * @param {MouseEvent} e */ }, { - key: 'registerListeners', - value: function registerListeners() { - var _this = this; - - function removeFromDragged(query) { - - if (_this.dragged.length === 1) { - // clear array - _this.dragged.splice(0, _this.dragged.length); + key: 'onMouseMove', + value: function onMouseMove(event) { + var _this6 = this; - return true; - } + if (this.pressed) { + this.currentWidth = this.startWidth + ((0, _event.pageX)(event) - this.startX); - var entryPosition = _this.dragged.indexOf(query); + (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { + _this6.newSize = _this6.setManualSize(selectedCol, _this6.currentWidth); + }); - if (entryPosition == -1) { - return false; - } else if (entryPosition === 0) { - _this.dragged = _this.dragged.slice(0, 1); - } else if (entryPosition == 1) { - _this.dragged = _this.dragged.slice(-1); - } + this.refreshHandlePosition(); + this.refreshGuidePosition(); } + } - this.eventManager.addEventListener(this.hot.rootElement, 'touchstart', function (event) { - var selectedRange = void 0; + /** + * 'mouseup' event callback - apply the column resizing. + * + * @private + * @param {MouseEvent} e + */ - if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) { - selectedRange = _this.hot.getSelectedRange(); + }, { + key: 'onMouseUp', + value: function onMouseUp(event) { + var _this7 = this; - _this.dragged.push('topLeft'); + var render = function render() { + _this7.hot.forceFullRender = true; + _this7.hot.view.render(); // updates all + _this7.hot.view.wt.wtOverlays.adjustElementsSize(true); + }; + var resize = function resize(selectedCol, forceRender) { + _this7.hot.runHooks('beforeColumnResize', selectedCol, _this7.newSize); - _this.touchStartRange = { - width: selectedRange.getWidth(), - height: selectedRange.getHeight(), - direction: selectedRange.getDirection() - }; + if (forceRender) { + render(); + } - event.preventDefault(); - return false; - } else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) { - selectedRange = _this.hot.getSelectedRange(); + _this7.saveManualColumnWidths(); - _this.dragged.push('bottomRight'); + _this7.hot.runHooks('afterColumnResize', selectedCol, _this7.newSize); + }; - _this.touchStartRange = { - width: selectedRange.getWidth(), - height: selectedRange.getHeight(), - direction: selectedRange.getDirection() - }; + if (this.pressed) { + this.hideHandleAndGuide(); + this.pressed = false; - event.preventDefault(); - return false; - } - }); + if (this.newSize != this.startWidth) { + var selectedColsLength = this.selectedCols.length; - this.eventManager.addEventListener(this.hot.rootElement, 'touchend', function (event) { - if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) { - removeFromDragged.call(_this, 'topLeft'); + if (selectedColsLength > 1) { + (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { + resize(selectedCol); + }); + render(); + } else { + (0, _array.arrayEach)(this.selectedCols, function (selectedCol) { + resize(selectedCol, true); + }); + } + } - _this.touchStartRange = void 0; + this.setupHandlePosition(this.currentTH); + } + } - event.preventDefault(); - return false; - } else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) { - removeFromDragged.call(_this, 'bottomRight'); + /** + * Bind the mouse events. + * + * @private + */ - _this.touchStartRange = void 0; + }, { + key: 'bindEvents', + value: function bindEvents() { + var _this8 = this; - event.preventDefault(); - return false; - } + this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) { + return _this8.onMouseOver(e); }); + this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) { + return _this8.onMouseDown(e); + }); + this.eventManager.addEventListener(window, 'mousemove', function (e) { + return _this8.onMouseMove(e); + }); + this.eventManager.addEventListener(window, 'mouseup', function (e) { + return _this8.onMouseUp(e); + }); + } - this.eventManager.addEventListener(this.hot.rootElement, 'touchmove', function (event) { - var scrollTop = (0, _element.getWindowScrollTop)(), - scrollLeft = (0, _element.getWindowScrollLeft)(), - endTarget = void 0, - targetCoords = void 0, - selectedRange = void 0, - rangeWidth = void 0, - rangeHeight = void 0, - rangeDirection = void 0, - newRangeCoords = void 0; - - if (_this.dragged.length === 0) { - return; - } + /** + * Cache the current column width. + * + * @param {Number} column Visual column index. + * @param {Number} width Column width. + * @returns {Number} + */ - endTarget = document.elementFromPoint(event.touches[0].screenX - scrollLeft, event.touches[0].screenY - scrollTop); + }, { + key: 'setManualSize', + value: function setManualSize(column, width) { + width = Math.max(width, 20); - if (!endTarget || endTarget === _this.lastSetCell) { - return; - } + /** + * We need to run col through modifyCol hook, in case the order of displayed columns is different than the order + * in data source. For instance, this order can be modified by manualColumnMove plugin. + */ + column = this.hot.runHooks('modifyCol', column); - if (endTarget.nodeName == 'TD' || endTarget.nodeName == 'TH') { - targetCoords = _this.hot.getCoords(endTarget); + this.manualColumnWidths[column] = width; - if (targetCoords.col == -1) { - targetCoords.col = 0; - } + return width; + } - selectedRange = _this.hot.getSelectedRange(); - rangeWidth = selectedRange.getWidth(); - rangeHeight = selectedRange.getHeight(); - rangeDirection = selectedRange.getDirection(); + /** + * Clear cache for the current column index. + * + * @param {Number} column Visual column index. + */ - if (rangeWidth == 1 && rangeHeight == 1) { - _this.hot.selection.setRangeEnd(targetCoords); - } + }, { + key: 'clearManualSize', + value: function clearManualSize(column) { + column = this.hot.runHooks('modifyCol', column); - newRangeCoords = _this.getCurrentRangeCoords(selectedRange, targetCoords, _this.touchStartRange.direction, rangeDirection, _this.dragged[0]); + this.manualColumnWidths[column] = void 0; + } - if (newRangeCoords.start !== null) { - _this.hot.selection.setRangeStart(newRangeCoords.start); - } + /** + * Modify the provided column width, based on the plugin settings + * + * @private + * @param {Number} width Column width. + * @param {Number} column Visual column index. + * @returns {Number} + */ - _this.hot.selection.setRangeEnd(newRangeCoords.end); + }, { + key: 'onModifyColWidth', + value: function onModifyColWidth(width, column) { + if (this.enabled) { + column = this.hot.runHooks('modifyCol', column); - _this.lastSetCell = endTarget; + if (this.hot.getSettings().manualColumnResize && this.manualColumnWidths[column]) { + return this.manualColumnWidths[column]; } + } - event.preventDefault(); - }); + return width; } - }, { - key: 'getCurrentRangeCoords', - value: function getCurrentRangeCoords(selectedRange, currentTouch, touchStartDirection, currentDirection, draggedHandle) { - var topLeftCorner = selectedRange.getTopLeftCorner(), - bottomRightCorner = selectedRange.getBottomRightCorner(), - bottomLeftCorner = selectedRange.getBottomLeftCorner(), - topRightCorner = selectedRange.getTopRightCorner(); - var newCoords = { - start: null, - end: null - }; + /** + * Modify the provided column stretched width. This hook decides if specified column should be stretched or not. + * + * @private + * @param {Number} stretchedWidth Stretched width. + * @param {Number} column Physical column index. + * @returns {Number} + */ - switch (touchStartDirection) { - case 'NE-SW': - switch (currentDirection) { - case 'NE-SW': - case 'NW-SE': - if (draggedHandle == 'topLeft') { - newCoords = { - start: new _src.CellCoords(currentTouch.row, selectedRange.highlight.col), - end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col) - }; - } else { - newCoords = { - start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col), - end: new _src.CellCoords(currentTouch.row, topLeftCorner.col) - }; - } - break; - case 'SE-NW': - if (draggedHandle == 'bottomRight') { - newCoords = { - start: new _src.CellCoords(bottomRightCorner.row, currentTouch.col), - end: new _src.CellCoords(currentTouch.row, topLeftCorner.col) - }; - } - break; - default: - break; - } - break; - case 'NW-SE': - switch (currentDirection) { - case 'NE-SW': - if (draggedHandle == 'topLeft') { - newCoords = { - start: currentTouch, - end: bottomLeftCorner - }; - } else { - newCoords.end = currentTouch; - } - break; - case 'NW-SE': - if (draggedHandle == 'topLeft') { - newCoords = { - start: currentTouch, - end: bottomRightCorner - }; - } else { - newCoords.end = currentTouch; - } - break; - case 'SE-NW': - if (draggedHandle == 'topLeft') { - newCoords = { - start: currentTouch, - end: topLeftCorner - }; - } else { - newCoords.end = currentTouch; - } - break; - case 'SW-NE': - if (draggedHandle == 'topLeft') { - newCoords = { - start: currentTouch, - end: topRightCorner - }; - } else { - newCoords.end = currentTouch; - } - break; - default: - break; - } - break; - case 'SW-NE': - switch (currentDirection) { - case 'NW-SE': - if (draggedHandle == 'bottomRight') { - newCoords = { - start: new _src.CellCoords(currentTouch.row, topLeftCorner.col), - end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col) - }; - } else { - newCoords = { - start: new _src.CellCoords(topLeftCorner.row, currentTouch.col), - end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col) - }; - } - break; - // case 'NE-SW': - // - // break; - case 'SW-NE': - if (draggedHandle == 'topLeft') { - newCoords = { - start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col), - end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col) - }; - } else { - newCoords = { - start: new _src.CellCoords(currentTouch.row, topLeftCorner.col), - end: new _src.CellCoords(topLeftCorner.row, currentTouch.col) - }; - } - break; - case 'SE-NW': - if (draggedHandle == 'bottomRight') { - newCoords = { - start: new _src.CellCoords(currentTouch.row, topRightCorner.col), - end: new _src.CellCoords(topLeftCorner.row, currentTouch.col) - }; - } else if (draggedHandle == 'topLeft') { - newCoords = { - start: bottomLeftCorner, - end: currentTouch - }; - } - break; - default: - break; - } - break; - case 'SE-NW': - switch (currentDirection) { - case 'NW-SE': - case 'NE-SW': - case 'SW-NE': - if (draggedHandle == 'topLeft') { - newCoords.end = currentTouch; - } - break; - case 'SE-NW': - if (draggedHandle == 'topLeft') { - newCoords.end = currentTouch; - } else { - newCoords = { - start: currentTouch, - end: topLeftCorner - }; - } - break; - default: - break; - } - break; - default: - break; + }, { + key: 'onBeforeStretchingColumnWidth', + value: function onBeforeStretchingColumnWidth(stretchedWidth, column) { + var width = this.manualColumnWidths[column]; + + if (width === void 0) { + width = stretchedWidth; } - return newCoords; + return width; } /** - * Check if user is currently dragging the handle. + * `beforeColumnResize` hook callback. * - * @returns {boolean} Dragging state + * @private + * @param {Number} currentColumn Index of the resized column. + * @param {Number} newSize Calculated new column width. + * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click. */ }, { - key: 'isDragged', - value: function isDragged() { - return this.dragged.length > 0; + key: 'onBeforeColumnResize', + value: function onBeforeColumnResize() { + // clear the header height cache information + this.hot.view.wt.wtViewport.hasOversizedColumnHeadersMarked = {}; } }]); - return MultipleSelectionHandles; + return ManualColumnResize; }(_base2.default); -(0, _plugins.registerPlugin)('multipleSelectionHandles', MultipleSelectionHandles); +(0, _plugins.registerPlugin)('manualColumnResize', ManualColumnResize); -exports.default = MultipleSelectionHandles; +exports.default = ManualColumnResize; /***/ }), -/* 257 */ +/* 293 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61415,681 +61608,924 @@ exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _jsonPatchDuplex = __webpack_require__(135); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _base = __webpack_require__(13); -var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex); +var _base2 = _interopRequireDefault(_base); -var _localHooks = __webpack_require__(69); +var _pluginHooks = __webpack_require__(7); -var _localHooks2 = _interopRequireDefault(_localHooks); +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); -var _object = __webpack_require__(1); +var _array = __webpack_require__(2); + +var _element = __webpack_require__(0); + +var _number = __webpack_require__(6); + +var _eventManager = __webpack_require__(4); + +var _eventManager2 = _interopRequireDefault(_eventManager); + +var _plugins = __webpack_require__(5); + +var _rowsMapper = __webpack_require__(294); + +var _rowsMapper2 = _interopRequireDefault(_rowsMapper); + +var _backlight = __webpack_require__(295); + +var _backlight2 = _interopRequireDefault(_backlight); + +var _guideline = __webpack_require__(296); + +var _guideline2 = _interopRequireDefault(_guideline); + +var _src = __webpack_require__(12); + +__webpack_require__(297); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } -var _utils = __webpack_require__(259); +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +_pluginHooks2.default.getSingleton().register('beforeRowMove'); +_pluginHooks2.default.getSingleton().register('afterRowMove'); +_pluginHooks2.default.getSingleton().register('unmodifyRow'); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var privatePool = new WeakMap(); +var CSS_PLUGIN = 'ht__manualRowMove'; +var CSS_SHOW_UI = 'show-ui'; +var CSS_ON_MOVING = 'on-moving--rows'; +var CSS_AFTER_SELECTION = 'after-selection--rows'; /** - * @class DataObserver - * @plugin ObserveChanges + * @plugin ManualRowMove + * + * @description + * This plugin allows to change rows order. + * + * API: + * - moveRow - move single row to the new position. + * - moveRows - move many rows (as an array of indexes) to the new position. + * + * If you want apply visual changes, you have to call manually the render() method on the instance of handsontable. + * + * UI components: + * - backlight - highlight of selected rows. + * - guideline - line which shows where rows has been moved. + * + * @class ManualRowMove + * @plugin ManualRowMove */ -var DataObserver = function () { - function DataObserver(observedData) { - _classCallCheck(this, DataObserver); + +var ManualRowMove = function (_BasePlugin) { + _inherits(ManualRowMove, _BasePlugin); + + function ManualRowMove(hotInstance) { + _classCallCheck(this, ManualRowMove); /** - * Observed source data. + * Set up WeakMap of plugin to sharing private parameters; + */ + var _this = _possibleConstructorReturn(this, (ManualRowMove.__proto__ || Object.getPrototypeOf(ManualRowMove)).call(this, hotInstance)); + + privatePool.set(_this, { + rowsToMove: [], + pressed: void 0, + disallowMoving: void 0, + target: { + eventPageY: void 0, + coords: void 0, + TD: void 0, + row: void 0 + } + }); + + /** + * List of last removed row indexes. * * @type {Array} */ - this.observedData = null; + _this.removedRows = []; /** - * JsonPatch observer. + * Object containing visual row indexes mapped to data source indexes. + * + * @type {RowsMapper} + */ + _this.rowsMapper = new _rowsMapper2.default(_this); + /** + * Event Manager object. * * @type {Object} */ - this.observer = null; + _this.eventManager = new _eventManager2.default(_this); /** - * Flag which determines if observer is paused or not. Paused observer doesn't emit `change` hooks. + * Backlight UI object. * - * @type {Boolean} - * @default false + * @type {Object} */ - this.paused = false; - - this.setObservedData(observedData); + _this.backlight = new _backlight2.default(hotInstance); + /** + * Guideline UI object. + * + * @type {Object} + */ + _this.guideline = new _guideline2.default(hotInstance); + return _this; } /** - * Set data to observe. + * Check if plugin is enabled. * - * @param {*} observedData + * @returns {Boolean} */ - _createClass(DataObserver, [{ - key: 'setObservedData', - value: function setObservedData(observedData) { - var _this = this; - - if (this.observer) { - _jsonPatchDuplex2.default.unobserve(this.observedData, this.observer); - } - this.observedData = observedData; - this.observer = _jsonPatchDuplex2.default.observe(this.observedData, function (patches) { - return _this.onChange(patches); - }); + _createClass(ManualRowMove, [{ + key: 'isEnabled', + value: function isEnabled() { + return !!this.hot.getSettings().manualRowMove; } /** - * Check if observer was paused. - * - * @returns {Boolean} + * Enable the plugin. */ }, { - key: 'isPaused', - value: function isPaused() { - return this.paused; + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; + + if (this.enabled) { + return; + } + + this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) { + return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations); + }); + this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) { + return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations); + }); + this.addHook('afterScrollHorizontally', function () { + return _this2.onAfterScrollHorizontally(); + }); + this.addHook('modifyRow', function (row, source) { + return _this2.onModifyRow(row, source); + }); + this.addHook('beforeRemoveRow', function (index, amount) { + return _this2.onBeforeRemoveRow(index, amount); + }); + this.addHook('afterRemoveRow', function () { + return _this2.onAfterRemoveRow(); + }); + this.addHook('afterCreateRow', function (index, amount) { + return _this2.onAfterCreateRow(index, amount); + }); + this.addHook('afterLoadData', function () { + return _this2.onAfterLoadData(); + }); + this.addHook('beforeColumnSort', function (column, order) { + return _this2.onBeforeColumnSort(column, order); + }); + this.addHook('unmodifyRow', function (row) { + return _this2.onUnmodifyRow(row); + }); + + this.registerEvents(); + + // TODO: move adding plugin classname to BasePlugin. + (0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN); + + _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'enablePlugin', this).call(this); } /** - * Pause observer (stop emitting all detected changes). + * Updates the plugin to use the latest options you have specified. */ }, { - key: 'pause', - value: function pause() { - this.paused = true; + key: 'updatePlugin', + value: function updatePlugin() { + this.disablePlugin(); + this.enablePlugin(); + + this.onAfterPluginsInitialized(); + + _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'updatePlugin', this).call(this); } /** - * Resume observer (emit all detected changes). + * Disable plugin for this Handsontable instance. */ }, { - key: 'resume', - value: function resume() { - this.paused = false; + key: 'disablePlugin', + value: function disablePlugin() { + var pluginSettings = this.hot.getSettings().manualRowMove; + + if (Array.isArray(pluginSettings)) { + this.rowsMapper.clearMap(); + } + + (0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN); + + this.unregisterEvents(); + this.backlight.destroy(); + this.guideline.destroy(); + + _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'disablePlugin', this).call(this); } /** - * JsonPatch on change listener. + * Move a single row. * - * @private - * @param {Array} patches An array of object passed from jsonpatch. + * @param {Number} row Visual row index to be moved. + * @param {Number} target Visual row index being a target for the moved row. */ }, { - key: 'onChange', - value: function onChange(patches) { - this.runLocalHooks('change', (0, _utils.cleanPatches)(patches)); + key: 'moveRow', + value: function moveRow(row, target) { + this.moveRows([row], target); } /** - * Destroy observer instance. + * Move multiple rows. + * + * @param {Array} rows Array of visual row indexes to be moved. + * @param {Number} target Visual row index being a target for the moved rows. */ }, { - key: 'destroy', - value: function destroy() { - _jsonPatchDuplex2.default.unobserve(this.observedData, this.observer); - this.observedData = null; - this.observer = null; - } - }]); - - return DataObserver; -}(); + key: 'moveRows', + value: function moveRows(rows, target) { + var _this3 = this; -(0, _object.mixin)(DataObserver, _localHooks2.default); + var priv = privatePool.get(this); + var beforeMoveHook = this.hot.runHooks('beforeRowMove', rows, target); -exports.default = DataObserver; + priv.disallowMoving = beforeMoveHook === false; -/***/ }), -/* 258 */ -/***/ (function(module, exports, __webpack_require__) { + if (!priv.disallowMoving) { + // first we need to rewrite an visual indexes to physical for save reference after move + (0, _array.arrayEach)(rows, function (row, index, array) { + array[index] = _this3.rowsMapper.getValueByIndex(row); + }); -"use strict"; + // next, when we have got an physical indexes, we can move rows + (0, _array.arrayEach)(rows, function (row, index) { + var actualPosition = _this3.rowsMapper.getIndexByValue(row); + if (actualPosition !== target) { + _this3.rowsMapper.moveRow(actualPosition, target + index); + } + }); -exports.__esModule = true; + // after moving we have to clear rowsMapper from null entries + this.rowsMapper.clearNull(); + } -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + this.hot.runHooks('afterRowMove', rows, target); + } -var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + /** + * Correct the cell selection after the move action. Fired only when action was made with a mouse. + * That means that changing the row order using the API won't correct the selection. + * + * @private + * @param {Number} startRow Visual row index for the start of the selection. + * @param {Number} endRow Visual row index for the end of the selection. + */ -var _base = __webpack_require__(12); + }, { + key: 'changeSelection', + value: function changeSelection(startRow, endRow) { + var selection = this.hot.selection; + var lastColIndex = this.hot.countCols() - 1; -var _base2 = _interopRequireDefault(_base); + selection.setRangeStartOnly(new _src.CellCoords(startRow, 0)); + selection.setRangeEnd(new _src.CellCoords(endRow, lastColIndex), false); + } -var _jsonPatchDuplex = __webpack_require__(135); + /** + * Get the sum of the heights of rows in the provided range. + * + * @private + * @param {Number} from Visual row index. + * @param {Number} to Visual row index. + * @returns {Number} + */ -var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex); + }, { + key: 'getRowsHeight', + value: function getRowsHeight(from, to) { + var height = 0; -var _dataObserver = __webpack_require__(257); + for (var i = from; i < to; i++) { + var rowHeight = this.hot.view.wt.wtTable.getRowHeight(i) || 23; -var _dataObserver2 = _interopRequireDefault(_dataObserver); + height += rowHeight; + } -var _array = __webpack_require__(2); + return height; + } -var _plugins = __webpack_require__(5); + /** + * Load initial settings when persistent state is saved or when plugin was initialized as an array. + * + * @private + */ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + }, { + key: 'initialSettings', + value: function initialSettings() { + var pluginSettings = this.hot.getSettings().manualRowMove; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + if (Array.isArray(pluginSettings)) { + this.moveRows(pluginSettings, 0); + } else if (pluginSettings !== void 0) { + var persistentState = this.persistentStateLoad(); -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + if (persistentState.length) { + this.moveRows(persistentState, 0); + } + } + } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + /** + * Check if the provided row is in the fixedRowsTop section. + * + * @private + * @param {Number} row Visual row index to check. + * @returns {Boolean} + */ -// Handsontable.hooks.register('afterChangesObserved'); + }, { + key: 'isFixedRowTop', + value: function isFixedRowTop(row) { + return row < this.hot.getSettings().fixedRowsTop; + } -/** - * @plugin ObserveChanges - * - * @description - * This plugin allows to observe data source changes. - * - * By default, the plugin is declared as `undefined`, which makes it disabled. - * Enabling this plugin switches the table into one-way data binding where changes are applied into the data source (outside from the table) - * will be automatically reflected in the table. - * - * ```js - * ... - * // as a boolean - * observeChanges: true, - * ... - * ``` - * - * To configure this plugin see {@link Options#observeChanges}. - */ -var ObserveChanges = function (_BasePlugin) { - _inherits(ObserveChanges, _BasePlugin); + /** + * Check if the provided row is in the fixedRowsBottom section. + * + * @private + * @param {Number} row Visual row index to check. + * @returns {Boolean} + */ - function ObserveChanges(hotInstance) { - _classCallCheck(this, ObserveChanges); + }, { + key: 'isFixedRowBottom', + value: function isFixedRowBottom(row) { + return row > this.hot.getSettings().fixedRowsBottom; + } /** - * Instance of {@link DataObserver}. + * Save the manual row positions to the persistent state. * - * @type {DataObserver} + * @private */ - var _this = _possibleConstructorReturn(this, (ObserveChanges.__proto__ || Object.getPrototypeOf(ObserveChanges)).call(this, hotInstance)); - _this.observer = null; - return _this; - } + }, { + key: 'persistentStateSave', + value: function persistentStateSave() { + this.hot.runHooks('persistentStateSave', 'manualRowMove', this.rowsMapper._arrayMap); + } - /** - * Check if the plugin is enabled in the handsontable settings. - * - * @returns {Boolean} - */ + /** + * Load the manual row positions from the persistent state. + * + * @private + * @returns {Array} Stored state. + */ + + }, { + key: 'persistentStateLoad', + value: function persistentStateLoad() { + var storedState = {}; + this.hot.runHooks('persistentStateLoad', 'manualRowMove', storedState); - _createClass(ObserveChanges, [{ - key: 'isEnabled', - value: function isEnabled() { - return this.hot.getSettings().observeChanges; + return storedState.value ? storedState.value : []; } /** - * Enable plugin for this Handsontable instance. + * Prepare array of indexes based on actual selection. + * + * @private + * @returns {Array} */ }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + key: 'prepareRowsToMoving', + value: function prepareRowsToMoving() { + var selection = this.hot.getSelectedRange(); + var selectedRows = []; - if (this.enabled) { - return; - } - if (!this.observer) { - this.observer = new _dataObserver2.default(this.hot.getSourceData()); - this._exposePublicApi(); + if (!selection) { + return selectedRows; } - this.observer.addLocalHook('change', function (patches) { - return _this2.onDataChange(patches); - }); - this.addHook('afterCreateRow', function () { - return _this2.onAfterTableAlter(); - }); - this.addHook('afterRemoveRow', function () { - return _this2.onAfterTableAlter(); - }); - this.addHook('afterCreateCol', function () { - return _this2.onAfterTableAlter(); - }); - this.addHook('afterRemoveCol', function () { - return _this2.onAfterTableAlter(); - }); - this.addHook('afterChange', function (changes, source) { - return _this2.onAfterTableAlter(source); - }); - this.addHook('afterLoadData', function (firstRun) { - return _this2.onAfterLoadData(firstRun); + var from = selection.from, + to = selection.to; + + var start = Math.min(from.row, to.row); + var end = Math.max(from.row, to.row); + + (0, _number.rangeEach)(start, end, function (i) { + selectedRows.push(i); }); - _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'enablePlugin', this).call(this); + return selectedRows; } - /** - * Disable plugin for this Handsontable instance. - */ + /** + * Update the UI visual position. + * + * @private + */ + + }, { + key: 'refreshPositions', + value: function refreshPositions() { + var priv = privatePool.get(this); + var coords = priv.target.coords; + var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleRow(); + var lastVisible = this.hot.view.wt.wtTable.getLastVisibleRow(); + var fixedRows = this.hot.getSettings().fixedRowsTop; + var countRows = this.hot.countRows(); + + if (coords.row < fixedRows && firstVisible > 0) { + this.hot.scrollViewportTo(firstVisible - 1); + } + if (coords.row >= lastVisible && lastVisible < countRows) { + this.hot.scrollViewportTo(lastVisible + 1, undefined, true); + } + + var wtTable = this.hot.view.wt.wtTable; + var TD = priv.target.TD; + var rootElementOffset = (0, _element.offset)(this.hot.rootElement); + var tdOffsetTop = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row); + var mouseOffsetTop = priv.target.eventPageY - rootElementOffset.top + wtTable.holder.scrollTop; + var hiderHeight = wtTable.hider.offsetHeight; + var tbodyOffsetTop = wtTable.TBODY.offsetTop; + var backlightElemMarginTop = this.backlight.getOffset().top; + var backlightElemHeight = this.backlight.getSize().height; + + if (this.isFixedRowTop(coords.row)) { + tdOffsetTop += wtTable.holder.scrollTop; + } + + // todo: fixedRowsBottom + // if (this.isFixedRowBottom(coords.row)) { + // + // } + + if (coords.row < 0) { + // if hover on colHeader + priv.target.row = firstVisible > 0 ? firstVisible - 1 : firstVisible; + } else if (TD.offsetHeight / 2 + tdOffsetTop <= mouseOffsetTop) { + // if hover on lower part of TD + priv.target.row = coords.row + 1; + // unfortunately first row is bigger than rest + tdOffsetTop += coords.row === 0 ? TD.offsetHeight - 1 : TD.offsetHeight; + } else { + // elsewhere on table + priv.target.row = coords.row; + } + + var backlightTop = mouseOffsetTop; + var guidelineTop = tdOffsetTop; + + if (mouseOffsetTop + backlightElemHeight + backlightElemMarginTop >= hiderHeight) { + // prevent display backlight below table + backlightTop = hiderHeight - backlightElemHeight - backlightElemMarginTop; + } else if (mouseOffsetTop + backlightElemMarginTop < tbodyOffsetTop) { + // prevent display above below table + backlightTop = tbodyOffsetTop + Math.abs(backlightElemMarginTop); + } + + if (tdOffsetTop >= hiderHeight - 1) { + // prevent display guideline below table + guidelineTop = hiderHeight - 1; + } + + var topOverlayHeight = 0; + if (this.hot.view.wt.wtOverlays.topOverlay) { + topOverlayHeight = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.TABLE.offsetHeight; + } - }, { - key: 'disablePlugin', - value: function disablePlugin() { - if (this.observer) { - this.observer.destroy(); - this.observer = null; - this._deletePublicApi(); + if (coords.row >= fixedRows && guidelineTop - wtTable.holder.scrollTop < topOverlayHeight) { + this.hot.scrollViewportTo(coords.row); } - _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'disablePlugin', this).call(this); + this.backlight.setPosition(backlightTop); + this.guideline.setPosition(guidelineTop); } /** - * Data change observer. + * This method checks arrayMap from rowsMapper and updates the rowsMapper if it's necessary. * * @private - * @param {Array} patches An array of objects which every item defines coordinates where data was changed. */ }, { - key: 'onDataChange', - value: function onDataChange(patches) { - var _this3 = this; + key: 'updateRowsMapper', + value: function updateRowsMapper() { + var countRows = this.hot.countSourceRows(); + var rowsMapperLen = this.rowsMapper._arrayMap.length; - if (!this.observer.isPaused()) { - var sourceName = this.pluginName + '.change'; - var actions = { - add: function add(patch) { - if (isNaN(patch.col)) { - _this3.hot.runHooks('afterCreateRow', patch.row, 1, sourceName); - } else { - _this3.hot.runHooks('afterCreateCol', patch.col, 1, sourceName); - } - }, - remove: function remove(patch) { - if (isNaN(patch.col)) { - _this3.hot.runHooks('afterRemoveRow', patch.row, 1, sourceName); - } else { - _this3.hot.runHooks('afterRemoveCol', patch.col, 1, sourceName); - } - }, - replace: function replace(patch) { - _this3.hot.runHooks('afterChange', [patch.row, patch.col, null, patch.value], sourceName); - } - }; + if (rowsMapperLen === 0) { + this.rowsMapper.createMap(countRows || this.hot.getSettings().startRows); + } else if (rowsMapperLen < countRows) { + var diff = countRows - rowsMapperLen; - (0, _array.arrayEach)(patches, function (patch) { - if (actions[patch.op]) { - actions[patch.op](patch); + this.rowsMapper.insertItems(rowsMapperLen, diff); + } else if (rowsMapperLen > countRows) { + var maxIndex = countRows - 1; + var rowsToRemove = []; + + (0, _array.arrayEach)(this.rowsMapper._arrayMap, function (value, index) { + if (value > maxIndex) { + rowsToRemove.push(index); } }); - this.hot.render(); - } - this.hot.runHooks('afterChangesObserved'); + this.rowsMapper.removeItems(rowsToRemove); + } } /** - * On after table alter listener. Prevents infinity loop between internal and external data changing. + * Bind the events used by the plugin. * * @private - * @param source */ }, { - key: 'onAfterTableAlter', - value: function onAfterTableAlter(source) { + key: 'registerEvents', + value: function registerEvents() { var _this4 = this; - if (source !== 'loadData') { - this.observer.pause(); - this.hot.addHookOnce('afterChangesObserved', function () { - return _this4.observer.resume(); - }); - } + this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) { + return _this4.onMouseMove(event); + }); + this.eventManager.addEventListener(document.documentElement, 'mouseup', function () { + return _this4.onMouseUp(); + }); } /** - * On after load data listener. + * Unbind the events used by the plugin. * * @private - * @param {Boolean} firstRun `true` if event was fired first time. - */ - - }, { - key: 'onAfterLoadData', - value: function onAfterLoadData(firstRun) { - if (!firstRun) { - this.observer.setObservedData(this.hot.getSourceData()); - } - } - - /** - * Destroy plugin instance. */ }, { - key: 'destroy', - value: function destroy() { - if (this.observer) { - this.observer.destroy(); - this._deletePublicApi(); - } - _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'destroy', this).call(this); + key: 'unregisterEvents', + value: function unregisterEvents() { + this.eventManager.clear(); } /** - * Expose plugins methods to the core. + * `beforeColumnSort` hook callback. If user uses the sorting, manual row moving is disabled. * * @private + * @param {Number} column Column index where soring is present + * @param {*} order State of sorting. ASC/DESC/None */ }, { - key: '_exposePublicApi', - value: function _exposePublicApi() { - var _this5 = this; - - var hot = this.hot; + key: 'onBeforeColumnSort', + value: function onBeforeColumnSort(column, order) { + var priv = privatePool.get(this); - hot.pauseObservingChanges = function () { - return _this5.observer.pause(); - }; - hot.resumeObservingChanges = function () { - return _this5.observer.resume(); - }; - hot.isPausedObservingChanges = function () { - return _this5.observer.isPaused(); - }; + priv.disallowMoving = order !== void 0; } /** - * Delete all previously exposed methods. + * Change the behavior of selection / dragging. * * @private + * @param {MouseEvent} event + * @param {CellCoords} coords Visual coordinates. + * @param {HTMLElement} TD + * @param {Object} blockCalculations */ }, { - key: '_deletePublicApi', - value: function _deletePublicApi() { - var hot = this.hot; - - delete hot.pauseObservingChanges; - delete hot.resumeObservingChanges; - delete hot.isPausedObservingChanges; - } - }]); - - return ObserveChanges; -}(_base2.default); - -exports.default = ObserveChanges; - - -(0, _plugins.registerPlugin)('observeChanges', ObserveChanges); - -/***/ }), -/* 259 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + key: 'onBeforeOnCellMouseDown', + value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) { + var wtTable = this.hot.view.wt.wtTable; + var isHeaderSelection = this.hot.selection.selectedHeader.rows; + var selection = this.hot.getSelectedRange(); + var priv = privatePool.get(this); + if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0) { + priv.pressed = false; + priv.rowsToMove.length = 0; + (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]); + return; + } -exports.__esModule = true; + var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended(); + var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended(); -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + if (guidelineIsNotReady && backlightIsNotReady) { + this.guideline.appendTo(wtTable.hider); + this.backlight.appendTo(wtTable.hider); + } -exports.cleanPatches = cleanPatches; -exports.parsePath = parsePath; + var from = selection.from, + to = selection.to; -var _array = __webpack_require__(2); + var start = Math.min(from.row, to.row); + var end = Math.max(from.row, to.row); -/** - * Clean and extend patches from jsonpatch observer. - * - * @param {Array} patches - * @returns {Array} - */ -function cleanPatches(patches) { - var newOrRemovedColumns = []; + if (coords.col < 0 && coords.row >= start && coords.row <= end) { + blockCalculations.row = true; + priv.pressed = true; + priv.target.eventPageY = event.pageY; + priv.target.coords = coords; + priv.target.TD = TD; + priv.rowsToMove = this.prepareRowsToMoving(); - /** - * If observeChanges uses native Object.observe method, then it produces patches for length property. Filter them. - * If path can't be parsed. Filter it. - */ - patches = (0, _array.arrayFilter)(patches, function (patch) { - if (/[/]length/ig.test(patch.path)) { - return false; - } - if (!parsePath(patch.path)) { - return false; - } + var leftPos = wtTable.holder.scrollLeft + this.hot.view.wt.wtViewport.getRowHeaderWidth(); - return true; - }); - /** - * Extend patches with changed cells coords - */ - patches = (0, _array.arrayMap)(patches, function (patch) { - var coords = parsePath(patch.path); + this.backlight.setPosition(null, leftPos); + this.backlight.setSize(wtTable.hider.offsetWidth - leftPos, this.getRowsHeight(start, end + 1)); + this.backlight.setOffset((this.getRowsHeight(start, coords.row) + event.layerY) * -1, null); - patch.row = coords.row; - patch.col = coords.col; + (0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING); - return patch; - }); - /** - * Removing or adding column will produce one patch for each table row. - * Leaves only one patch for each column add/remove operation. - */ - patches = (0, _array.arrayFilter)(patches, function (patch) { - if (['add', 'remove'].indexOf(patch.op) !== -1 && !isNaN(patch.col)) { - if (newOrRemovedColumns.indexOf(patch.col) !== -1) { - return false; + this.refreshPositions(); + } else { + (0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION); + priv.pressed = false; + priv.rowsToMove.length = 0; } - newOrRemovedColumns.push(patch.col); } - return true; - }); - newOrRemovedColumns.length = 0; + /** + * 'mouseMove' event callback. Fired when pointer move on document.documentElement. + * + * @private + * @param {MouseEvent} event `mousemove` event properties. + */ - return patches; -} + }, { + key: 'onMouseMove', + value: function onMouseMove(event) { + var priv = privatePool.get(this); -/** - * Extract coordinates from path where data was changed. - * - * @param {String} path Path describing where data was changed. - * @returns {Object|null} Returns an object with `row` and `col` properties or `null` if path doesn't have necessary information. - */ -function parsePath(path) { - var match = path.match(/^\/(\d+)\/?(.*)?$/); + if (!priv.pressed) { + return; + } - if (!match) { - return null; - } + // callback for browser which doesn't supports CSS pointer-event: none + if (event.realTarget === this.backlight.element) { + var height = this.backlight.getSize().height; + this.backlight.setSize(null, 0); - var _match = _slicedToArray(match, 3), - row = _match[1], - column = _match[2]; + setTimeout(function () { + this.backlight.setPosition(null, height); + }); + } - return { - row: parseInt(row, 10), - col: /^\d*$/.test(column) ? parseInt(column, 10) : column - }; -} + priv.target.eventPageY = event.pageY; + this.refreshPositions(); + } -/***/ }), -/* 260 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell. + * + * @private + * @param {MouseEvent} event `mouseover` event properties. + * @param {CellCoords} coords Visual cell coordinates where was fired event. + * @param {HTMLElement} TD Cell represented as HTMLElement. + * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells. + */ -"use strict"; + }, { + key: 'onBeforeOnCellMouseOver', + value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) { + var selectedRange = this.hot.getSelectedRange(); + var priv = privatePool.get(this); + if (!selectedRange || !priv.pressed) { + return; + } -exports.__esModule = true; + if (priv.rowsToMove.indexOf(coords.row) > -1) { + (0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI); + } else { + (0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI); + } -var _pluginHooks = __webpack_require__(8); + blockCalculations.row = true; + blockCalculations.column = true; + blockCalculations.cell = true; + priv.target.coords = coords; + priv.target.TD = TD; + } -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); + /** + * `onMouseUp` hook callback. + * + * @private + */ -var _plugins = __webpack_require__(5); + }, { + key: 'onMouseUp', + value: function onMouseUp() { + var priv = privatePool.get(this); + var target = priv.target.row; + var rowsLen = priv.rowsToMove.length; -var _object = __webpack_require__(1); + priv.pressed = false; + priv.backlightHeight = 0; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]); -function Storage(prefix) { - var savedKeys; + if (this.hot.selection.selectedHeader.rows) { + (0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION); + } - var saveSavedKeys = function saveSavedKeys() { - window.localStorage[prefix + '__persistentStateKeys'] = JSON.stringify(savedKeys); - }; + if (rowsLen < 1 || target === void 0 || priv.rowsToMove.indexOf(target) > -1 || priv.rowsToMove[rowsLen - 1] === target - 1) { + return; + } - var loadSavedKeys = function loadSavedKeys() { - var keysJSON = window.localStorage[prefix + '__persistentStateKeys']; - var keys = typeof keysJSON == 'string' ? JSON.parse(keysJSON) : void 0; - savedKeys = keys ? keys : []; - }; + this.moveRows(priv.rowsToMove, target); - var clearSavedKeys = function clearSavedKeys() { - savedKeys = []; - saveSavedKeys(); - }; + this.persistentStateSave(); + this.hot.render(); - loadSavedKeys(); + if (!priv.disallowMoving) { + var selectionStart = this.rowsMapper.getIndexByValue(priv.rowsToMove[0]); + var selectionEnd = this.rowsMapper.getIndexByValue(priv.rowsToMove[rowsLen - 1]); + this.changeSelection(selectionStart, selectionEnd); + } - this.saveValue = function (key, value) { - window.localStorage[prefix + '_' + key] = JSON.stringify(value); - if (savedKeys.indexOf(key) == -1) { - savedKeys.push(key); - saveSavedKeys(); + priv.rowsToMove.length = 0; } - }; - - this.loadValue = function (key, defaultValue) { - - key = typeof key === 'undefined' ? defaultValue : key; - - var value = window.localStorage[prefix + '_' + key]; - return typeof value == 'undefined' ? void 0 : JSON.parse(value); - }; + /** + * `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally. + * + * @private + */ - this.reset = function (key) { - window.localStorage.removeItem(prefix + '_' + key); - }; + }, { + key: 'onAfterScrollHorizontally', + value: function onAfterScrollHorizontally() { + var wtTable = this.hot.view.wt.wtTable; + var headerWidth = this.hot.view.wt.wtViewport.getRowHeaderWidth(); + var scrollLeft = wtTable.holder.scrollLeft; + var posLeft = headerWidth + scrollLeft; - this.resetAll = function () { - for (var index = 0; index < savedKeys.length; index++) { - window.localStorage.removeItem(prefix + '_' + savedKeys[index]); + this.backlight.setPosition(null, posLeft); + this.backlight.setSize(wtTable.hider.offsetWidth - posLeft); } - clearSavedKeys(); - }; -} + /** + * `afterCreateRow` hook callback. + * + * @private + * @param {Number} index Visual index of the created row. + * @param {Number} amount Amount of created rows. + */ -/** - * @private - * @class PersistentState - * @plugin PersistentState - */ -function HandsontablePersistentState() { - var plugin = this; + }, { + key: 'onAfterCreateRow', + value: function onAfterCreateRow(index, amount) { + this.rowsMapper.shiftItems(index, amount); + } - this.init = function () { - var instance = this, - pluginSettings = instance.getSettings().persistentState; + /** + * On before remove row listener. + * + * @private + * @param {Number} index Visual row index. + * @param {Number} amount Defines how many rows removed. + */ - plugin.enabled = !!pluginSettings; + }, { + key: 'onBeforeRemoveRow', + value: function onBeforeRemoveRow(index, amount) { + var _this5 = this; - if (!plugin.enabled) { - removeHooks.call(instance); - return; - } + this.removedRows.length = 0; - if (!instance.storage) { - instance.storage = new Storage(instance.rootElement.id); + if (index !== false) { + // Collect physical row index. + (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) { + _this5.removedRows.push(_this5.hot.runHooks('modifyRow', removedIndex, _this5.pluginName)); + }); + } } - instance.resetState = plugin.resetValue; - - addHooks.call(instance); - }; + /** + * `afterRemoveRow` hook callback. + * + * @private + */ - this.saveValue = function (key, value) { - var instance = this; + }, { + key: 'onAfterRemoveRow', + value: function onAfterRemoveRow() { + this.rowsMapper.unshiftItems(this.removedRows); + } - instance.storage.saveValue(key, value); - }; + /** + * `afterLoadData` hook callback. + * + * @private + */ - this.loadValue = function (key, saveTo) { - var instance = this; + }, { + key: 'onAfterLoadData', + value: function onAfterLoadData() { + this.updateRowsMapper(); + } - saveTo.value = instance.storage.loadValue(key); - }; + /** + * 'modifyRow' hook callback. + * + * @private + * @param {Number} row Visual Row index. + * @returns {Number} Physical row index. + */ - this.resetValue = function (key) { - var instance = this; + }, { + key: 'onModifyRow', + value: function onModifyRow(row, source) { + if (source !== this.pluginName) { + var rowInMapper = this.rowsMapper.getValueByIndex(row); + row = rowInMapper === null ? row : rowInMapper; + } - if (typeof key === 'undefined') { - instance.storage.resetAll(); - } else { - instance.storage.reset(key); + return row; } - }; - var hooks = { - persistentStateSave: plugin.saveValue, - persistentStateLoad: plugin.loadValue, - persistentStateReset: plugin.resetValue - }; + /** + * 'unmodifyRow' hook callback. + * + * @private + * @param {Number} row Physical row index. + * @returns {Number} Visual row index. + */ - for (var hookName in hooks) { - if ((0, _object.hasOwnProperty)(hooks, hookName)) { - _pluginHooks2.default.getSingleton().register(hookName); + }, { + key: 'onUnmodifyRow', + value: function onUnmodifyRow(row) { + var indexInMapper = this.rowsMapper.getIndexByValue(row); + + return indexInMapper === null ? row : indexInMapper; } - } - function addHooks() { - var instance = this; + /** + * `afterPluginsInitialized` hook callback. + * + * @private + */ - for (var hookName in hooks) { - if ((0, _object.hasOwnProperty)(hooks, hookName)) { - instance.addHook(hookName, hooks[hookName]); - } + }, { + key: 'onAfterPluginsInitialized', + value: function onAfterPluginsInitialized() { + this.updateRowsMapper(); + this.initialSettings(); + this.backlight.build(); + this.guideline.build(); } - } - function removeHooks() { - var instance = this; + /** + * Destroy plugin instance. + */ - for (var hookName in hooks) { - if ((0, _object.hasOwnProperty)(hooks, hookName)) { - instance.removeHook(hookName, hooks[hookName]); - } + }, { + key: 'destroy', + value: function destroy() { + this.backlight.destroy(); + this.guideline.destroy(); + + _get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'destroy', this).call(this); } - } -} + }]); -var htPersistentState = new HandsontablePersistentState(); + return ManualRowMove; +}(_base2.default); -_pluginHooks2.default.getSingleton().add('beforeInit', htPersistentState.init); -_pluginHooks2.default.getSingleton().add('afterUpdateSettings', htPersistentState.init); +(0, _plugins.registerPlugin)('ManualRowMove', ManualRowMove); -exports.default = HandsontablePersistentState; +exports.default = ManualRowMove; /***/ }), -/* 261 */ +/* 294 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62097,145 +62533,106 @@ exports.default = HandsontablePersistentState; exports.__esModule = true; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _pluginHooks = __webpack_require__(8); +var _arrayMapper = __webpack_require__(176); -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); +var _arrayMapper2 = _interopRequireDefault(_arrayMapper); -var _element = __webpack_require__(0); +var _array = __webpack_require__(2); -var _renderers = __webpack_require__(9); +var _object = __webpack_require__(1); + +var _number = __webpack_require__(6); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + /** - * @private - * @plugin Search + * @class RowsMapper + * @plugin ManualRowMove */ -function Search(instance) { - this.query = function (queryStr, callback, queryMethod) { - var rowCount = instance.countRows(); - var colCount = instance.countCols(); - var queryResult = []; - - if (!callback) { - callback = Search.global.getDefaultCallback(); - } - - if (!queryMethod) { - queryMethod = Search.global.getDefaultQueryMethod(); - } - - for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) { - for (var colIndex = 0; colIndex < colCount; colIndex++) { - var cellData = instance.getDataAtCell(rowIndex, colIndex); - var cellProperties = instance.getCellMeta(rowIndex, colIndex); - var cellCallback = cellProperties.search.callback || callback; - var cellQueryMethod = cellProperties.search.queryMethod || queryMethod; - var testResult = cellQueryMethod(queryStr, cellData); - - if (testResult) { - var singleResult = { - row: rowIndex, - col: colIndex, - data: cellData - }; - - queryResult.push(singleResult); - } - - if (cellCallback) { - cellCallback(instance, rowIndex, colIndex, cellData, testResult); - } - } - } - - return queryResult; - }; -}; - -Search.DEFAULT_CALLBACK = function (instance, row, col, data, testResult) { - instance.getCellMeta(row, col).isSearchResult = testResult; -}; +var RowsMapper = function () { + function RowsMapper(manualRowMove) { + _classCallCheck(this, RowsMapper); -Search.DEFAULT_QUERY_METHOD = function (query, value) { - if (typeof query == 'undefined' || query == null || !query.toLowerCase || query.length === 0) { - return false; - } - if (typeof value == 'undefined' || value == null) { - return false; + /** + * Instance of ManualRowMove plugin. + * + * @type {ManualRowMove} + */ + this.manualRowMove = manualRowMove; } - return value.toString().toLowerCase().indexOf(query.toLowerCase()) != -1; -}; + /** + * Reset current map array and create new one. + * + * @param {Number} [length] Custom generated map length. + */ -Search.DEFAULT_SEARCH_RESULT_CLASS = 'htSearchResult'; -Search.global = function () { + _createClass(RowsMapper, [{ + key: 'createMap', + value: function createMap(length) { + var _this = this; - var defaultCallback = Search.DEFAULT_CALLBACK; - var defaultQueryMethod = Search.DEFAULT_QUERY_METHOD; - var defaultSearchResultClass = Search.DEFAULT_SEARCH_RESULT_CLASS; + var originLength = length === void 0 ? this._arrayMap.length : length; - return { - getDefaultCallback: function getDefaultCallback() { - return defaultCallback; - }, - setDefaultCallback: function setDefaultCallback(newDefaultCallback) { - defaultCallback = newDefaultCallback; - }, - getDefaultQueryMethod: function getDefaultQueryMethod() { - return defaultQueryMethod; - }, - setDefaultQueryMethod: function setDefaultQueryMethod(newDefaultQueryMethod) { - defaultQueryMethod = newDefaultQueryMethod; - }, - getDefaultSearchResultClass: function getDefaultSearchResultClass() { - return defaultSearchResultClass; - }, - setDefaultSearchResultClass: function setDefaultSearchResultClass(newSearchResultClass) { - defaultSearchResultClass = newSearchResultClass; + this._arrayMap.length = 0; + + (0, _number.rangeEach)(originLength - 1, function (itemIndex) { + _this._arrayMap[itemIndex] = itemIndex; + }); } - }; -}(); -function SearchCellDecorator(instance, TD, row, col, prop, value, cellProperties) { - var searchResultClass = cellProperties.search !== null && _typeof(cellProperties.search) == 'object' && cellProperties.search.searchResultClass || Search.global.getDefaultSearchResultClass(); + /** + * Destroy class. + */ - if (cellProperties.isSearchResult) { - (0, _element.addClass)(TD, searchResultClass); - } else { - (0, _element.removeClass)(TD, searchResultClass); - } -}; + }, { + key: 'destroy', + value: function destroy() { + this._arrayMap = null; + } -var originalBaseRenderer = (0, _renderers.getRenderer)('base'); + /** + * Moving elements in rowsMapper. + * + * @param {Number} from Row index to move. + * @param {Number} to Target index. + */ -(0, _renderers.registerRenderer)('base', function (instance, TD, row, col, prop, value, cellProperties) { - originalBaseRenderer.apply(this, arguments); - SearchCellDecorator.apply(this, arguments); -}); + }, { + key: 'moveRow', + value: function moveRow(from, to) { + var indexToMove = this._arrayMap[from]; + this._arrayMap[from] = null; + this._arrayMap.splice(to, 0, indexToMove); + } -function init() { - var instance = this; + /** + * Clearing arrayMap from `null` entries. + */ - var pluginEnabled = !!instance.getSettings().search; + }, { + key: 'clearNull', + value: function clearNull() { + this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) { + return i !== null; + }); + } + }]); - if (pluginEnabled) { - instance.search = new Search(instance); - } else { - delete instance.search; - } -} + return RowsMapper; +}(); -_pluginHooks2.default.getSingleton().add('afterInit', init); -_pluginHooks2.default.getSingleton().add('afterUpdateSettings', init); +(0, _object.mixin)(RowsMapper, _arrayMapper2.default); -exports.default = Search; +exports.default = RowsMapper; /***/ }), -/* 262 */ +/* 295 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62247,17 +62644,11 @@ var _createClass = function () { function defineProperties(target, props) { for var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var _element = __webpack_require__(0); - -var _array = __webpack_require__(2); - -var _base = __webpack_require__(12); +var _base = __webpack_require__(178); var _base2 = _interopRequireDefault(_base); -var _plugins = __webpack_require__(5); - -var _feature = __webpack_require__(34); +var _element = __webpack_require__(0); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -62267,889 +62658,694 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } +var CSS_CLASSNAME = 'ht__manualRowMove--backlight'; + /** - * @private - * @plugin TouchScroll - * @class TouchScroll + * @class BacklightUI + * @util */ -var TouchScroll = function (_BasePlugin) { - _inherits(TouchScroll, _BasePlugin); - function TouchScroll(hotInstance) { - _classCallCheck(this, TouchScroll); +var BacklightUI = function (_BaseUI) { + _inherits(BacklightUI, _BaseUI); - /** - * Collection of scrollbars to update. - * - * @type {Array} - */ - var _this = _possibleConstructorReturn(this, (TouchScroll.__proto__ || Object.getPrototypeOf(TouchScroll)).call(this, hotInstance)); + function BacklightUI() { + _classCallCheck(this, BacklightUI); - _this.scrollbars = []; - /** - * Collection of overlays to update. - * - * @type {Array} - */ - _this.clones = []; - /** - * Flag which determines if collection of overlays should be refilled on every table render. - * - * @type {Boolean} - * @default false - */ - _this.lockedCollection = false; - /** - * Flag which determines if walkontable should freeze overlays while scrolling. - * - * @type {Boolean} - * @default false - */ - _this.freezeOverlays = false; - return _this; + return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments)); } - /** - * Check if plugin is enabled. - * - * @returns {Boolean} - */ - - - _createClass(TouchScroll, [{ - key: 'isEnabled', - value: function isEnabled() { - return (0, _feature.isTouchSupported)(); - } + _createClass(BacklightUI, [{ + key: 'build', /** - * Enable the plugin. + * Custom className on build process. */ + value: function build() { + _get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this); - }, { - key: 'enablePlugin', - value: function enablePlugin() { - var _this2 = this; + (0, _element.addClass)(this._element, CSS_CLASSNAME); + } + }]); - if (this.enabled) { - return; - } + return BacklightUI; +}(_base2.default); - this.addHook('afterRender', function () { - return _this2.onAfterRender(); - }); - this.registerEvents(); +exports.default = BacklightUI; - _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'enablePlugin', this).call(this); - } +/***/ }), +/* 296 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Updates the plugin to use the latest options you have specified. - */ +"use strict"; - }, { - key: 'updatePlugin', - value: function updatePlugin() { - this.lockedCollection = false; - _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'updatePlugin', this).call(this); - } +exports.__esModule = true; - /** - * Disable plugin for this Handsontable instance. - */ +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - }, { - key: 'disablePlugin', - value: function disablePlugin() { - _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'disablePlugin', this).call(this); - } +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - /** - * Register all necessary events. - * - * @private - */ +var _base = __webpack_require__(178); - }, { - key: 'registerEvents', - value: function registerEvents() { - var _this3 = this; +var _base2 = _interopRequireDefault(_base); - this.addHook('beforeTouchScroll', function () { - return _this3.onBeforeTouchScroll(); - }); - this.addHook('afterMomentumScroll', function () { - return _this3.onAfterMomentumScroll(); - }); - } +var _element = __webpack_require__(0); - /** - * After render listener. - * - * @private - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - }, { - key: 'onAfterRender', - value: function onAfterRender() { - if (this.lockedCollection) { - return; - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var _hot$view$wt$wtOverla = this.hot.view.wt.wtOverlays, - topOverlay = _hot$view$wt$wtOverla.topOverlay, - bottomOverlay = _hot$view$wt$wtOverla.bottomOverlay, - leftOverlay = _hot$view$wt$wtOverla.leftOverlay, - topLeftCornerOverlay = _hot$view$wt$wtOverla.topLeftCornerOverlay, - bottomLeftCornerOverlay = _hot$view$wt$wtOverla.bottomLeftCornerOverlay; +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - this.lockedCollection = true; - this.scrollbars.length = 0; - this.scrollbars.push(topOverlay); +var CSS_CLASSNAME = 'ht__manualRowMove--guideline'; - if (bottomOverlay.clone) { - this.scrollbars.push(bottomOverlay); - } - this.scrollbars.push(leftOverlay); +/** + * @class GuidelineUI + * @util + */ - if (topLeftCornerOverlay) { - this.scrollbars.push(topLeftCornerOverlay); - } - if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) { - this.scrollbars.push(bottomLeftCornerOverlay); - } +var GuidelineUI = function (_BaseUI) { + _inherits(GuidelineUI, _BaseUI); - this.clones.length = 0; + function GuidelineUI() { + _classCallCheck(this, GuidelineUI); - if (topOverlay.needFullRender) { - this.clones.push(topOverlay.clone.wtTable.holder.parentNode); - } - if (bottomOverlay.needFullRender) { - this.clones.push(bottomOverlay.clone.wtTable.holder.parentNode); - } - if (leftOverlay.needFullRender) { - this.clones.push(leftOverlay.clone.wtTable.holder.parentNode); - } - if (topLeftCornerOverlay) { - this.clones.push(topLeftCornerOverlay.clone.wtTable.holder.parentNode); - } - if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) { - this.clones.push(bottomLeftCornerOverlay.clone.wtTable.holder.parentNode); - } - } + return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments)); + } + + _createClass(GuidelineUI, [{ + key: 'build', /** - * Touch scroll listener. - * - * @private + * Custom className on build process. */ + value: function build() { + _get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this); - }, { - key: 'onBeforeTouchScroll', - value: function onBeforeTouchScroll() { - this.freezeOverlays = true; - - (0, _array.arrayEach)(this.clones, function (clone) { - (0, _element.addClass)(clone, 'hide-tween'); - }); + (0, _element.addClass)(this._element, CSS_CLASSNAME); } + }]); - /** - * After momentum scroll listener. - * - * @private - */ + return GuidelineUI; +}(_base2.default); - }, { - key: 'onAfterMomentumScroll', - value: function onAfterMomentumScroll() { - var _this4 = this; +exports.default = GuidelineUI; - this.freezeOverlays = false; +/***/ }), +/* 297 */ +/***/ (function(module, exports) { - (0, _array.arrayEach)(this.clones, function (clone) { - (0, _element.removeClass)(clone, 'hide-tween'); - (0, _element.addClass)(clone, 'show-tween'); - }); +// removed by extract-text-webpack-plugin - setTimeout(function () { - (0, _array.arrayEach)(_this4.clones, function (clone) { - (0, _element.removeClass)(clone, 'show-tween'); - }); - }, 400); +/***/ }), +/* 298 */ +/***/ (function(module, exports, __webpack_require__) { - (0, _array.arrayEach)(this.scrollbars, function (scrollbar) { - scrollbar.refresh(); - scrollbar.resetFixedPosition(); - }); +"use strict"; - this.hot.view.wt.wtOverlays.syncScrollWithMaster(); - } - }]); - return TouchScroll; -}(_base2.default); +exports.__esModule = true; -(0, _plugins.registerPlugin)('touchScroll', TouchScroll); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -exports.default = TouchScroll; +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -/***/ }), -/* 263 */ -/***/ (function(module, exports, __webpack_require__) { +var _base = __webpack_require__(13); + +var _base2 = _interopRequireDefault(_base); -"use strict"; +var _element = __webpack_require__(0); +var _eventManager = __webpack_require__(4); -var _pluginHooks = __webpack_require__(8); +var _eventManager2 = _interopRequireDefault(_eventManager); -var _pluginHooks2 = _interopRequireDefault(_pluginHooks); +var _event = __webpack_require__(8); var _array = __webpack_require__(2); var _number = __webpack_require__(6); -var _object = __webpack_require__(1); +var _plugins = __webpack_require__(5); -var _event = __webpack_require__(7); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _src = __webpack_require__(11); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js /** * @description - * Handsontable UndoRedo plugin. It allows to undo and redo certain actions done in the table. - * Please note, that not all actions are currently undo-able. + * ManualRowResize Plugin. * - * @example - * ```js - * ... - * undo: true - * ... - * ``` - * @class UndoRedo - * @plugin UndoRedo - */ -/** - * Handsontable UndoRedo class + * Has 2 UI components: + * - handle - the draggable element that sets the desired height of the row. + * - guide - the helper guide that shows the desired height as a horizontal guide. + * + * @plugin ManualRowResize */ -function UndoRedo(instance) { - var plugin = this; - this.instance = instance; - this.doneActions = []; - this.undoneActions = []; - this.ignoreNewActions = false; - - instance.addHook('afterChange', function (changes, source) { - if (changes && source !== 'UndoRedo.undo' && source !== 'UndoRedo.redo') { - plugin.done(new UndoRedo.ChangeAction(changes)); - } - }); - - instance.addHook('afterCreateRow', function (index, amount, source) { - if (source === 'UndoRedo.undo' || source === 'UndoRedo.undo' || source === 'auto') { - return; - } - - var action = new UndoRedo.CreateRowAction(index, amount); - plugin.done(action); - }); - - instance.addHook('beforeRemoveRow', function (index, amount, logicRows, source) { - if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') { - return; - } +var ManualRowResize = function (_BasePlugin) { + _inherits(ManualRowResize, _BasePlugin); - var originalData = plugin.instance.getSourceDataArray(); + function ManualRowResize(hotInstance) { + _classCallCheck(this, ManualRowResize); - index = (originalData.length + index) % originalData.length; + var _this = _possibleConstructorReturn(this, (ManualRowResize.__proto__ || Object.getPrototypeOf(ManualRowResize)).call(this, hotInstance)); - var removedData = (0, _object.deepClone)(originalData.slice(index, index + amount)); + _this.currentTH = null; + _this.currentRow = null; + _this.selectedRows = []; + _this.currentHeight = null; + _this.newSize = null; + _this.startY = null; + _this.startHeight = null; + _this.startOffset = null; + _this.handle = document.createElement('DIV'); + _this.guide = document.createElement('DIV'); + _this.eventManager = new _eventManager2.default(_this); + _this.pressed = null; + _this.dblclick = 0; + _this.autoresizeTimeout = null; + _this.manualRowHeights = []; - plugin.done(new UndoRedo.RemoveRowAction(index, removedData)); - }); + (0, _element.addClass)(_this.handle, 'manualRowResizer'); + (0, _element.addClass)(_this.guide, 'manualRowResizerGuide'); + return _this; + } - instance.addHook('afterCreateCol', function (index, amount, source) { - if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') { - return; - } + /** + * Check if the plugin is enabled in the handsontable settings. + * + * @returns {Boolean} + */ - plugin.done(new UndoRedo.CreateColumnAction(index, amount)); - }); - instance.addHook('beforeRemoveCol', function (index, amount, logicColumns, source) { - if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') { - return; + _createClass(ManualRowResize, [{ + key: 'isEnabled', + value: function isEnabled() { + return this.hot.getSettings().manualRowResize; } - var originalData = plugin.instance.getSourceDataArray(); + /** + * Enable plugin for this Handsontable instance. + */ - index = (plugin.instance.countCols() + index) % plugin.instance.countCols(); + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; - var removedData = []; - var headers = []; - var indexes = []; + if (this.enabled) { + return; + } - (0, _number.rangeEach)(originalData.length - 1, function (i) { - var column = []; - var origRow = originalData[i]; + this.manualRowHeights = []; - (0, _number.rangeEach)(index, index + (amount - 1), function (j) { - column.push(origRow[instance.runHooks('modifyCol', j)]); - }); - removedData.push(column); - }); + var initialRowHeights = this.hot.getSettings().manualRowResize; + var loadedManualRowHeights = this.loadManualRowHeights(); - (0, _number.rangeEach)(amount - 1, function (i) { - indexes.push(instance.runHooks('modifyCol', index + i)); - }); + if (typeof loadedManualRowHeights != 'undefined') { + this.manualRowHeights = loadedManualRowHeights; + } else if (Array.isArray(initialRowHeights)) { + this.manualRowHeights = initialRowHeights; + } else { + this.manualRowHeights = []; + } - if (Array.isArray(instance.getSettings().colHeaders)) { - (0, _number.rangeEach)(amount - 1, function (i) { - headers.push(instance.getSettings().colHeaders[instance.runHooks('modifyCol', index + i)] || null); + this.addHook('modifyRowHeight', function (height, row) { + return _this2.onModifyRowHeight(height, row); }); - } - var manualColumnMovePlugin = plugin.instance.getPlugin('manualColumnMove'); + // Handsontable.hooks.register('beforeRowResize'); + // Handsontable.hooks.register('afterRowResize'); - var columnsMap = manualColumnMovePlugin.isEnabled() ? manualColumnMovePlugin.columnsMapper.__arrayMap : []; - var action = new UndoRedo.RemoveColumnAction(index, indexes, removedData, headers, columnsMap); + this.bindEvents(); - plugin.done(action); - }); + _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'enablePlugin', this).call(this); + } - instance.addHook('beforeCellAlignment', function (stateBefore, range, type, alignment) { - var action = new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment); - plugin.done(action); - }); + /** + * Updates the plugin to use the latest options you have specified. + */ - instance.addHook('beforeFilter', function (conditionsStack) { - plugin.done(new UndoRedo.FiltersAction(conditionsStack)); - }); + }, { + key: 'updatePlugin', + value: function updatePlugin() { + var initialRowHeights = this.hot.getSettings().manualRowResize; - instance.addHook('beforeRowMove', function (movedRows, target) { - if (movedRows === false) { - return; + if (Array.isArray(initialRowHeights)) { + this.manualRowHeights = initialRowHeights; + } else if (!initialRowHeights) { + this.manualRowHeights = []; + } } - plugin.done(new UndoRedo.RowMoveAction(movedRows, target)); - }); -}; - -UndoRedo.prototype.done = function (action) { - if (!this.ignoreNewActions) { - this.doneActions.push(action); - this.undoneActions.length = 0; - } -}; + /** + * Disable plugin for this Handsontable instance. + */ -/** - * Undo last edit. - * - * @function undo - * @memberof UndoRedo# - */ -UndoRedo.prototype.undo = function () { - if (this.isUndoAvailable()) { - var action = this.doneActions.pop(); - var actionClone = (0, _object.deepClone)(action); - var instance = this.instance; + }, { + key: 'disablePlugin', + value: function disablePlugin() { + _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'disablePlugin', this).call(this); + } - var continueAction = instance.runHooks('beforeUndo', actionClone); + /** + * Save the current sizes using the persistentState plugin. + */ - if (continueAction === false) { - return; + }, { + key: 'saveManualRowHeights', + value: function saveManualRowHeights() { + this.hot.runHooks('persistentStateSave', 'manualRowHeights', this.manualRowHeights); } - this.ignoreNewActions = true; - var that = this; - action.undo(this.instance, function () { - that.ignoreNewActions = false; - that.undoneActions.push(action); - }); - - instance.runHooks('afterUndo', actionClone); - } -}; + /** + * Load the previously saved sizes using the persistentState plugin. + * + * @returns {Array} + */ -/** - * Redo edit (used to reverse an undo). - * - * @function redo - * @memberof UndoRedo# - */ -UndoRedo.prototype.redo = function () { - if (this.isRedoAvailable()) { - var action = this.undoneActions.pop(); - var actionClone = (0, _object.deepClone)(action); - var instance = this.instance; + }, { + key: 'loadManualRowHeights', + value: function loadManualRowHeights() { + var storedState = {}; - var continueAction = instance.runHooks('beforeRedo', actionClone); + this.hot.runHooks('persistentStateLoad', 'manualRowHeights', storedState); - if (continueAction === false) { - return; + return storedState.value; } - this.ignoreNewActions = true; - var that = this; - action.redo(this.instance, function () { - that.ignoreNewActions = false; - that.doneActions.push(action); - }); - - instance.runHooks('afterRedo', actionClone); - } -}; - -/** - * Check if undo action is available. - * - * @function isUndoAvailable - * @memberof UndoRedo# - * @return {Boolean} Return `true` if undo can be performed, `false` otherwise - */ -UndoRedo.prototype.isUndoAvailable = function () { - return this.doneActions.length > 0; -}; - -/** - * Check if redo action is available. - * - * @function isRedoAvailable - * @memberof UndoRedo# - * @return {Boolean} Return `true` if redo can be performed, `false` otherwise. - */ -UndoRedo.prototype.isRedoAvailable = function () { - return this.undoneActions.length > 0; -}; + /** + * Set the resize handle position. + * + * @param {HTMLCellElement} TH TH HTML element. + */ -/** - * Clears undo history. - * - * @function clear - * @memberof UndoRedo# - */ -UndoRedo.prototype.clear = function () { - this.doneActions.length = 0; - this.undoneActions.length = 0; -}; + }, { + key: 'setupHandlePosition', + value: function setupHandlePosition(TH) { + var _this3 = this; -UndoRedo.Action = function () {}; -UndoRedo.Action.prototype.undo = function () {}; -UndoRedo.Action.prototype.redo = function () {}; + this.currentTH = TH; + var row = this.hot.view.wt.wtTable.getCoords(TH).row; // getCoords returns CellCoords + var headerWidth = (0, _element.outerWidth)(this.currentTH); -/** - * Change action. - */ -UndoRedo.ChangeAction = function (changes) { - this.changes = changes; - this.actionType = 'change'; -}; -(0, _object.inherit)(UndoRedo.ChangeAction, UndoRedo.Action); + if (row >= 0) { + // if not col header + var box = this.currentTH.getBoundingClientRect(); -UndoRedo.ChangeAction.prototype.undo = function (instance, undoneCallback) { - var data = (0, _object.deepClone)(this.changes), - emptyRowsAtTheEnd = instance.countEmptyRows(true), - emptyColsAtTheEnd = instance.countEmptyCols(true); + this.currentRow = row; + this.selectedRows = []; - for (var i = 0, len = data.length; i < len; i++) { - data[i].splice(3, 1); - } + if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.rows) { + var _hot$getSelectedRange = this.hot.getSelectedRange(), + from = _hot$getSelectedRange.from, + to = _hot$getSelectedRange.to; - instance.addHookOnce('afterChange', undoneCallback); + var start = from.row; + var end = to.row; - instance.setDataAtRowProp(data, null, null, 'UndoRedo.undo'); + if (start >= end) { + start = to.row; + end = from.row; + } - for (var _i = 0, _len = data.length; _i < _len; _i++) { - if (instance.getSettings().minSpareRows && data[_i][0] + 1 + instance.getSettings().minSpareRows === instance.countRows() && emptyRowsAtTheEnd == instance.getSettings().minSpareRows) { + if (this.currentRow >= start && this.currentRow <= end) { + (0, _number.rangeEach)(start, end, function (i) { + return _this3.selectedRows.push(i); + }); + } else { + this.selectedRows.push(this.currentRow); + } + } else { + this.selectedRows.push(this.currentRow); + } - instance.alter('remove_row', parseInt(data[_i][0] + 1, 10), instance.getSettings().minSpareRows); - instance.undoRedo.doneActions.pop(); + this.startOffset = box.top - 6; + this.startHeight = parseInt(box.height, 10); + this.handle.style.left = box.left + 'px'; + this.handle.style.top = this.startOffset + this.startHeight + 'px'; + this.handle.style.width = headerWidth + 'px'; + this.hot.rootElement.appendChild(this.handle); + } } - if (instance.getSettings().minSpareCols && data[_i][1] + 1 + instance.getSettings().minSpareCols === instance.countCols() && emptyColsAtTheEnd == instance.getSettings().minSpareCols) { + /** + * Refresh the resize handle position. + */ - instance.alter('remove_col', parseInt(data[_i][1] + 1, 10), instance.getSettings().minSpareCols); - instance.undoRedo.doneActions.pop(); + }, { + key: 'refreshHandlePosition', + value: function refreshHandlePosition() { + this.handle.style.top = this.startOffset + this.currentHeight + 'px'; } - } -}; -UndoRedo.ChangeAction.prototype.redo = function (instance, onFinishCallback) { - var data = (0, _object.deepClone)(this.changes); - - for (var i = 0, len = data.length; i < len; i++) { - data[i].splice(2, 1); - } - instance.addHookOnce('afterChange', onFinishCallback); - instance.setDataAtRowProp(data, null, null, 'UndoRedo.redo'); -}; - -/** - * Create row action. - */ -UndoRedo.CreateRowAction = function (index, amount) { - this.index = index; - this.amount = amount; - this.actionType = 'insert_row'; -}; -(0, _object.inherit)(UndoRedo.CreateRowAction, UndoRedo.Action); + /** + * Set the resize guide position. + */ -UndoRedo.CreateRowAction.prototype.undo = function (instance, undoneCallback) { - var rowCount = instance.countRows(), - minSpareRows = instance.getSettings().minSpareRows; + }, { + key: 'setupGuidePosition', + value: function setupGuidePosition() { + var handleWidth = parseInt((0, _element.outerWidth)(this.handle), 10); + var handleRightPosition = parseInt(this.handle.style.left, 10) + handleWidth; + var maximumVisibleElementWidth = parseInt(this.hot.view.maximumVisibleElementWidth(0), 10); + (0, _element.addClass)(this.handle, 'active'); + (0, _element.addClass)(this.guide, 'active'); - if (this.index >= rowCount && this.index - minSpareRows < rowCount) { - this.index -= minSpareRows; // work around the situation where the needed row was removed due to an 'undo' of a made change - } + this.guide.style.top = this.handle.style.top; + this.guide.style.left = handleRightPosition + 'px'; + this.guide.style.width = maximumVisibleElementWidth - handleWidth + 'px'; + this.hot.rootElement.appendChild(this.guide); + } - instance.addHookOnce('afterRemoveRow', undoneCallback); - instance.alter('remove_row', this.index, this.amount, 'UndoRedo.undo'); -}; -UndoRedo.CreateRowAction.prototype.redo = function (instance, redoneCallback) { - instance.addHookOnce('afterCreateRow', redoneCallback); - instance.alter('insert_row', this.index, this.amount, 'UndoRedo.redo'); -}; + /** + * Refresh the resize guide position. + */ -/** - * Remove row action. - */ -UndoRedo.RemoveRowAction = function (index, data) { - this.index = index; - this.data = data; - this.actionType = 'remove_row'; -}; -(0, _object.inherit)(UndoRedo.RemoveRowAction, UndoRedo.Action); + }, { + key: 'refreshGuidePosition', + value: function refreshGuidePosition() { + this.guide.style.top = this.handle.style.top; + } -UndoRedo.RemoveRowAction.prototype.undo = function (instance, undoneCallback) { - instance.alter('insert_row', this.index, this.data.length, 'UndoRedo.undo'); - instance.addHookOnce('afterRender', undoneCallback); - instance.populateFromArray(this.index, 0, this.data, void 0, void 0, 'UndoRedo.undo'); -}; -UndoRedo.RemoveRowAction.prototype.redo = function (instance, redoneCallback) { - instance.addHookOnce('afterRemoveRow', redoneCallback); - instance.alter('remove_row', this.index, this.data.length, 'UndoRedo.redo'); -}; + /** + * Hide both the resize handle and resize guide. + */ -/** - * Create column action. - */ -UndoRedo.CreateColumnAction = function (index, amount) { - this.index = index; - this.amount = amount; - this.actionType = 'insert_col'; -}; -(0, _object.inherit)(UndoRedo.CreateColumnAction, UndoRedo.Action); + }, { + key: 'hideHandleAndGuide', + value: function hideHandleAndGuide() { + (0, _element.removeClass)(this.handle, 'active'); + (0, _element.removeClass)(this.guide, 'active'); + } -UndoRedo.CreateColumnAction.prototype.undo = function (instance, undoneCallback) { - instance.addHookOnce('afterRemoveCol', undoneCallback); - instance.alter('remove_col', this.index, this.amount, 'UndoRedo.undo'); -}; -UndoRedo.CreateColumnAction.prototype.redo = function (instance, redoneCallback) { - instance.addHookOnce('afterCreateCol', redoneCallback); - instance.alter('insert_col', this.index, this.amount, 'UndoRedo.redo'); -}; + /** + * Check if provided element is considered as a row header. + * + * @param {HTMLElement} element HTML element. + * @returns {Boolean} + */ -/** - * Remove column action. - */ -UndoRedo.RemoveColumnAction = function (index, indexes, data, headers, columnPositions) { - this.index = index; - this.indexes = indexes; - this.data = data; - this.amount = this.data[0].length; - this.headers = headers; - this.columnPositions = columnPositions.slice(0); - this.actionType = 'remove_col'; -}; -(0, _object.inherit)(UndoRedo.RemoveColumnAction, UndoRedo.Action); + }, { + key: 'checkIfRowHeader', + value: function checkIfRowHeader(element) { + if (element != this.hot.rootElement) { + var parent = element.parentNode; -UndoRedo.RemoveColumnAction.prototype.undo = function (instance, undoneCallback) { - var _this = this; + if (parent.tagName === 'TBODY') { + return true; + } - var row = void 0; - var ascendingIndexes = this.indexes.slice(0).sort(); - var sortByIndexes = function sortByIndexes(elem, j, arr) { - return arr[_this.indexes.indexOf(ascendingIndexes[j])]; - }; + return this.checkIfRowHeader(parent); + } - var sortedData = []; - (0, _number.rangeEach)(this.data.length - 1, function (i) { - sortedData[i] = (0, _array.arrayMap)(_this.data[i], sortByIndexes); - }); + return false; + } - var sortedHeaders = []; - sortedHeaders = (0, _array.arrayMap)(this.headers, sortByIndexes); + /** + * Get the TH element from the provided element. + * + * @param {HTMLElement} element HTML element. + * @returns {HTMLElement} + */ - var changes = []; + }, { + key: 'getTHFromTargetElement', + value: function getTHFromTargetElement(element) { + if (element.tagName != 'TABLE') { + if (element.tagName == 'TH') { + return element; + } + return this.getTHFromTargetElement(element.parentNode); + } - // TODO: Temporary hook for undo/redo mess - instance.runHooks('beforeCreateCol', this.indexes[0], this.indexes[this.indexes.length - 1], 'UndoRedo.undo'); + return null; + } - (0, _number.rangeEach)(this.data.length - 1, function (i) { - row = instance.getSourceDataAtRow(i); + /** + * 'mouseover' event callback - set the handle position. + * + * @private + * @param {MouseEvent} event + */ - (0, _number.rangeEach)(ascendingIndexes.length - 1, function (j) { - row.splice(ascendingIndexes[j], 0, sortedData[i][j]); - changes.push([i, ascendingIndexes[j], null, sortedData[i][j]]); - }); - }); + }, { + key: 'onMouseOver', + value: function onMouseOver(event) { + if (this.checkIfRowHeader(event.target)) { + var th = this.getTHFromTargetElement(event.target); - // TODO: Temporary hook for undo/redo mess - if (instance.getPlugin('formulas')) { - instance.getPlugin('formulas').onAfterSetDataAtCell(changes); - } + if (th) { + if (!this.pressed) { + this.setupHandlePosition(th); + } + } + } + } - if (typeof this.headers !== 'undefined') { - (0, _number.rangeEach)(sortedHeaders.length - 1, function (j) { - instance.getSettings().colHeaders.splice(ascendingIndexes[j], 0, sortedHeaders[j]); - }); - } + /** + * Auto-size row after doubleclick - callback. + * + * @private + */ - if (instance.getPlugin('manualColumnMove')) { - instance.getPlugin('manualColumnMove').columnsMapper.__arrayMap = this.columnPositions; - } + }, { + key: 'afterMouseDownTimeout', + value: function afterMouseDownTimeout() { + var _this4 = this; - instance.addHookOnce('afterRender', undoneCallback); + var render = function render() { + _this4.hot.forceFullRender = true; + _this4.hot.view.render(); // updates all + _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); + }; + var resize = function resize(selectedRow, forceRender) { + var hookNewSize = _this4.hot.runHooks('beforeRowResize', selectedRow, _this4.newSize, true); - // TODO: Temporary hook for undo/redo mess - instance.runHooks('afterCreateCol', this.indexes[0], this.indexes[this.indexes.length - 1], 'UndoRedo.undo'); + if (hookNewSize !== void 0) { + _this4.newSize = hookNewSize; + } - if (instance.getPlugin('formulas')) { - instance.getPlugin('formulas').recalculateFull(); - } + _this4.setManualSize(selectedRow, _this4.newSize); // double click sets auto row size - instance.render(); -}; + if (forceRender) { + render(); + } -UndoRedo.RemoveColumnAction.prototype.redo = function (instance, redoneCallback) { - instance.addHookOnce('afterRemoveCol', redoneCallback); - instance.alter('remove_col', this.index, this.amount, 'UndoRedo.redo'); -}; + _this4.hot.runHooks('afterRowResize', selectedRow, _this4.newSize, true); + }; -/** - * Cell alignment action. - */ -UndoRedo.CellAlignmentAction = function (stateBefore, range, type, alignment) { - this.stateBefore = stateBefore; - this.range = range; - this.type = type; - this.alignment = alignment; -}; -UndoRedo.CellAlignmentAction.prototype.undo = function (instance, undoneCallback) { - if (!instance.getPlugin('contextMenu').isEnabled()) { - return; - } - for (var row = this.range.from.row; row <= this.range.to.row; row++) { - for (var col = this.range.from.col; col <= this.range.to.col; col++) { - instance.setCellMeta(row, col, 'className', this.stateBefore[row][col] || ' htLeft'); + if (this.dblclick >= 2) { + var selectedRowsLength = this.selectedRows.length; + + if (selectedRowsLength > 1) { + (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { + resize(selectedRow); + }); + render(); + } else { + (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { + resize(selectedRow, true); + }); + } + } + this.dblclick = 0; + this.autoresizeTimeout = null; } - } - instance.addHookOnce('afterRender', undoneCallback); - instance.render(); -}; -UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback) { - if (!instance.getPlugin('contextMenu').isEnabled()) { - return; - } - instance.selectCell(this.range.from.row, this.range.from.col, this.range.to.row, this.range.to.col); - instance.getPlugin('contextMenu').executeCommand('alignment:' + this.alignment.replace('ht', '').toLowerCase()); + /** + * 'mousedown' event callback. + * + * @private + * @param {MouseEvent} event + */ - instance.addHookOnce('afterRender', undoneCallback); - instance.render(); -}; + }, { + key: 'onMouseDown', + value: function onMouseDown(event) { + var _this5 = this; -/** - * Filters action. - */ -UndoRedo.FiltersAction = function (conditionsStack) { - this.conditionsStack = conditionsStack; - this.actionType = 'filter'; -}; -(0, _object.inherit)(UndoRedo.FiltersAction, UndoRedo.Action); + if ((0, _element.hasClass)(event.target, 'manualRowResizer')) { + this.setupGuidePosition(); + this.pressed = this.hot; -UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) { - var filters = instance.getPlugin('filters'); + if (this.autoresizeTimeout == null) { + this.autoresizeTimeout = setTimeout(function () { + return _this5.afterMouseDownTimeout(); + }, 500); - instance.addHookOnce('afterRender', undoneCallback); + this.hot._registerTimeout(this.autoresizeTimeout); + } + this.dblclick++; - filters.conditionCollection.importAllConditions(this.conditionsStack.slice(0, this.conditionsStack.length - 1)); - filters.filter(); -}; -UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) { - var filters = instance.getPlugin('filters'); + this.startY = (0, _event.pageY)(event); + this.newSize = this.startHeight; + } + } - instance.addHookOnce('afterRender', redoneCallback); + /** + * 'mousemove' event callback - refresh the handle and guide positions, cache the new row height. + * + * @private + * @param {MouseEvent} event + */ - filters.conditionCollection.importAllConditions(this.conditionsStack); - filters.filter(); -}; + }, { + key: 'onMouseMove', + value: function onMouseMove(event) { + var _this6 = this; -/** - * ManualRowMove action. - * @TODO: removeRow undo should works on logical index - */ -UndoRedo.RowMoveAction = function (movedRows, target) { - this.rows = movedRows.slice(); - this.target = target; -}; -(0, _object.inherit)(UndoRedo.RowMoveAction, UndoRedo.Action); + if (this.pressed) { + this.currentHeight = this.startHeight + ((0, _event.pageY)(event) - this.startY); -UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) { - var manualRowMove = instance.getPlugin('manualRowMove'); + (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { + _this6.newSize = _this6.setManualSize(selectedRow, _this6.currentHeight); + }); - instance.addHookOnce('afterRender', undoneCallback); - var mod = this.rows[0] < this.target ? -1 * this.rows.length : 0; - var newTarget = this.rows[0] > this.target ? this.rows[0] + this.rows.length : this.rows[0]; - var newRows = []; - var rowsLen = this.rows.length + mod; + this.refreshHandlePosition(); + this.refreshGuidePosition(); + } + } - for (var i = mod; i < rowsLen; i++) { - newRows.push(this.target + i); - } - manualRowMove.moveRows(newRows.slice(), newTarget); - instance.render(); + /** + * 'mouseup' event callback - apply the row resizing. + * + * @private + * @param {MouseEvent} event + */ - instance.selection.setRangeStartOnly(new _src.CellCoords(this.rows[0], 0)); - instance.selection.setRangeEnd(new _src.CellCoords(this.rows[this.rows.length - 1], instance.countCols() - 1)); -}; -UndoRedo.RowMoveAction.prototype.redo = function (instance, redoneCallback) { - var manualRowMove = instance.getPlugin('manualRowMove'); + }, { + key: 'onMouseUp', + value: function onMouseUp(event) { + var _this7 = this; - instance.addHookOnce('afterRender', redoneCallback); - manualRowMove.moveRows(this.rows.slice(), this.target); - instance.render(); - var startSelection = this.rows[0] < this.target ? this.target - this.rows.length : this.target; - instance.selection.setRangeStartOnly(new _src.CellCoords(startSelection, 0)); - instance.selection.setRangeEnd(new _src.CellCoords(startSelection + this.rows.length - 1, instance.countCols() - 1)); -}; + var render = function render() { + _this7.hot.forceFullRender = true; + _this7.hot.view.render(); // updates all + _this7.hot.view.wt.wtOverlays.adjustElementsSize(true); + }; + var runHooks = function runHooks(selectedRow, forceRender) { + _this7.hot.runHooks('beforeRowResize', selectedRow, _this7.newSize); -function init() { - var instance = this; - var pluginEnabled = typeof instance.getSettings().undo == 'undefined' || instance.getSettings().undo; + if (forceRender) { + render(); + } - if (pluginEnabled) { - if (!instance.undoRedo) { - /** - * Instance of Handsontable.UndoRedo Plugin {@link Handsontable.UndoRedo} - * - * @alias undoRedo - * @memberof! Handsontable.Core# - * @type {UndoRedo} - */ - instance.undoRedo = new UndoRedo(instance); + _this7.saveManualRowHeights(); - exposeUndoRedoMethods(instance); + _this7.hot.runHooks('afterRowResize', selectedRow, _this7.newSize); + }; + if (this.pressed) { + this.hideHandleAndGuide(); + this.pressed = false; - instance.addHook('beforeKeyDown', onBeforeKeyDown); - instance.addHook('afterChange', onAfterChange); - } - } else if (instance.undoRedo) { - delete instance.undoRedo; + if (this.newSize != this.startHeight) { + var selectedRowsLength = this.selectedRows.length; - removeExposedUndoRedoMethods(instance); + if (selectedRowsLength > 1) { + (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { + runHooks(selectedRow); + }); + render(); + } else { + (0, _array.arrayEach)(this.selectedRows, function (selectedRow) { + runHooks(selectedRow, true); + }); + } + } - instance.removeHook('beforeKeyDown', onBeforeKeyDown); - instance.removeHook('afterChange', onAfterChange); - } -} + this.setupHandlePosition(this.currentTH); + } + } -function onBeforeKeyDown(event) { - var instance = this; + /** + * Bind the mouse events. + * + * @private + */ - var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; + }, { + key: 'bindEvents', + value: function bindEvents() { + var _this8 = this; - if (ctrlDown) { - if (event.keyCode === 89 || event.shiftKey && event.keyCode === 90) { - // CTRL + Y or CTRL + SHIFT + Z - instance.undoRedo.redo(); - (0, _event.stopImmediatePropagation)(event); - } else if (event.keyCode === 90) { - // CTRL + Z - instance.undoRedo.undo(); - (0, _event.stopImmediatePropagation)(event); + this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) { + return _this8.onMouseOver(e); + }); + this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) { + return _this8.onMouseDown(e); + }); + this.eventManager.addEventListener(window, 'mousemove', function (e) { + return _this8.onMouseMove(e); + }); + this.eventManager.addEventListener(window, 'mouseup', function (e) { + return _this8.onMouseUp(e); + }); } - } -} -function onAfterChange(changes, source) { - var instance = this; - if (source === 'loadData') { - return instance.undoRedo.clear(); - } -} + /** + * Cache the current row height. + * + * @param {Number} row Visual row index. + * @param {Number} height Row height. + * @returns {Number} + */ -function exposeUndoRedoMethods(instance) { - /** - * {@link UndoRedo#undo} - * @alias undo - * @memberof! Handsontable.Core# - */ - instance.undo = function () { - return instance.undoRedo.undo(); - }; + }, { + key: 'setManualSize', + value: function setManualSize(row, height) { + row = this.hot.runHooks('modifyRow', row); + this.manualRowHeights[row] = height; - /** - * {@link UndoRedo#redo} - * @alias redo - * @memberof! Handsontable.Core# - */ - instance.redo = function () { - return instance.undoRedo.redo(); - }; + return height; + } - /** - * {@link UndoRedo#isUndoAvailable} - * @alias isUndoAvailable - * @memberof! Handsontable.Core# - */ - instance.isUndoAvailable = function () { - return instance.undoRedo.isUndoAvailable(); - }; + /** + * Modify the provided row height, based on the plugin settings. + * + * @private + * @param {Number} height Row height. + * @param {Number} row Visual row index. + * @returns {Number} + */ - /** - * {@link UndoRedo#isRedoAvailable} - * @alias isRedoAvailable - * @memberof! Handsontable.Core# - */ - instance.isRedoAvailable = function () { - return instance.undoRedo.isRedoAvailable(); - }; + }, { + key: 'onModifyRowHeight', + value: function onModifyRowHeight(height, row) { + if (this.enabled) { + var autoRowSizePlugin = this.hot.getPlugin('autoRowSize'); + var autoRowHeightResult = autoRowSizePlugin ? autoRowSizePlugin.heights[row] : null; - /** - * {@link UndoRedo#clear} - * @alias clearUndo - * @memberof! Handsontable.Core# - */ - instance.clearUndo = function () { - return instance.undoRedo.clear(); - }; -} + row = this.hot.runHooks('modifyRow', row); -function removeExposedUndoRedoMethods(instance) { - delete instance.undo; - delete instance.redo; - delete instance.isUndoAvailable; - delete instance.isRedoAvailable; - delete instance.clearUndo; -} + var manualRowHeight = this.manualRowHeights[row]; -var hook = _pluginHooks2.default.getSingleton(); + if (manualRowHeight !== void 0 && (manualRowHeight === autoRowHeightResult || manualRowHeight > (height || 0))) { + return manualRowHeight; + } + } -hook.add('afterInit', init); -hook.add('afterUpdateSettings', init); + return height; + } + }]); -hook.register('beforeUndo'); -hook.register('afterUndo'); -hook.register('beforeRedo'); -hook.register('afterRedo'); + return ManualRowResize; +}(_base2.default); + +(0, _plugins.registerPlugin)('manualRowResize', ManualRowResize); + +exports.default = ManualRowResize; /***/ }), -/* 264 */ +/* 299 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63157,494 +63353,653 @@ hook.register('afterRedo'); exports.__esModule = true; -var _element = __webpack_require__(0); +var _pluginHooks = __webpack_require__(7); -function cellDecorator(instance, TD, row, col, prop, value, cellProperties) { - if (cellProperties.className) { - if (TD.className) { - TD.className = TD.className + ' ' + cellProperties.className; - } else { - TD.className = cellProperties.className; - } - } +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - if (cellProperties.readOnly) { - (0, _element.addClass)(TD, cellProperties.readOnlyCellClassName); - } +var _plugins = __webpack_require__(5); - if (cellProperties.valid === false && cellProperties.invalidCellClassName) { - (0, _element.addClass)(TD, cellProperties.invalidCellClassName); - } else { - (0, _element.removeClass)(TD, cellProperties.invalidCellClassName); - } +var _event = __webpack_require__(8); - if (cellProperties.wordWrap === false && cellProperties.noWordWrapClassName) { - (0, _element.addClass)(TD, cellProperties.noWordWrapClassName); - } +var _src = __webpack_require__(12); - if (!value && cellProperties.placeholder) { - (0, _element.addClass)(TD, cellProperties.placeholderCellClassName); - } -} /** - * Adds appropriate CSS class to table cell, based on cellProperties - */ -exports.default = cellDecorator; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -/***/ }), -/* 265 */ -/***/ (function(module, exports, __webpack_require__) { +function CellInfoCollection() { + var collection = []; -"use strict"; + collection.getInfo = function (row, col) { + for (var i = 0, ilen = this.length; i < ilen; i++) { + if (this[i].row <= row && this[i].row + this[i].rowspan - 1 >= row && this[i].col <= col && this[i].col + this[i].colspan - 1 >= col) { + return this[i]; + } + } + }; + collection.setInfo = function (info) { + for (var i = 0, ilen = this.length; i < ilen; i++) { + if (this[i].row === info.row && this[i].col === info.col) { + this[i] = info; + return; + } + } + this.push(info); + }; + + collection.removeInfo = function (row, col) { + for (var i = 0, ilen = this.length; i < ilen; i++) { + if (this[i].row === row && this[i].col === col) { + this.splice(i, 1); + break; + } + } + }; -exports.__esModule = true; + return collection; +} -var _element = __webpack_require__(0); +/** + * Plugin used to merge cells in Handsontable. + * + * @private + * @plugin MergeCells + * @class MergeCells + */ +function MergeCells(mergeCellsSetting) { + this.mergedCellInfoCollection = new CellInfoCollection(); -var _eventManager = __webpack_require__(4); + if (Array.isArray(mergeCellsSetting)) { + for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) { + this.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]); + } + } +} -var _eventManager2 = _interopRequireDefault(_eventManager); +/** + * @param cellRange (CellRange) + */ +MergeCells.prototype.canMergeRange = function (cellRange) { + // is more than one cell selected + return !cellRange.isSingle(); +}; -var _src = __webpack_require__(11); +MergeCells.prototype.mergeRange = function (cellRange) { + if (!this.canMergeRange(cellRange)) { + return; + } -var _index = __webpack_require__(9); + // normalize top left corner + var topLeft = cellRange.getTopLeftCorner(); + var bottomRight = cellRange.getBottomRightCorner(); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + var mergeParent = {}; + mergeParent.row = topLeft.row; + mergeParent.col = topLeft.col; + // TD has rowspan == 1 by default. rowspan == 2 means spread over 2 cells + mergeParent.rowspan = bottomRight.row - topLeft.row + 1; + mergeParent.colspan = bottomRight.col - topLeft.col + 1; + this.mergedCellInfoCollection.setInfo(mergeParent); +}; -var clonableWRAPPER = document.createElement('DIV'); -clonableWRAPPER.className = 'htAutocompleteWrapper'; +MergeCells.prototype.mergeOrUnmergeSelection = function (cellRange) { + var info = this.mergedCellInfoCollection.getInfo(cellRange.from.row, cellRange.from.col); + if (info) { + // unmerge + this.unmergeSelection(cellRange.from); + } else { + // merge + this.mergeSelection(cellRange); + } +}; -var clonableARROW = document.createElement('DIV'); -clonableARROW.className = 'htAutocompleteArrow'; -// workaround for https://github.com/handsontable/handsontable/issues/1946 -// this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips -clonableARROW.appendChild(document.createTextNode(String.fromCharCode(9660))); +MergeCells.prototype.mergeSelection = function (cellRange) { + this.mergeRange(cellRange); +}; -var wrapTdContentWithWrapper = function wrapTdContentWithWrapper(TD, WRAPPER) { - WRAPPER.innerHTML = TD.innerHTML; - (0, _element.empty)(TD); - TD.appendChild(WRAPPER); +MergeCells.prototype.unmergeSelection = function (cellRange) { + var info = this.mergedCellInfoCollection.getInfo(cellRange.row, cellRange.col); + this.mergedCellInfoCollection.removeInfo(info.row, info.col); }; -/** - * Autocomplete renderer - * - * @private - * @renderer AutocompleteRenderer - * @param {Object} instance Handsontable instance - * @param {Element} TD Table cell where to render - * @param {Number} row - * @param {Number} col - * @param {String|Number} prop Row object property name - * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) - * @param {Object} cellProperties Cell properites (shared by cell renderer and editor) - */ -function autocompleteRenderer(instance, TD, row, col, prop, value, cellProperties) { - var WRAPPER = clonableWRAPPER.cloneNode(true); // this is faster than createElement - var ARROW = clonableARROW.cloneNode(true); // this is faster than createElement +MergeCells.prototype.applySpanProperties = function (TD, row, col) { + var info = this.mergedCellInfoCollection.getInfo(row, col); - if (cellProperties.allowHtml) { - (0, _index.getRenderer)('html').apply(this, arguments); + if (info) { + if (info.row === row && info.col === col) { + TD.setAttribute('rowspan', info.rowspan); + TD.setAttribute('colspan', info.colspan); + } else { + TD.removeAttribute('rowspan'); + TD.removeAttribute('colspan'); + + TD.style.display = 'none'; + } } else { - (0, _index.getRenderer)('text').apply(this, arguments); + TD.removeAttribute('rowspan'); + TD.removeAttribute('colspan'); } +}; - TD.appendChild(ARROW); - (0, _element.addClass)(TD, 'htAutocomplete'); +MergeCells.prototype.modifyTransform = function (hook, currentSelectedRange, delta) { + var sameRowspan = function sameRowspan(merged, coords) { + if (coords.row >= merged.row && coords.row <= merged.row + merged.rowspan - 1) { + return true; + } + return false; + }, + sameColspan = function sameColspan(merged, coords) { + if (coords.col >= merged.col && coords.col <= merged.col + merged.colspan - 1) { + return true; + } + return false; + }, + getNextPosition = function getNextPosition(newDelta) { + return new _src.CellCoords(currentSelectedRange.to.row + newDelta.row, currentSelectedRange.to.col + newDelta.col); + }; - if (!TD.firstChild) { - // http://jsperf.com/empty-node-if-needed - // otherwise empty fields appear borderless in demo/renderers.html (IE) - TD.appendChild(document.createTextNode(String.fromCharCode(160))); // workaround for https://github.com/handsontable/handsontable/issues/1946 - // this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips - } + var newDelta = { + row: delta.row, + col: delta.col + }; - if (!instance.acArrowListener) { - var eventManager = new _eventManager2.default(instance); + if (hook == 'modifyTransformStart') { + /* eslint-disable block-scoped-var */ + var nextPosition; - // not very elegant but easy and fast - instance.acArrowListener = function (event) { - if ((0, _element.hasClass)(event.target, 'htAutocompleteArrow')) { - instance.view.wt.getSetting('onCellDblClick', null, new _src.CellCoords(row, col), TD); - } - }; + if (!this.lastDesiredCoords) { + this.lastDesiredCoords = new _src.CellCoords(null, null); + } + var currentPosition = new _src.CellCoords(currentSelectedRange.highlight.row, currentSelectedRange.highlight.col), - eventManager.addEventListener(instance.rootElement, 'mousedown', instance.acArrowListener); + // if current position's parent is a merged range, returns it + mergedParent = this.mergedCellInfoCollection.getInfo(currentPosition.row, currentPosition.col), + currentRangeContainsMerge; // if current range contains a merged range - // We need to unbind the listener after the table has been destroyed - instance.addHookOnce('afterDestroy', function () { - eventManager.destroy(); - }); - } -} + for (var i = 0, mergesLength = this.mergedCellInfoCollection.length; i < mergesLength; i++) { + var range = this.mergedCellInfoCollection[i]; + range = new _src.CellCoords(range.row + range.rowspan - 1, range.col + range.colspan - 1); + if (currentSelectedRange.includes(range)) { + currentRangeContainsMerge = true; + break; + } + } -exports.default = autocompleteRenderer; + if (mergedParent) { + // only merge selected + var mergeTopLeft = new _src.CellCoords(mergedParent.row, mergedParent.col); + var mergeBottomRight = new _src.CellCoords(mergedParent.row + mergedParent.rowspan - 1, mergedParent.col + mergedParent.colspan - 1); + var mergeRange = new _src.CellRange(mergeTopLeft, mergeTopLeft, mergeBottomRight); -/***/ }), -/* 266 */ -/***/ (function(module, exports, __webpack_require__) { + if (!mergeRange.includes(this.lastDesiredCoords)) { + this.lastDesiredCoords = new _src.CellCoords(null, null); // reset outdated version of lastDesiredCoords + } -"use strict"; + newDelta.row = this.lastDesiredCoords.row ? this.lastDesiredCoords.row - currentPosition.row : newDelta.row; + newDelta.col = this.lastDesiredCoords.col ? this.lastDesiredCoords.col - currentPosition.col : newDelta.col; + if (delta.row > 0) { + // moving down + newDelta.row = mergedParent.row + mergedParent.rowspan - 1 - currentPosition.row + delta.row; + } else if (delta.row < 0) { + // moving up + newDelta.row = currentPosition.row - mergedParent.row + delta.row; + } + if (delta.col > 0) { + // moving right + newDelta.col = mergedParent.col + mergedParent.colspan - 1 - currentPosition.col + delta.col; + } else if (delta.col < 0) { + // moving left + newDelta.col = currentPosition.col - mergedParent.col + delta.col; + } + } -exports.__esModule = true; + nextPosition = new _src.CellCoords(currentSelectedRange.highlight.row + newDelta.row, currentSelectedRange.highlight.col + newDelta.col); -var _element = __webpack_require__(0); + var nextParentIsMerged = this.mergedCellInfoCollection.getInfo(nextPosition.row, nextPosition.col); -var _string = __webpack_require__(27); + if (nextParentIsMerged) { + // skipping the invisible cells in the merge range + this.lastDesiredCoords = nextPosition; + newDelta = { + row: nextParentIsMerged.row - currentPosition.row, + col: nextParentIsMerged.col - currentPosition.col + }; + } + } else if (hook == 'modifyTransformEnd') { + for (var _i = 0, _mergesLength = this.mergedCellInfoCollection.length; _i < _mergesLength; _i++) { + var currentMerge = this.mergedCellInfoCollection[_i]; + var _mergeTopLeft = new _src.CellCoords(currentMerge.row, currentMerge.col); + var _mergeBottomRight = new _src.CellCoords(currentMerge.row + currentMerge.rowspan - 1, currentMerge.col + currentMerge.colspan - 1); + var mergedRange = new _src.CellRange(_mergeTopLeft, _mergeTopLeft, _mergeBottomRight); + var sharedBorders = currentSelectedRange.getBordersSharedWith(mergedRange); -var _eventManager = __webpack_require__(4); + if (mergedRange.isEqual(currentSelectedRange)) { + // only the merged range is selected + currentSelectedRange.setDirection('NW-SE'); + } else if (sharedBorders.length > 0) { + var mergeHighlighted = currentSelectedRange.highlight.isEqual(mergedRange.from); -var _eventManager2 = _interopRequireDefault(_eventManager); + if (sharedBorders.indexOf('top') > -1) { + // if range shares a border with the merged section, change range direction accordingly + if (currentSelectedRange.to.isSouthEastOf(mergedRange.from) && mergeHighlighted) { + currentSelectedRange.setDirection('NW-SE'); + } else if (currentSelectedRange.to.isSouthWestOf(mergedRange.from) && mergeHighlighted) { + currentSelectedRange.setDirection('NE-SW'); + } + } else if (sharedBorders.indexOf('bottom') > -1) { + if (currentSelectedRange.to.isNorthEastOf(mergedRange.from) && mergeHighlighted) { + currentSelectedRange.setDirection('SW-NE'); + } else if (currentSelectedRange.to.isNorthWestOf(mergedRange.from) && mergeHighlighted) { + currentSelectedRange.setDirection('SE-NW'); + } + } + } -var _unicode = __webpack_require__(16); + nextPosition = getNextPosition(newDelta); + var withinRowspan = sameRowspan(currentMerge, nextPosition), + withinColspan = sameColspan(currentMerge, nextPosition); -var _function = __webpack_require__(35); + if (currentSelectedRange.includesRange(mergedRange) && (mergedRange.includes(nextPosition) || withinRowspan || withinColspan)) { + // if next step overlaps a merged range, jump past it + if (withinRowspan) { + if (newDelta.row < 0) { + newDelta.row -= currentMerge.rowspan - 1; + } else if (newDelta.row > 0) { + newDelta.row += currentMerge.rowspan - 1; + } + } + if (withinColspan) { + if (newDelta.col < 0) { + newDelta.col -= currentMerge.colspan - 1; + } else if (newDelta.col > 0) { + newDelta.col += currentMerge.colspan - 1; + } + } + } + } + } -var _event = __webpack_require__(7); + if (newDelta.row !== 0) { + delta.row = newDelta.row; + } + if (newDelta.col !== 0) { + delta.col = newDelta.col; + } +}; -var _index = __webpack_require__(9); +MergeCells.prototype.shiftCollection = function (direction, index, count) { + var shiftVector = [0, 0]; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + switch (direction) { + case 'right': + shiftVector[0] += 1; -var isListeningKeyDownEvent = new WeakMap(); -var isCheckboxListenerAdded = new WeakMap(); -var BAD_VALUE_CLASS = 'htBadValue'; + break; + case 'left': + shiftVector[0] -= 1; -/** - * Checkbox renderer - * - * @private - * @param {Object} instance Handsontable instance - * @param {Element} TD Table cell where to render - * @param {Number} row - * @param {Number} col - * @param {String|Number} prop Row object property name - * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) - * @param {Object} cellProperties Cell properties (shared by cell renderer and editor) - */ -function checkboxRenderer(instance, TD, row, col, prop, value, cellProperties) { - (0, _index.getRenderer)('base').apply(this, arguments); + break; + case 'down': + shiftVector[1] += 1; - var eventManager = registerEvents(instance); - var input = createInput(); - var labelOptions = cellProperties.label; - var badValue = false; + break; + case 'up': + shiftVector[1] -= 1; - if (typeof cellProperties.checkedTemplate === 'undefined') { - cellProperties.checkedTemplate = true; + break; + default: + break; } - if (typeof cellProperties.uncheckedTemplate === 'undefined') { - cellProperties.uncheckedTemplate = false; + + for (var i = 0; i < this.mergedCellInfoCollection.length; i++) { + var currentMerge = this.mergedCellInfoCollection[i]; + + if (direction === 'right' || direction === 'left') { + if (index <= currentMerge.col) { + currentMerge.col += shiftVector[0]; + } + } else if (index <= currentMerge.row) { + currentMerge.row += shiftVector[1]; + } } +}; - (0, _element.empty)(TD); // TODO identify under what circumstances this line can be removed +var beforeInit = function beforeInit() { + var instance = this; + var mergeCellsSetting = instance.getSettings().mergeCells; - if (value === cellProperties.checkedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.checkedTemplate)) { - input.checked = true; - } else if (value === cellProperties.uncheckedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.uncheckedTemplate)) { - input.checked = false; - } else if (value === null) { - // default value - (0, _element.addClass)(input, 'noValue'); - } else { - input.style.display = 'none'; - (0, _element.addClass)(input, BAD_VALUE_CLASS); - badValue = true; + if (mergeCellsSetting) { + if (!instance.mergeCells) { + instance.mergeCells = new MergeCells(mergeCellsSetting); + } } +}; - input.setAttribute('data-row', row); - input.setAttribute('data-col', col); +var afterInit = function afterInit() { + var instance = this; + if (instance.mergeCells) { + /** + * Monkey patch Table.prototype.getCell to return TD for merged cell parent if asked for TD of a cell that is + * invisible due to the merge. This is not the cleanest solution but there is a test case for it (merged cells scroll) so feel free to refactor it! + */ + instance.view.wt.wtTable.getCell = function (coords) { + if (instance.getSettings().mergeCells) { + var mergeParent = instance.mergeCells.mergedCellInfoCollection.getInfo(coords.row, coords.col); + if (mergeParent) { + coords = mergeParent; + } + } + return _src.Table.prototype.getCell.call(this, coords); + }; + } +}; - if (!badValue && labelOptions) { - var labelText = ''; +var afterUpdateSettings = function afterUpdateSettings() { + var instance = this; + var mergeCellsSetting = instance.getSettings().mergeCells; - if (labelOptions.value) { - labelText = typeof labelOptions.value === 'function' ? labelOptions.value.call(this, row, col, prop, value) : labelOptions.value; - } else if (labelOptions.property) { - labelText = instance.getDataAtRowProp(row, labelOptions.property); - } - var label = createLabel(labelText); + if (mergeCellsSetting) { + if (instance.mergeCells) { + instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection(); - if (labelOptions.position === 'before') { - label.appendChild(input); + if (Array.isArray(mergeCellsSetting)) { + for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) { + instance.mergeCells.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]); + } + } } else { - label.insertBefore(input, label.firstChild); + instance.mergeCells = new MergeCells(mergeCellsSetting); } - input = label; + } else if (instance.mergeCells) { + // it doesn't actually turn off the plugin, just resets the settings. Need to refactor. + instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection(); } +}; - TD.appendChild(input); - - if (badValue) { - TD.appendChild(document.createTextNode('#bad-value#')); +var onBeforeKeyDown = function onBeforeKeyDown(event) { + if (!this.mergeCells) { + return; } - if (!isListeningKeyDownEvent.has(instance)) { - isListeningKeyDownEvent.set(instance, true); - instance.addHook('beforeKeyDown', onBeforeKeyDown); + var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; + + if (ctrlDown) { + if (event.keyCode === 77) { + // CTRL + M + this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange()); + this.render(); + (0, _event.stopImmediatePropagation)(event); + } } +}; - /** - * On before key down DOM listener. - * - * @private - * @param {Event} event - */ - function onBeforeKeyDown(event) { - var toggleKeys = 'SPACE|ENTER'; - var switchOffKeys = 'DELETE|BACKSPACE'; - var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode); +var addMergeActionsToContextMenu = function addMergeActionsToContextMenu(defaultOptions) { + if (!this.getSettings().mergeCells) { + return; + } - if (isKeyCode(toggleKeys + '|' + switchOffKeys) && !(0, _event.isImmediatePropagationStopped)(event)) { - eachSelectedCheckboxCell(function () { - (0, _event.stopImmediatePropagation)(event); - event.preventDefault(); - }); - } - if (isKeyCode(toggleKeys)) { - changeSelectedCheckboxesState(); - } - if (isKeyCode(switchOffKeys)) { - changeSelectedCheckboxesState(true); + defaultOptions.items.push({ name: '---------' }); + defaultOptions.items.push({ + key: 'mergeCells', + name: function name() { + var sel = this.getSelected(); + var info = this.mergeCells.mergedCellInfoCollection.getInfo(sel[0], sel[1]); + if (info) { + return 'Unmerge cells'; + } + return 'Merge cells'; + }, + callback: function callback() { + this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange()); + this.render(); + }, + disabled: function disabled() { + return this.selection.selectedHeader.corner; } + }); +}; + +var afterRenderer = function afterRenderer(TD, row, col, prop, value, cellProperties) { + if (this.mergeCells) { + this.mergeCells.applySpanProperties(TD, row, col); } +}; - /** - * Change checkbox checked property - * - * @private - * @param {Boolean} [uncheckCheckbox=false] - */ - function changeSelectedCheckboxesState() { - var uncheckCheckbox = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; +var modifyTransformFactory = function modifyTransformFactory(hook) { + return function (delta) { + var mergeCellsSetting = this.getSettings().mergeCells; + if (mergeCellsSetting) { + var currentSelectedRange = this.getSelectedRange(); + this.mergeCells.modifyTransform(hook, currentSelectedRange, delta); - var selRange = instance.getSelectedRange(); + if (hook === 'modifyTransformEnd') { + // sanitize "from" (core.js will sanitize to) + var totalRows = this.countRows(); + var totalCols = this.countCols(); + if (currentSelectedRange.from.row < 0) { + currentSelectedRange.from.row = 0; + } else if (currentSelectedRange.from.row > 0 && currentSelectedRange.from.row >= totalRows) { + currentSelectedRange.from.row = currentSelectedRange.from - 1; + } - if (!selRange) { - return; + if (currentSelectedRange.from.col < 0) { + currentSelectedRange.from.col = 0; + } else if (currentSelectedRange.from.col > 0 && currentSelectedRange.from.col >= totalCols) { + currentSelectedRange.from.col = totalCols - 1; + } + } } + }; +}; + +/** + * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell + * @param coords + */ +var beforeSetRangeEnd = function beforeSetRangeEnd(coords) { + + this.lastDesiredCoords = null; // unset lastDesiredCoords when selection is changed with mouse + var mergeCellsSetting = this.getSettings().mergeCells; + if (mergeCellsSetting) { + var selRange = this.getSelectedRange(); + selRange.highlight = new _src.CellCoords(selRange.highlight.row, selRange.highlight.col); // clone in case we will modify its reference + selRange.to = coords; + + var rangeExpanded = false; + do { + rangeExpanded = false; - var topLeft = selRange.getTopLeftCorner(); - var bottomRight = selRange.getBottomRightCorner(); - var changes = []; + for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) { + var cellInfo = this.mergeCells.mergedCellInfoCollection[i]; + var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col); + var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1); - for (var _row = topLeft.row; _row <= bottomRight.row; _row += 1) { - for (var _col = topLeft.col; _col <= bottomRight.col; _col += 1) { - var _cellProperties = instance.getCellMeta(_row, _col); + var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight); + if (selRange.expandByRange(mergedCellRange)) { + coords.row = selRange.to.row; + coords.col = selRange.to.col; - if (_cellProperties.type !== 'checkbox') { - return; + rangeExpanded = true; } + } + } while (rangeExpanded); + } +}; - /* eslint-disable no-continue */ - if (_cellProperties.readOnly === true) { - continue; - } +/** + * Returns correct coordinates for merged start / end cells in selection for area borders + * @param corners + * @param className + */ +var beforeDrawAreaBorders = function beforeDrawAreaBorders(corners, className) { + if (className && className == 'area') { + var mergeCellsSetting = this.getSettings().mergeCells; + if (mergeCellsSetting) { + var selRange = this.getSelectedRange(); + var startRange = new _src.CellRange(selRange.from, selRange.from, selRange.from); + var stopRange = new _src.CellRange(selRange.to, selRange.to, selRange.to); - if (typeof _cellProperties.checkedTemplate === 'undefined') { - _cellProperties.checkedTemplate = true; - } - if (typeof _cellProperties.uncheckedTemplate === 'undefined') { - _cellProperties.uncheckedTemplate = false; - } + for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) { + var cellInfo = this.mergeCells.mergedCellInfoCollection[i]; + var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col); + var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1); + var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight); - var dataAtCell = instance.getDataAtCell(_row, _col); + if (startRange.expandByRange(mergedCellRange)) { + corners[0] = startRange.from.row; + corners[1] = startRange.from.col; + } - if (uncheckCheckbox === false) { - if (dataAtCell === _cellProperties.checkedTemplate) { - changes.push([_row, _col, _cellProperties.uncheckedTemplate]); - } else if ([_cellProperties.uncheckedTemplate, null, void 0].indexOf(dataAtCell) !== -1) { - changes.push([_row, _col, _cellProperties.checkedTemplate]); - } - } else { - changes.push([_row, _col, _cellProperties.uncheckedTemplate]); + if (stopRange.expandByRange(mergedCellRange)) { + corners[2] = stopRange.from.row; + corners[3] = stopRange.from.col; } } } + } +}; - if (changes.length > 0) { - instance.setDataAtCell(changes); +var afterGetCellMeta = function afterGetCellMeta(row, col, cellProperties) { + var mergeCellsSetting = this.getSettings().mergeCells; + if (mergeCellsSetting) { + var mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(row, col); + if (mergeParent && (mergeParent.row != row || mergeParent.col != col)) { + cellProperties.copyable = false; } } +}; - /** - * Call callback for each found selected cell with checkbox type. - * - * @private - * @param {Function} callback - */ - function eachSelectedCheckboxCell(callback) { - var selRange = instance.getSelectedRange(); - - if (!selRange) { - return; +var afterViewportRowCalculatorOverride = function afterViewportRowCalculatorOverride(calc) { + var mergeCellsSetting = this.getSettings().mergeCells; + if (mergeCellsSetting) { + var colCount = this.countCols(); + var mergeParent; + for (var c = 0; c < colCount; c++) { + mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.startRow, c); + if (mergeParent) { + if (mergeParent.row < calc.startRow) { + calc.startRow = mergeParent.row; + return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards + } + } + mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.endRow, c); + if (mergeParent) { + var mergeEnd = mergeParent.row + mergeParent.rowspan - 1; + if (mergeEnd > calc.endRow) { + calc.endRow = mergeEnd; + return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards + } + } } - var topLeft = selRange.getTopLeftCorner(); - var bottomRight = selRange.getBottomRightCorner(); + } +}; - for (var _row2 = topLeft.row; _row2 <= bottomRight.row; _row2++) { - for (var _col2 = topLeft.col; _col2 <= bottomRight.col; _col2++) { - var _cellProperties2 = instance.getCellMeta(_row2, _col2); +var afterViewportColumnCalculatorOverride = function afterViewportColumnCalculatorOverride(calc) { + var mergeCellsSetting = this.getSettings().mergeCells; + if (mergeCellsSetting) { + var rowCount = this.countRows(); + var mergeParent; + for (var r = 0; r < rowCount; r++) { + mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.startColumn); - if (_cellProperties2.type !== 'checkbox') { - return; + if (mergeParent) { + if (mergeParent.col < calc.startColumn) { + calc.startColumn = mergeParent.col; + return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards } - - var cell = instance.getCell(_row2, _col2); - - if (cell == null) { - - callback(_row2, _col2, _cellProperties2); - } else { - var checkboxes = cell.querySelectorAll('input[type=checkbox]'); - - if (checkboxes.length > 0 && !_cellProperties2.readOnly) { - callback(checkboxes); - } + } + mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.endColumn); + if (mergeParent) { + var mergeEnd = mergeParent.col + mergeParent.colspan - 1; + if (mergeEnd > calc.endColumn) { + calc.endColumn = mergeEnd; + return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards } } } } -} - -/** - * Register checkbox listeners. - * - * @param {Handsontable} instance Handsontable instance. - * @returns {EventManager} - */ -function registerEvents(instance) { - var eventManager = isCheckboxListenerAdded.get(instance); +}; - if (!eventManager) { - eventManager = new _eventManager2.default(instance); - eventManager.addEventListener(instance.rootElement, 'click', function (event) { - return onClick(event, instance); - }); - eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) { - return onMouseUp(event, instance); - }); - eventManager.addEventListener(instance.rootElement, 'change', function (event) { - return onChange(event, instance); - }); +var isMultipleSelection = function isMultipleSelection(isMultiple) { + if (isMultiple && this.mergeCells) { + var mergedCells = this.mergeCells.mergedCellInfoCollection, + selectionRange = this.getSelectedRange(); - isCheckboxListenerAdded.set(instance, eventManager); + for (var group in mergedCells) { + if (selectionRange.highlight.row == mergedCells[group].row && selectionRange.highlight.col == mergedCells[group].col && selectionRange.to.row == mergedCells[group].row + mergedCells[group].rowspan - 1 && selectionRange.to.col == mergedCells[group].col + mergedCells[group].colspan - 1) { + return false; + } + } } + return isMultiple; +}; - return eventManager; -} - -/** - * Create input element. - * - * @returns {Node} - */ -function createInput() { - var input = document.createElement('input'); - - input.className = 'htCheckboxRendererInput'; - input.type = 'checkbox'; - input.setAttribute('autocomplete', 'off'); - input.setAttribute('tabindex', '-1'); - - return input.cloneNode(false); -} - -/** - * Create label element. - * - * @returns {Node} - */ -function createLabel(text) { - var label = document.createElement('label'); - - label.className = 'htCheckboxRendererLabel'; - label.appendChild(document.createTextNode(text)); - - return label.cloneNode(true); -} +function modifyAutofillRange(select, drag) { + var mergeCellsSetting = this.getSettings().mergeCells; -/** - * `mouseup` callback. - * - * @private - * @param {Event} event `mouseup` event. - * @param {Object} instance Handsontable instance. - */ -function onMouseUp(event, instance) { - if (!isCheckboxInput(event.target)) { + if (!mergeCellsSetting || this.selection.isMultiple()) { return; } - setTimeout(instance.listen, 10); -} + var info = this.mergeCells.mergedCellInfoCollection.getInfo(select[0], select[1]); -/** - * `click` callback. - * - * @private - * @param {Event} event `click` event. - * @param {Object} instance Handsontable instance. - */ -function onClick(event, instance) { - if (!isCheckboxInput(event.target)) { - return false; + if (info) { + select[0] = info.row; + select[1] = info.col; + select[2] = info.row + info.rowspan - 1; + select[3] = info.col + info.colspan - 1; } +} - var row = parseInt(event.target.getAttribute('data-row'), 10); - var col = parseInt(event.target.getAttribute('data-col'), 10); - var cellProperties = instance.getCellMeta(row, col); - - if (cellProperties.readOnly) { - event.preventDefault(); +function onAfterCreateCol(col, count) { + if (this.mergeCells) { + this.mergeCells.shiftCollection('right', col, count); } } -/** - * `change` callback. - * - * @param {Event} event `change` event. - * @param {Object} instance Handsontable instance. - * @param {Object} cellProperties Reference to cell properties. - * @returns {Boolean} - */ -function onChange(event, instance) { - if (!isCheckboxInput(event.target)) { - return false; +function onAfterRemoveCol(col, count) { + if (this.mergeCells) { + this.mergeCells.shiftCollection('left', col, count); } +} - var row = parseInt(event.target.getAttribute('data-row'), 10); - var col = parseInt(event.target.getAttribute('data-col'), 10); - var cellProperties = instance.getCellMeta(row, col); - - if (!cellProperties.readOnly) { - var newCheckboxValue = null; - - if (event.target.checked) { - newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? true : cellProperties.checkedTemplate; - } else { - newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? false : cellProperties.uncheckedTemplate; - } - - instance.setDataAtCell(row, col, newCheckboxValue); +function onAfterCreateRow(row, count) { + if (this.mergeCells) { + this.mergeCells.shiftCollection('down', row, count); } } -/** - * Check if the provided element is the checkbox input. - * - * @private - * @param {HTMLElement} element The element in question. - * @returns {Boolean} - */ -function isCheckboxInput(element) { - return element.tagName === 'INPUT' && element.getAttribute('type') === 'checkbox'; +function onAfterRemoveRow(row, count) { + if (this.mergeCells) { + this.mergeCells.shiftCollection('up', row, count); + } } -exports.default = checkboxRenderer; +var hook = _pluginHooks2.default.getSingleton(); + +hook.add('beforeInit', beforeInit); +hook.add('afterInit', afterInit); +hook.add('afterUpdateSettings', afterUpdateSettings); +hook.add('beforeKeyDown', onBeforeKeyDown); +hook.add('modifyTransformStart', modifyTransformFactory('modifyTransformStart')); +hook.add('modifyTransformEnd', modifyTransformFactory('modifyTransformEnd')); +hook.add('beforeSetRangeEnd', beforeSetRangeEnd); +hook.add('beforeDrawBorders', beforeDrawAreaBorders); +hook.add('afterIsMultipleSelection', isMultipleSelection); +hook.add('afterRenderer', afterRenderer); +hook.add('afterContextMenuDefaultOptions', addMergeActionsToContextMenu); +hook.add('afterGetCellMeta', afterGetCellMeta); +hook.add('afterViewportRowCalculatorOverride', afterViewportRowCalculatorOverride); +hook.add('afterViewportColumnCalculatorOverride', afterViewportColumnCalculatorOverride); +hook.add('modifyAutofillRange', modifyAutofillRange); +hook.add('afterCreateCol', onAfterCreateCol); +hook.add('afterRemoveCol', onAfterRemoveCol); +hook.add('afterCreateRow', onAfterCreateRow); +hook.add('afterRemoveRow', onAfterRemoveRow); + +exports.default = MergeCells; /***/ }), -/* 267 */ +/* 300 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63652,197 +64007,419 @@ exports.default = checkboxRenderer; exports.__esModule = true; -var _element = __webpack_require__(0); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _index = __webpack_require__(9); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -/** - * @private - * @renderer HtmlRenderer - * @param instance - * @param TD - * @param row - * @param col - * @param prop - * @param value - * @param cellProperties - */ -function htmlRenderer(instance, TD, row, col, prop, value, cellProperties) { - (0, _index.getRenderer)('base').apply(this, arguments); +var _pluginHooks = __webpack_require__(7); - if (value === null || value === void 0) { - value = ''; - } +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - (0, _element.fastInnerHTML)(TD, value); -} +var _element = __webpack_require__(0); -exports.default = htmlRenderer; +var _browser = __webpack_require__(26); -/***/ }), -/* 268 */ -/***/ (function(module, exports, __webpack_require__) { +var _base = __webpack_require__(13); -"use strict"; +var _base2 = _interopRequireDefault(_base); +var _eventManager = __webpack_require__(4); -exports.__esModule = true; +var _eventManager2 = _interopRequireDefault(_eventManager); -var _numbro = __webpack_require__(87); +var _plugins = __webpack_require__(5); -var _numbro2 = _interopRequireDefault(_numbro); +var _src = __webpack_require__(12); -var _index = __webpack_require__(9); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _number = __webpack_require__(6); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** - * Numeric cell renderer - * * @private - * @renderer NumericRenderer - * @dependencies numbro - * @param {Object} instance Handsontable instance - * @param {Element} TD Table cell where to render - * @param {Number} row - * @param {Number} col - * @param {String|Number} prop Row object property name - * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) - * @param {Object} cellProperties Cell properties (shared by cell renderer and editor) + * @plugin MultipleSelectionHandles */ -function numericRenderer(instance, TD, row, col, prop, value, cellProperties) { - if ((0, _number.isNumeric)(value)) { - if (typeof cellProperties.language !== 'undefined') { - _numbro2.default.culture(cellProperties.language); - } +var MultipleSelectionHandles = function (_BasePlugin) { + _inherits(MultipleSelectionHandles, _BasePlugin); - value = (0, _numbro2.default)(value).format(cellProperties.format || '0'); + /** + * @param {Object} hotInstance + */ + function MultipleSelectionHandles(hotInstance) { + _classCallCheck(this, MultipleSelectionHandles); - var className = cellProperties.className || ''; + /** + * @type {Array} + */ + var _this2 = _possibleConstructorReturn(this, (MultipleSelectionHandles.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles)).call(this, hotInstance)); - var classArr = className.length ? className.split(' ') : []; + _this2.dragged = []; + /** + * Instance of EventManager. + * + * @type {EventManager} + */ + _this2.eventManager = null; + /** + * @type {null} + */ + _this2.lastSetCell = null; + return _this2; + } - if (classArr.indexOf('htLeft') < 0 && classArr.indexOf('htCenter') < 0 && classArr.indexOf('htRight') < 0 && classArr.indexOf('htJustify') < 0) { - classArr.push('htRight'); + /** + * Check if the plugin is enabled in the handsontable settings. + * + * @returns {Boolean} + */ + + + _createClass(MultipleSelectionHandles, [{ + key: 'isEnabled', + value: function isEnabled() { + return (0, _browser.isMobileBrowser)(); } - if (classArr.indexOf('htNumeric') < 0) { - classArr.push('htNumeric'); + /** + * Enable plugin for this Handsontable instance. + */ + + }, { + key: 'enablePlugin', + value: function enablePlugin() { + if (this.enabled) { + return; + } + if (!this.eventManager) { + this.eventManager = new _eventManager2.default(this); + } + this.registerListeners(); + _get(MultipleSelectionHandles.prototype.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles.prototype), 'enablePlugin', this).call(this); } - cellProperties.className = classArr.join(' '); - } + /** + * Bind the touch events + * @private + */ - (0, _index.getRenderer)('text')(instance, TD, row, col, prop, value, cellProperties); -} + }, { + key: 'registerListeners', + value: function registerListeners() { + var _this = this; -exports.default = numericRenderer; + function removeFromDragged(query) { -/***/ }), -/* 269 */ -/***/ (function(module, exports, __webpack_require__) { + if (_this.dragged.length === 1) { + // clear array + _this.dragged.splice(0, _this.dragged.length); + + return true; + } + + var entryPosition = _this.dragged.indexOf(query); + + if (entryPosition == -1) { + return false; + } else if (entryPosition === 0) { + _this.dragged = _this.dragged.slice(0, 1); + } else if (entryPosition == 1) { + _this.dragged = _this.dragged.slice(-1); + } + } + + this.eventManager.addEventListener(this.hot.rootElement, 'touchstart', function (event) { + var selectedRange = void 0; + + if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) { + selectedRange = _this.hot.getSelectedRange(); + + _this.dragged.push('topLeft'); + + _this.touchStartRange = { + width: selectedRange.getWidth(), + height: selectedRange.getHeight(), + direction: selectedRange.getDirection() + }; + + event.preventDefault(); + return false; + } else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) { + selectedRange = _this.hot.getSelectedRange(); + + _this.dragged.push('bottomRight'); + + _this.touchStartRange = { + width: selectedRange.getWidth(), + height: selectedRange.getHeight(), + direction: selectedRange.getDirection() + }; + + event.preventDefault(); + return false; + } + }); + + this.eventManager.addEventListener(this.hot.rootElement, 'touchend', function (event) { + if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) { + removeFromDragged.call(_this, 'topLeft'); -"use strict"; + _this.touchStartRange = void 0; + event.preventDefault(); + return false; + } else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) { + removeFromDragged.call(_this, 'bottomRight'); -exports.__esModule = true; + _this.touchStartRange = void 0; -var _element = __webpack_require__(0); + event.preventDefault(); + return false; + } + }); -var _index = __webpack_require__(9); + this.eventManager.addEventListener(this.hot.rootElement, 'touchmove', function (event) { + var scrollTop = (0, _element.getWindowScrollTop)(), + scrollLeft = (0, _element.getWindowScrollLeft)(), + endTarget = void 0, + targetCoords = void 0, + selectedRange = void 0, + rangeWidth = void 0, + rangeHeight = void 0, + rangeDirection = void 0, + newRangeCoords = void 0; -var _number = __webpack_require__(6); + if (_this.dragged.length === 0) { + return; + } -/** - * @private - * @renderer PasswordRenderer - * @param instance - * @param TD - * @param row - * @param col - * @param prop - * @param value - * @param cellProperties - */ -function passwordRenderer(instance, TD, row, col, prop, value, cellProperties) { - (0, _index.getRenderer)('text').apply(this, arguments); + endTarget = document.elementFromPoint(event.touches[0].screenX - scrollLeft, event.touches[0].screenY - scrollTop); - value = TD.innerHTML; + if (!endTarget || endTarget === _this.lastSetCell) { + return; + } - var hashLength = cellProperties.hashLength || value.length; - var hashSymbol = cellProperties.hashSymbol || '*'; + if (endTarget.nodeName == 'TD' || endTarget.nodeName == 'TH') { + targetCoords = _this.hot.getCoords(endTarget); - var hash = ''; + if (targetCoords.col == -1) { + targetCoords.col = 0; + } - (0, _number.rangeEach)(hashLength - 1, function () { - hash += hashSymbol; - }); - (0, _element.fastInnerHTML)(TD, hash); -} + selectedRange = _this.hot.getSelectedRange(); + rangeWidth = selectedRange.getWidth(); + rangeHeight = selectedRange.getHeight(); + rangeDirection = selectedRange.getDirection(); -exports.default = passwordRenderer; + if (rangeWidth == 1 && rangeHeight == 1) { + _this.hot.selection.setRangeEnd(targetCoords); + } -/***/ }), -/* 270 */ -/***/ (function(module, exports, __webpack_require__) { + newRangeCoords = _this.getCurrentRangeCoords(selectedRange, targetCoords, _this.touchStartRange.direction, rangeDirection, _this.dragged[0]); -"use strict"; + if (newRangeCoords.start !== null) { + _this.hot.selection.setRangeStart(newRangeCoords.start); + } + _this.hot.selection.setRangeEnd(newRangeCoords.end); -exports.__esModule = true; + _this.lastSetCell = endTarget; + } -var _element = __webpack_require__(0); + event.preventDefault(); + }); + } + }, { + key: 'getCurrentRangeCoords', + value: function getCurrentRangeCoords(selectedRange, currentTouch, touchStartDirection, currentDirection, draggedHandle) { + var topLeftCorner = selectedRange.getTopLeftCorner(), + bottomRightCorner = selectedRange.getBottomRightCorner(), + bottomLeftCorner = selectedRange.getBottomLeftCorner(), + topRightCorner = selectedRange.getTopRightCorner(); -var _mixed = __webpack_require__(20); + var newCoords = { + start: null, + end: null + }; -var _index = __webpack_require__(9); + switch (touchStartDirection) { + case 'NE-SW': + switch (currentDirection) { + case 'NE-SW': + case 'NW-SE': + if (draggedHandle == 'topLeft') { + newCoords = { + start: new _src.CellCoords(currentTouch.row, selectedRange.highlight.col), + end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col) + }; + } else { + newCoords = { + start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col), + end: new _src.CellCoords(currentTouch.row, topLeftCorner.col) + }; + } + break; + case 'SE-NW': + if (draggedHandle == 'bottomRight') { + newCoords = { + start: new _src.CellCoords(bottomRightCorner.row, currentTouch.col), + end: new _src.CellCoords(currentTouch.row, topLeftCorner.col) + }; + } + break; + default: + break; + } + break; + case 'NW-SE': + switch (currentDirection) { + case 'NE-SW': + if (draggedHandle == 'topLeft') { + newCoords = { + start: currentTouch, + end: bottomLeftCorner + }; + } else { + newCoords.end = currentTouch; + } + break; + case 'NW-SE': + if (draggedHandle == 'topLeft') { + newCoords = { + start: currentTouch, + end: bottomRightCorner + }; + } else { + newCoords.end = currentTouch; + } + break; + case 'SE-NW': + if (draggedHandle == 'topLeft') { + newCoords = { + start: currentTouch, + end: topLeftCorner + }; + } else { + newCoords.end = currentTouch; + } + break; + case 'SW-NE': + if (draggedHandle == 'topLeft') { + newCoords = { + start: currentTouch, + end: topRightCorner + }; + } else { + newCoords.end = currentTouch; + } + break; + default: + break; + } + break; + case 'SW-NE': + switch (currentDirection) { + case 'NW-SE': + if (draggedHandle == 'bottomRight') { + newCoords = { + start: new _src.CellCoords(currentTouch.row, topLeftCorner.col), + end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col) + }; + } else { + newCoords = { + start: new _src.CellCoords(topLeftCorner.row, currentTouch.col), + end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col) + }; + } + break; + // case 'NE-SW': + // + // break; + case 'SW-NE': + if (draggedHandle == 'topLeft') { + newCoords = { + start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col), + end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col) + }; + } else { + newCoords = { + start: new _src.CellCoords(currentTouch.row, topLeftCorner.col), + end: new _src.CellCoords(topLeftCorner.row, currentTouch.col) + }; + } + break; + case 'SE-NW': + if (draggedHandle == 'bottomRight') { + newCoords = { + start: new _src.CellCoords(currentTouch.row, topRightCorner.col), + end: new _src.CellCoords(topLeftCorner.row, currentTouch.col) + }; + } else if (draggedHandle == 'topLeft') { + newCoords = { + start: bottomLeftCorner, + end: currentTouch + }; + } + break; + default: + break; + } + break; + case 'SE-NW': + switch (currentDirection) { + case 'NW-SE': + case 'NE-SW': + case 'SW-NE': + if (draggedHandle == 'topLeft') { + newCoords.end = currentTouch; + } + break; + case 'SE-NW': + if (draggedHandle == 'topLeft') { + newCoords.end = currentTouch; + } else { + newCoords = { + start: currentTouch, + end: topLeftCorner + }; + } + break; + default: + break; + } + break; + default: + break; + } -/** - * Default text renderer - * - * @private - * @renderer TextRenderer - * @param {Object} instance Handsontable instance - * @param {Element} TD Table cell where to render - * @param {Number} row - * @param {Number} col - * @param {String|Number} prop Row object property name - * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!) - * @param {Object} cellProperties Cell properties (shared by cell renderer and editor) - */ -function textRenderer(instance, TD, row, col, prop, value, cellProperties) { - (0, _index.getRenderer)('base').apply(this, arguments); + return newCoords; + } - if (!value && cellProperties.placeholder) { - value = cellProperties.placeholder; - } + /** + * Check if user is currently dragging the handle. + * + * @returns {boolean} Dragging state + */ - var escaped = (0, _mixed.stringify)(value); + }, { + key: 'isDragged', + value: function isDragged() { + return this.dragged.length > 0; + } + }]); - if (!instance.getSettings().trimWhitespace) { - escaped = escaped.replace(/ /g, String.fromCharCode(160)); - } + return MultipleSelectionHandles; +}(_base2.default); - if (cellProperties.rendererTemplate) { - (0, _element.empty)(TD); - var TEMPLATE = document.createElement('TEMPLATE'); - TEMPLATE.setAttribute('bind', '{{}}'); - TEMPLATE.innerHTML = cellProperties.rendererTemplate; - HTMLTemplateElement.decorate(TEMPLATE); - TEMPLATE.model = instance.getSourceDataAtRow(row); - TD.appendChild(TEMPLATE); - } else { - // this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips - (0, _element.fastInnerText)(TD, escaped); - } -} +(0, _plugins.registerPlugin)('multipleSelectionHandles', MultipleSelectionHandles); -exports.default = textRenderer; +exports.default = MultipleSelectionHandles; /***/ }), -/* 271 */ +/* 301 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63850,1121 +64427,829 @@ exports.default = textRenderer; exports.__esModule = true; -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _element = __webpack_require__(0); +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; -var _browser = __webpack_require__(25); +var _base = __webpack_require__(13); -var _eventManager = __webpack_require__(4); +var _base2 = _interopRequireDefault(_base); -var _eventManager2 = _interopRequireDefault(_eventManager); +var _jsonPatchDuplex = __webpack_require__(179); -var _event = __webpack_require__(7); +var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex); -var _src = __webpack_require__(11); +var _dataObserver = __webpack_require__(302); -var _src2 = _interopRequireDefault(_src); +var _dataObserver2 = _interopRequireDefault(_dataObserver); + +var _array = __webpack_require__(2); + +var _plugins = __webpack_require__(5); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -/** - * Handsontable TableView constructor - * @param {Object} instance - */ -function TableView(instance) { - var _this = this; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var that = this; +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - this.eventManager = new _eventManager2.default(instance); - this.instance = instance; - this.settings = instance.getSettings(); - this.selectionMouseDown = false; +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var originalStyle = instance.rootElement.getAttribute('style'); +// Handsontable.hooks.register('afterChangesObserved'); - if (originalStyle) { - instance.rootElement.setAttribute('data-originalstyle', originalStyle); // needed to retrieve original style in jsFiddle link generator in HT examples. may be removed in future versions - } +/** + * @plugin ObserveChanges + * + * @description + * This plugin allows to observe data source changes. + * + * By default, the plugin is declared as `undefined`, which makes it disabled. + * Enabling this plugin switches the table into one-way data binding where changes are applied into the data source (outside from the table) + * will be automatically reflected in the table. + * + * ```js + * ... + * // as a boolean + * observeChanges: true, + * ... + * ``` + * + * To configure this plugin see {@link Options#observeChanges}. + */ +var ObserveChanges = function (_BasePlugin) { + _inherits(ObserveChanges, _BasePlugin); - (0, _element.addClass)(instance.rootElement, 'handsontable'); + function ObserveChanges(hotInstance) { + _classCallCheck(this, ObserveChanges); - var table = document.createElement('TABLE'); - (0, _element.addClass)(table, 'htCore'); + /** + * Instance of {@link DataObserver}. + * + * @type {DataObserver} + */ + var _this = _possibleConstructorReturn(this, (ObserveChanges.__proto__ || Object.getPrototypeOf(ObserveChanges)).call(this, hotInstance)); - if (instance.getSettings().tableClassName) { - (0, _element.addClass)(table, instance.getSettings().tableClassName); + _this.observer = null; + return _this; } - this.THEAD = document.createElement('THEAD'); - table.appendChild(this.THEAD); - this.TBODY = document.createElement('TBODY'); - table.appendChild(this.TBODY); - instance.table = table; - - instance.container.insertBefore(table, instance.container.firstChild); + /** + * Check if the plugin is enabled in the handsontable settings. + * + * @returns {Boolean} + */ - this.eventManager.addEventListener(instance.rootElement, 'mousedown', function (event) { - this.selectionMouseDown = true; - if (!that.isTextSelectionAllowed(event.target)) { - clearTextSelection(); - event.preventDefault(); - window.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe. - } - }); - this.eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) { - this.selectionMouseDown = false; - }); - this.eventManager.addEventListener(instance.rootElement, 'mousemove', function (event) { - if (this.selectionMouseDown && !that.isTextSelectionAllowed(event.target)) { - clearTextSelection(); - event.preventDefault(); + _createClass(ObserveChanges, [{ + key: 'isEnabled', + value: function isEnabled() { + return this.hot.getSettings().observeChanges; } - }); - this.eventManager.addEventListener(document.documentElement, 'keyup', function (event) { - if (instance.selection.isInProgress() && !event.shiftKey) { - instance.selection.finish(); - } - }); + /** + * Enable plugin for this Handsontable instance. + */ - var isMouseDown; - this.isMouseDown = function () { - return isMouseDown; - }; + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; - this.eventManager.addEventListener(document.documentElement, 'mouseup', function (event) { - if (instance.selection.isInProgress() && event.which === 1) { - // is left mouse button - instance.selection.finish(); - } + if (this.enabled) { + return; + } + if (!this.observer) { + this.observer = new _dataObserver2.default(this.hot.getSourceData()); + this._exposePublicApi(); + } - isMouseDown = false; + this.observer.addLocalHook('change', function (patches) { + return _this2.onDataChange(patches); + }); + this.addHook('afterCreateRow', function () { + return _this2.onAfterTableAlter(); + }); + this.addHook('afterRemoveRow', function () { + return _this2.onAfterTableAlter(); + }); + this.addHook('afterCreateCol', function () { + return _this2.onAfterTableAlter(); + }); + this.addHook('afterRemoveCol', function () { + return _this2.onAfterTableAlter(); + }); + this.addHook('afterChange', function (changes, source) { + return _this2.onAfterTableAlter(source); + }); + this.addHook('afterLoadData', function (firstRun) { + return _this2.onAfterLoadData(firstRun); + }); - if ((0, _element.isOutsideInput)(document.activeElement) || !instance.selection.isSelected()) { - instance.unlisten(); + _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'enablePlugin', this).call(this); } - }); - this.eventManager.addEventListener(document.documentElement, 'mousedown', function (event) { - var originalTarget = event.target; - var next = event.target; - var eventX = event.x || event.clientX; - var eventY = event.y || event.clientY; + /** + * Disable plugin for this Handsontable instance. + */ - if (isMouseDown || !instance.rootElement) { - return; // it must have been started in a cell + }, { + key: 'disablePlugin', + value: function disablePlugin() { + if (this.observer) { + this.observer.destroy(); + this.observer = null; + this._deletePublicApi(); + } + + _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'disablePlugin', this).call(this); } - // immediate click on "holder" means click on the right side of vertical scrollbar - if (next === instance.view.wt.wtTable.holder) { - var scrollbarWidth = (0, _element.getScrollbarWidth)(); + /** + * Data change observer. + * + * @private + * @param {Array} patches An array of objects which every item defines coordinates where data was changed. + */ - if (document.elementFromPoint(eventX + scrollbarWidth, eventY) !== instance.view.wt.wtTable.holder || document.elementFromPoint(eventX, eventY + scrollbarWidth) !== instance.view.wt.wtTable.holder) { - return; - } - } else { - while (next !== document.documentElement) { - if (next === null) { - if (event.isTargetWebComponent) { - break; + }, { + key: 'onDataChange', + value: function onDataChange(patches) { + var _this3 = this; + + if (!this.observer.isPaused()) { + var sourceName = this.pluginName + '.change'; + var actions = { + add: function add(patch) { + if (isNaN(patch.col)) { + _this3.hot.runHooks('afterCreateRow', patch.row, 1, sourceName); + } else { + _this3.hot.runHooks('afterCreateCol', patch.col, 1, sourceName); + } + }, + remove: function remove(patch) { + if (isNaN(patch.col)) { + _this3.hot.runHooks('afterRemoveRow', patch.row, 1, sourceName); + } else { + _this3.hot.runHooks('afterRemoveCol', patch.col, 1, sourceName); + } + }, + replace: function replace(patch) { + _this3.hot.runHooks('afterChange', [patch.row, patch.col, null, patch.value], sourceName); } - // click on something that was a row but now is detached (possibly because your click triggered a rerender) - return; - } - if (next === instance.rootElement) { - // click inside container - return; - } - next = next.parentNode; + }; + + (0, _array.arrayEach)(patches, function (patch) { + if (actions[patch.op]) { + actions[patch.op](patch); + } + }); + this.hot.render(); } + + this.hot.runHooks('afterChangesObserved'); } - // function did not return until here, we have an outside click! + /** + * On after table alter listener. Prevents infinity loop between internal and external data changing. + * + * @private + * @param source + */ - var outsideClickDeselects = typeof that.settings.outsideClickDeselects === 'function' ? that.settings.outsideClickDeselects(originalTarget) : that.settings.outsideClickDeselects; + }, { + key: 'onAfterTableAlter', + value: function onAfterTableAlter(source) { + var _this4 = this; - if (outsideClickDeselects) { - instance.deselectCell(); - } else { - instance.destroyEditor(); + if (source !== 'loadData') { + this.observer.pause(); + this.hot.addHookOnce('afterChangesObserved', function () { + return _this4.observer.resume(); + }); + } } - }); - this.eventManager.addEventListener(table, 'selectstart', function (event) { - if (that.settings.fragmentSelection || (0, _element.isInput)(event.target)) { - return; - } - // https://github.com/handsontable/handsontable/issues/160 - // Prevent text from being selected when performing drag down. - event.preventDefault(); - }); + /** + * On after load data listener. + * + * @private + * @param {Boolean} firstRun `true` if event was fired first time. + */ - var clearTextSelection = function clearTextSelection() { - // http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript - if (window.getSelection) { - if (window.getSelection().empty) { - // Chrome - window.getSelection().empty(); - } else if (window.getSelection().removeAllRanges) { - // Firefox - window.getSelection().removeAllRanges(); + }, { + key: 'onAfterLoadData', + value: function onAfterLoadData(firstRun) { + if (!firstRun) { + this.observer.setObservedData(this.hot.getSourceData()); } - } else if (document.selection) { - // IE? - document.selection.empty(); } - }; - var selections = [new _src.Selection({ - className: 'current', - border: { - width: 2, - color: '#5292F7', - // style: 'solid', // not used - cornerVisible: function cornerVisible() { - return that.settings.fillHandle && !that.isCellEdited() && !instance.selection.isMultiple(); - }, - multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() { - return !that.isCellEdited() && !instance.selection.isMultiple(); - } - } - }), new _src.Selection({ - className: 'area', - border: { - width: 1, - color: '#89AFF9', - // style: 'solid', // not used - cornerVisible: function cornerVisible() { - return that.settings.fillHandle && !that.isCellEdited() && instance.selection.isMultiple(); - }, - multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() { - return !that.isCellEdited() && instance.selection.isMultiple(); + /** + * Destroy plugin instance. + */ + + }, { + key: 'destroy', + value: function destroy() { + if (this.observer) { + this.observer.destroy(); + this._deletePublicApi(); } + _get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'destroy', this).call(this); } - }), new _src.Selection({ - className: 'highlight', - highlightHeaderClassName: that.settings.currentHeaderClassName, - highlightRowClassName: that.settings.currentRowClassName, - highlightColumnClassName: that.settings.currentColClassName - }), new _src.Selection({ - className: 'fill', - border: { - width: 1, - color: 'red' - // style: 'solid' // not used - } - })]; - selections.current = selections[0]; - selections.area = selections[1]; - selections.highlight = selections[2]; - selections.fill = selections[3]; - var walkontableConfig = { - debug: function debug() { - return that.settings.debug; - }, - externalRowCalculator: this.instance.getPlugin('autoRowSize') && this.instance.getPlugin('autoRowSize').isEnabled(), - table: table, - preventOverflow: function preventOverflow() { - return _this.settings.preventOverflow; - }, - stretchH: function stretchH() { - return that.settings.stretchH; - }, - data: instance.getDataAtCell, - totalRows: function totalRows() { - return instance.countRows(); - }, - totalColumns: function totalColumns() { - return instance.countCols(); - }, - fixedColumnsLeft: function fixedColumnsLeft() { - return that.settings.fixedColumnsLeft; - }, - fixedRowsTop: function fixedRowsTop() { - return that.settings.fixedRowsTop; - }, - fixedRowsBottom: function fixedRowsBottom() { - return that.settings.fixedRowsBottom; - }, - minSpareRows: function minSpareRows() { - return that.settings.minSpareRows; - }, - renderAllRows: that.settings.renderAllRows, - rowHeaders: function rowHeaders() { - var headerRenderers = []; + /** + * Expose plugins methods to the core. + * + * @private + */ - if (instance.hasRowHeaders()) { - headerRenderers.push(function (row, TH) { - that.appendRowHeader(row, TH); - }); - } - instance.runHooks('afterGetRowHeaderRenderers', headerRenderers); + }, { + key: '_exposePublicApi', + value: function _exposePublicApi() { + var _this5 = this; - return headerRenderers; - }, - columnHeaders: function columnHeaders() { - var headerRenderers = []; + var hot = this.hot; - if (instance.hasColHeaders()) { - headerRenderers.push(function (column, TH) { - that.appendColHeader(column, TH); - }); - } - instance.runHooks('afterGetColumnHeaderRenderers', headerRenderers); + hot.pauseObservingChanges = function () { + return _this5.observer.pause(); + }; + hot.resumeObservingChanges = function () { + return _this5.observer.resume(); + }; + hot.isPausedObservingChanges = function () { + return _this5.observer.isPaused(); + }; + } - return headerRenderers; - }, - columnWidth: instance.getColWidth, - rowHeight: instance.getRowHeight, - cellRenderer: function cellRenderer(row, col, TD) { - var cellProperties = that.instance.getCellMeta(row, col); - var prop = that.instance.colToProp(col); - var value = that.instance.getDataAtRowProp(row, prop); + /** + * Delete all previously exposed methods. + * + * @private + */ - if (that.instance.hasHook('beforeValueRender')) { - value = that.instance.runHooks('beforeValueRender', value); - } + }, { + key: '_deletePublicApi', + value: function _deletePublicApi() { + var hot = this.hot; - that.instance.runHooks('beforeRenderer', TD, row, col, prop, value, cellProperties); - that.instance.getCellRenderer(cellProperties)(that.instance, TD, row, col, prop, value, cellProperties); - that.instance.runHooks('afterRenderer', TD, row, col, prop, value, cellProperties); - }, - selections: selections, - hideBorderOnMouseDownOver: function hideBorderOnMouseDownOver() { - return that.settings.fragmentSelection; - }, - onCellMouseDown: function onCellMouseDown(event, coords, TD, wt) { - var blockCalculations = { - row: false, - column: false, - cells: false - }; + delete hot.pauseObservingChanges; + delete hot.resumeObservingChanges; + delete hot.isPausedObservingChanges; + } + }]); - instance.listen(); + return ObserveChanges; +}(_base2.default); - that.activeWt = wt; - isMouseDown = true; +exports.default = ObserveChanges; - instance.runHooks('beforeOnCellMouseDown', event, coords, TD, blockCalculations); - if ((0, _event.isImmediatePropagationStopped)(event)) { - return; - } +(0, _plugins.registerPlugin)('observeChanges', ObserveChanges); - var actualSelection = instance.getSelectedRange(); - var selection = instance.selection; - var selectedHeader = selection.selectedHeader; +/***/ }), +/* 302 */ +/***/ (function(module, exports, __webpack_require__) { - if (event.shiftKey && actualSelection) { - if (coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) { - selection.setSelectedHeaders(false, false); - selection.setRangeEnd(coords); - } else if ((selectedHeader.cols || selectedHeader.rows) && coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) { - selection.setSelectedHeaders(false, false); - selection.setRangeEnd(new _src.CellCoords(coords.row, coords.col)); - } else if (selectedHeader.cols && coords.row < 0 && !blockCalculations.column) { - selection.setRangeEnd(new _src.CellCoords(actualSelection.to.row, coords.col)); - } else if (selectedHeader.rows && coords.col < 0 && !blockCalculations.row) { - selection.setRangeEnd(new _src.CellCoords(coords.row, actualSelection.to.col)); - } else if ((!selectedHeader.cols && !selectedHeader.rows && coords.col < 0 || selectedHeader.cols && coords.col < 0) && !blockCalculations.row) { - selection.setSelectedHeaders(true, false); - selection.setRangeStartOnly(new _src.CellCoords(actualSelection.from.row, 0)); - selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1)); - } else if ((!selectedHeader.cols && !selectedHeader.rows && coords.row < 0 || selectedHeader.rows && coords.row < 0) && !blockCalculations.column) { - selection.setSelectedHeaders(false, true); - selection.setRangeStartOnly(new _src.CellCoords(0, actualSelection.from.col)); - selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col)); - } - } else { - var doNewSelection = true; +"use strict"; - if (actualSelection) { - var from = actualSelection.from, - to = actualSelection.to; - var coordsNotInSelection = !selection.inInSelection(coords); +exports.__esModule = true; - if (coords.row < 0 && selectedHeader.cols) { - var start = Math.min(from.col, to.col); - var end = Math.max(from.col, to.col); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - doNewSelection = coords.col < start || coords.col > end; - } else if (coords.col < 0 && selectedHeader.rows) { - var _start = Math.min(from.row, to.row); - var _end = Math.max(from.row, to.row); +var _jsonPatchDuplex = __webpack_require__(179); - doNewSelection = coords.row < _start || coords.row > _end; - } else { - doNewSelection = coordsNotInSelection; - } - } +var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex); - var rightClick = (0, _event.isRightClick)(event); - var leftClick = (0, _event.isLeftClick)(event) || event.type === 'touchstart'; +var _localHooks = __webpack_require__(87); - // clicked row header and when some column was selected - if (coords.row < 0 && coords.col >= 0 && !blockCalculations.column) { - selection.setSelectedHeaders(false, true); +var _localHooks2 = _interopRequireDefault(_localHooks); - if (leftClick || rightClick && doNewSelection) { - selection.setRangeStartOnly(new _src.CellCoords(0, coords.col)); - selection.setRangeEnd(new _src.CellCoords(Math.max(instance.countRows() - 1, 0), coords.col), false); - } +var _object = __webpack_require__(1); - // clicked column header and when some row was selected - } else if (coords.col < 0 && coords.row >= 0 && !blockCalculations.row) { - selection.setSelectedHeaders(true, false); +var _utils = __webpack_require__(303); - if (leftClick || rightClick && doNewSelection) { - selection.setRangeStartOnly(new _src.CellCoords(coords.row, 0)); - selection.setRangeEnd(new _src.CellCoords(coords.row, Math.max(instance.countCols() - 1, 0)), false); - } - } else if (coords.col >= 0 && coords.row >= 0 && !blockCalculations.cells) { - if (leftClick || rightClick && doNewSelection) { - selection.setSelectedHeaders(false, false); - selection.setRangeStart(coords); - } - } else if (coords.col < 0 && coords.row < 0) { - coords.row = 0; - coords.col = 0; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - selection.setSelectedHeaders(false, false, true); - selection.setRangeStart(coords); - } - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - instance.runHooks('afterOnCellMouseDown', event, coords, TD); - that.activeWt = that.wt; - }, - onCellMouseOut: function onCellMouseOut(event, coords, TD, wt) { - that.activeWt = wt; - instance.runHooks('beforeOnCellMouseOut', event, coords, TD); +/** + * @class DataObserver + * @plugin ObserveChanges + */ +var DataObserver = function () { + function DataObserver(observedData) { + _classCallCheck(this, DataObserver); - if ((0, _event.isImmediatePropagationStopped)(event)) { - return; - } + /** + * Observed source data. + * + * @type {Array} + */ + this.observedData = null; + /** + * JsonPatch observer. + * + * @type {Object} + */ + this.observer = null; + /** + * Flag which determines if observer is paused or not. Paused observer doesn't emit `change` hooks. + * + * @type {Boolean} + * @default false + */ + this.paused = false; - instance.runHooks('afterOnCellMouseOut', event, coords, TD); - that.activeWt = that.wt; - }, - onCellMouseOver: function onCellMouseOver(event, coords, TD, wt) { - var blockCalculations = { - row: false, - column: false, - cell: false - }; + this.setObservedData(observedData); + } - that.activeWt = wt; - instance.runHooks('beforeOnCellMouseOver', event, coords, TD, blockCalculations); + /** + * Set data to observe. + * + * @param {*} observedData + */ - if ((0, _event.isImmediatePropagationStopped)(event)) { - return; - } - if (event.button === 0 && isMouseDown) { - if (coords.row >= 0 && coords.col >= 0) { - // is not a header - if (instance.selection.selectedHeader.cols && !blockCalculations.column) { - instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false); - } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) { - instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false); - } else if (!blockCalculations.cell) { - instance.selection.setRangeEnd(coords); - } - } else { - /* eslint-disable no-lonely-if */ - if (instance.selection.selectedHeader.cols && !blockCalculations.column) { - instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false); - } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) { - instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false); - } else if (!blockCalculations.cell) { - instance.selection.setRangeEnd(coords); - } - } + _createClass(DataObserver, [{ + key: 'setObservedData', + value: function setObservedData(observedData) { + var _this = this; + + if (this.observer) { + _jsonPatchDuplex2.default.unobserve(this.observedData, this.observer); } + this.observedData = observedData; + this.observer = _jsonPatchDuplex2.default.observe(this.observedData, function (patches) { + return _this.onChange(patches); + }); + } - instance.runHooks('afterOnCellMouseOver', event, coords, TD); - that.activeWt = that.wt; - }, - onCellMouseUp: function onCellMouseUp(event, coords, TD, wt) { - that.activeWt = wt; - instance.runHooks('beforeOnCellMouseUp', event, coords, TD); + /** + * Check if observer was paused. + * + * @returns {Boolean} + */ - instance.runHooks('afterOnCellMouseUp', event, coords, TD); - that.activeWt = that.wt; - }, - onCellCornerMouseDown: function onCellCornerMouseDown(event) { - event.preventDefault(); - instance.runHooks('afterOnCellCornerMouseDown', event); - }, - onCellCornerDblClick: function onCellCornerDblClick(event) { - event.preventDefault(); - instance.runHooks('afterOnCellCornerDblClick', event); - }, - beforeDraw: function beforeDraw(force, skipRender) { - that.beforeRender(force, skipRender); - }, - onDraw: function onDraw(force) { - that.onDraw(force); - }, - onScrollVertically: function onScrollVertically() { - instance.runHooks('afterScrollVertically'); - }, - onScrollHorizontally: function onScrollHorizontally() { - instance.runHooks('afterScrollHorizontally'); - }, - onBeforeDrawBorders: function onBeforeDrawBorders(corners, borderClassName) { - instance.runHooks('beforeDrawBorders', corners, borderClassName); - }, - onBeforeTouchScroll: function onBeforeTouchScroll() { - instance.runHooks('beforeTouchScroll'); - }, - onAfterMomentumScroll: function onAfterMomentumScroll() { - instance.runHooks('afterMomentumScroll'); - }, - onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(stretchedWidth, column) { - return instance.runHooks('beforeStretchingColumnWidth', stretchedWidth, column); - }, - onModifyRowHeaderWidth: function onModifyRowHeaderWidth(rowHeaderWidth) { - return instance.runHooks('modifyRowHeaderWidth', rowHeaderWidth); - }, - viewportRowCalculatorOverride: function viewportRowCalculatorOverride(calc) { - var rows = instance.countRows(); - var viewportOffset = that.settings.viewportRowRenderingOffset; + }, { + key: 'isPaused', + value: function isPaused() { + return this.paused; + } - if (viewportOffset === 'auto' && that.settings.fixedRowsTop) { - viewportOffset = 10; - } - if (typeof viewportOffset === 'number') { - calc.startRow = Math.max(calc.startRow - viewportOffset, 0); - calc.endRow = Math.min(calc.endRow + viewportOffset, rows - 1); - } - if (viewportOffset === 'auto') { - var center = calc.startRow + calc.endRow - calc.startRow; - var offset = Math.ceil(center / rows * 12); + /** + * Pause observer (stop emitting all detected changes). + */ - calc.startRow = Math.max(calc.startRow - offset, 0); - calc.endRow = Math.min(calc.endRow + offset, rows - 1); - } - instance.runHooks('afterViewportRowCalculatorOverride', calc); - }, - viewportColumnCalculatorOverride: function viewportColumnCalculatorOverride(calc) { - var cols = instance.countCols(); - var viewportOffset = that.settings.viewportColumnRenderingOffset; + }, { + key: 'pause', + value: function pause() { + this.paused = true; + } - if (viewportOffset === 'auto' && that.settings.fixedColumnsLeft) { - viewportOffset = 10; - } - if (typeof viewportOffset === 'number') { - calc.startColumn = Math.max(calc.startColumn - viewportOffset, 0); - calc.endColumn = Math.min(calc.endColumn + viewportOffset, cols - 1); - } - if (viewportOffset === 'auto') { - var center = calc.startColumn + calc.endColumn - calc.startColumn; - var offset = Math.ceil(center / cols * 12); + /** + * Resume observer (emit all detected changes). + */ - calc.startRow = Math.max(calc.startColumn - offset, 0); - calc.endColumn = Math.min(calc.endColumn + offset, cols - 1); - } - instance.runHooks('afterViewportColumnCalculatorOverride', calc); - }, - rowHeaderWidth: function rowHeaderWidth() { - return that.settings.rowHeaderWidth; - }, - columnHeaderHeight: function columnHeaderHeight() { - var columnHeaderHeight = instance.runHooks('modifyColumnHeaderHeight'); - return that.settings.columnHeaderHeight || columnHeaderHeight; + }, { + key: 'resume', + value: function resume() { + this.paused = false; } - }; - instance.runHooks('beforeInitWalkontable', walkontableConfig); + /** + * JsonPatch on change listener. + * + * @private + * @param {Array} patches An array of object passed from jsonpatch. + */ - this.wt = new _src2.default(walkontableConfig); - this.activeWt = this.wt; + }, { + key: 'onChange', + value: function onChange(patches) { + this.runLocalHooks('change', (0, _utils.cleanPatches)(patches)); + } - if (!(0, _browser.isChrome)() && !(0, _browser.isSafari)()) { - this.eventManager.addEventListener(instance.rootElement, 'wheel', function (event) { - event.preventDefault(); + /** + * Destroy observer instance. + */ - var lineHeight = parseInt((0, _element.getComputedStyle)(document.body)['font-size'], 10); - var holder = that.wt.wtOverlays.scrollableElement; + }, { + key: 'destroy', + value: function destroy() { + _jsonPatchDuplex2.default.unobserve(this.observedData, this.observer); + this.observedData = null; + this.observer = null; + } + }]); - var deltaY = event.wheelDeltaY || event.deltaY; - var deltaX = event.wheelDeltaX || event.deltaX; + return DataObserver; +}(); - switch (event.deltaMode) { - case 0: - holder.scrollLeft += deltaX; - holder.scrollTop += deltaY; - break; +(0, _object.mixin)(DataObserver, _localHooks2.default); - case 1: - holder.scrollLeft += deltaX * lineHeight; - holder.scrollTop += deltaY * lineHeight; - break; +exports.default = DataObserver; - default: - break; - } - }); - } +/***/ }), +/* 303 */ +/***/ (function(module, exports, __webpack_require__) { - this.eventManager.addEventListener(that.wt.wtTable.spreader, 'mousedown', function (event) { - // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar - if (event.target === that.wt.wtTable.spreader && event.which === 3) { - (0, _event.stopPropagation)(event); - } - }); +"use strict"; - this.eventManager.addEventListener(that.wt.wtTable.spreader, 'contextmenu', function (event) { - // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar - if (event.target === that.wt.wtTable.spreader && event.which === 3) { - (0, _event.stopPropagation)(event); - } - }); - this.eventManager.addEventListener(document.documentElement, 'click', function () { - if (that.settings.observeDOMVisibility) { - if (that.wt.drawInterrupted) { - that.instance.forceFullRender = true; - that.render(); - } - } - }); -} +exports.__esModule = true; -TableView.prototype.isTextSelectionAllowed = function (el) { - if ((0, _element.isInput)(el)) { - return true; - } - var isChildOfTableBody = (0, _element.isChildOf)(el, this.instance.view.wt.wtTable.spreader); +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - if (this.settings.fragmentSelection === true && isChildOfTableBody) { - return true; - } - if (this.settings.fragmentSelection === 'cell' && this.isSelectedOnlyCell() && isChildOfTableBody) { - return true; - } - if (!this.settings.fragmentSelection && this.isCellEdited() && this.isSelectedOnlyCell()) { - return true; - } +exports.cleanPatches = cleanPatches; +exports.parsePath = parsePath; - return false; -}; +var _array = __webpack_require__(2); /** - * Check if selected only one cell. + * Clean and extend patches from jsonpatch observer. * - * @returns {Boolean} + * @param {Array} patches + * @returns {Array} */ -TableView.prototype.isSelectedOnlyCell = function () { - var _ref = this.instance.getSelected() || [], - _ref2 = _slicedToArray(_ref, 4), - row = _ref2[0], - col = _ref2[1], - rowEnd = _ref2[2], - colEnd = _ref2[3]; +function cleanPatches(patches) { + var newOrRemovedColumns = []; - return row !== void 0 && row === rowEnd && col === colEnd; -}; + /** + * If observeChanges uses native Object.observe method, then it produces patches for length property. Filter them. + * If path can't be parsed. Filter it. + */ + patches = (0, _array.arrayFilter)(patches, function (patch) { + if (/[/]length/ig.test(patch.path)) { + return false; + } + if (!parsePath(patch.path)) { + return false; + } -TableView.prototype.isCellEdited = function () { - var activeEditor = this.instance.getActiveEditor(); + return true; + }); + /** + * Extend patches with changed cells coords + */ + patches = (0, _array.arrayMap)(patches, function (patch) { + var coords = parsePath(patch.path); - return activeEditor && activeEditor.isOpened(); -}; + patch.row = coords.row; + patch.col = coords.col; -TableView.prototype.beforeRender = function (force, skipRender) { - if (force) { - // this.instance.forceFullRender = did Handsontable request full render? - this.instance.runHooks('beforeRender', this.instance.forceFullRender, skipRender); - } -}; + return patch; + }); + /** + * Removing or adding column will produce one patch for each table row. + * Leaves only one patch for each column add/remove operation. + */ + patches = (0, _array.arrayFilter)(patches, function (patch) { + if (['add', 'remove'].indexOf(patch.op) !== -1 && !isNaN(patch.col)) { + if (newOrRemovedColumns.indexOf(patch.col) !== -1) { + return false; + } + newOrRemovedColumns.push(patch.col); + } -TableView.prototype.onDraw = function (force) { - if (force) { - // this.instance.forceFullRender = did Handsontable request full render? - this.instance.runHooks('afterRender', this.instance.forceFullRender); - } -}; + return true; + }); + newOrRemovedColumns.length = 0; -TableView.prototype.render = function () { - this.wt.draw(!this.instance.forceFullRender); - this.instance.forceFullRender = false; - this.instance.renderCall = false; -}; + return patches; +} /** - * Returns td object given coordinates + * Extract coordinates from path where data was changed. * - * @param {CellCoords} coords - * @param {Boolean} topmost + * @param {String} path Path describing where data was changed. + * @returns {Object|null} Returns an object with `row` and `col` properties or `null` if path doesn't have necessary information. */ -TableView.prototype.getCellAtCoords = function (coords, topmost) { - var td = this.wt.getCell(coords, topmost); +function parsePath(path) { + var match = path.match(/^\/(\d+)\/?(.*)?$/); - if (td < 0) { - // there was an exit code (cell is out of bounds) + if (!match) { return null; } - return td; -}; - -/** - * Scroll viewport to selection. - * - * @param {CellCoords} coords - */ -TableView.prototype.scrollViewport = function (coords) { - this.wt.scrollViewport(coords); -}; - -/** - * Append row header to a TH element - * @param row - * @param TH - */ -TableView.prototype.appendRowHeader = function (row, TH) { - if (TH.firstChild) { - var container = TH.firstChild; - - if (!(0, _element.hasClass)(container, 'relative')) { - (0, _element.empty)(TH); - this.appendRowHeader(row, TH); - - return; - } - this.updateCellHeader(container.querySelector('.rowHeader'), row, this.instance.getRowHeader); - } else { - var div = document.createElement('div'); - var span = document.createElement('span'); + var _match = _slicedToArray(match, 3), + row = _match[1], + column = _match[2]; - div.className = 'relative'; - span.className = 'rowHeader'; - this.updateCellHeader(span, row, this.instance.getRowHeader); + return { + row: parseInt(row, 10), + col: /^\d*$/.test(column) ? parseInt(column, 10) : column + }; +} - div.appendChild(span); - TH.appendChild(div); - } +/***/ }), +/* 304 */ +/***/ (function(module, exports, __webpack_require__) { - this.instance.runHooks('afterGetRowHeader', row, TH); -}; +"use strict"; -/** - * Append column header to a TH element - * @param col - * @param TH - */ -TableView.prototype.appendColHeader = function (col, TH) { - if (TH.firstChild) { - var container = TH.firstChild; - if ((0, _element.hasClass)(container, 'relative')) { - this.updateCellHeader(container.querySelector('.colHeader'), col, this.instance.getColHeader); - } else { - (0, _element.empty)(TH); - this.appendColHeader(col, TH); - } - } else { - var div = document.createElement('div'); - var span = document.createElement('span'); +exports.__esModule = true; - div.className = 'relative'; - span.className = 'colHeader'; - this.updateCellHeader(span, col, this.instance.getColHeader); +var _pluginHooks = __webpack_require__(7); - div.appendChild(span); - TH.appendChild(div); - } +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - this.instance.runHooks('afterGetColHeader', col, TH); -}; +var _plugins = __webpack_require__(5); -/** - * Update header cell content - * - * @since 0.15.0-beta4 - * @param {HTMLElement} element Element to update - * @param {Number} index Row index or column index - * @param {Function} content Function which should be returns content for this cell - */ -TableView.prototype.updateCellHeader = function (element, index, content) { - var renderedIndex = index; - var parentOverlay = this.wt.wtOverlays.getParentOverlay(element) || this.wt; +var _object = __webpack_require__(1); - // prevent wrong calculations from SampleGenerator - if (element.parentNode) { - if ((0, _element.hasClass)(element, 'colHeader')) { - renderedIndex = parentOverlay.wtTable.columnFilter.sourceToRendered(index); - } else if ((0, _element.hasClass)(element, 'rowHeader')) { - renderedIndex = parentOverlay.wtTable.rowFilter.sourceToRendered(index); - } - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (renderedIndex > -1) { - (0, _element.fastInnerHTML)(element, content(index)); - } else { - // workaround for https://github.com/handsontable/handsontable/issues/1946 - (0, _element.fastInnerText)(element, String.fromCharCode(160)); - (0, _element.addClass)(element, 'cornerHeader'); - } -}; +function Storage(prefix) { + var savedKeys; -/** - * Given a element's left position relative to the viewport, returns maximum element width until the right - * edge of the viewport (before scrollbar) - * - * @param {Number} leftOffset - * @return {Number} - */ -TableView.prototype.maximumVisibleElementWidth = function (leftOffset) { - var workspaceWidth = this.wt.wtViewport.getWorkspaceWidth(); - var maxWidth = workspaceWidth - leftOffset; - return maxWidth > 0 ? maxWidth : 0; -}; + var saveSavedKeys = function saveSavedKeys() { + window.localStorage[prefix + '__persistentStateKeys'] = JSON.stringify(savedKeys); + }; -/** - * Given a element's top position relative to the viewport, returns maximum element height until the bottom - * edge of the viewport (before scrollbar) - * - * @param {Number} topOffset - * @return {Number} - */ -TableView.prototype.maximumVisibleElementHeight = function (topOffset) { - var workspaceHeight = this.wt.wtViewport.getWorkspaceHeight(); - var maxHeight = workspaceHeight - topOffset; - return maxHeight > 0 ? maxHeight : 0; -}; + var loadSavedKeys = function loadSavedKeys() { + var keysJSON = window.localStorage[prefix + '__persistentStateKeys']; + var keys = typeof keysJSON == 'string' ? JSON.parse(keysJSON) : void 0; + savedKeys = keys ? keys : []; + }; -TableView.prototype.mainViewIsActive = function () { - return this.wt === this.activeWt; -}; + var clearSavedKeys = function clearSavedKeys() { + savedKeys = []; + saveSavedKeys(); + }; -TableView.prototype.destroy = function () { - this.wt.destroy(); - this.eventManager.destroy(); -}; + loadSavedKeys(); -exports.default = TableView; + this.saveValue = function (key, value) { + window.localStorage[prefix + '_' + key] = JSON.stringify(value); + if (savedKeys.indexOf(key) == -1) { + savedKeys.push(key); + saveSavedKeys(); + } + }; -/***/ }), -/* 272 */ -/***/ (function(module, exports, __webpack_require__) { + this.loadValue = function (key, defaultValue) { -"use strict"; + key = typeof key === 'undefined' ? defaultValue : key; + var value = window.localStorage[prefix + '_' + key]; -exports.__esModule = true; + return typeof value == 'undefined' ? void 0 : JSON.parse(value); + }; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + this.reset = function (key) { + window.localStorage.removeItem(prefix + '_' + key); + }; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + this.resetAll = function () { + for (var index = 0; index < savedKeys.length; index++) { + window.localStorage.removeItem(prefix + '_' + savedKeys[index]); + } -/** - * Refactored implementation of LinkedList (part of javascript-algorithms project) by Github users: - * mgechev, AndriiHeonia, Microfed and Jakeh (part of javascript-algorithms project - all project contributors - * at repository website) - * - * Link to repository: https://github.com/mgechev/javascript-algorithms - */ + clearSavedKeys(); + }; +} /** - * Linked list node. - * - * @class NodeStructure - * @util + * @private + * @class PersistentState + * @plugin PersistentState */ -var NodeStructure = function NodeStructure(data) { - _classCallCheck(this, NodeStructure); +function HandsontablePersistentState() { + var plugin = this; - /** - * Data of the node. - * @member {Object} - */ - this.data = data; - /** - * Next node. - * @member {NodeStructure} - */ - this.next = null; - /** - * Previous node. - * @member {NodeStructure} - */ - this.prev = null; -}; + this.init = function () { + var instance = this, + pluginSettings = instance.getSettings().persistentState; -/** - * Linked list. - * - * @class LinkedList - * @util - */ + plugin.enabled = !!pluginSettings; + if (!plugin.enabled) { + removeHooks.call(instance); + return; + } -var LinkedList = function () { - function LinkedList() { - _classCallCheck(this, LinkedList); + if (!instance.storage) { + instance.storage = new Storage(instance.rootElement.id); + } - this.first = null; - this.last = null; - } + instance.resetState = plugin.resetValue; - /** - * Add data to the end of linked list. - * - * @param {Object} data Data which should be added. - */ + addHooks.call(instance); + }; + this.saveValue = function (key, value) { + var instance = this; - _createClass(LinkedList, [{ - key: "push", - value: function push(data) { - var node = new NodeStructure(data); + instance.storage.saveValue(key, value); + }; - if (this.first === null) { - this.first = node; - this.last = node; - } else { - var temp = this.last; + this.loadValue = function (key, saveTo) { + var instance = this; - this.last = node; - node.prev = temp; - temp.next = node; - } - } + saveTo.value = instance.storage.loadValue(key); + }; - /** - * Add data to the beginning of linked list. - * - * @param {Object} data Data which should be added. - */ + this.resetValue = function (key) { + var instance = this; - }, { - key: "unshift", - value: function unshift(data) { - var node = new NodeStructure(data); + if (typeof key === 'undefined') { + instance.storage.resetAll(); + } else { + instance.storage.reset(key); + } + }; - if (this.first === null) { - this.first = node; - this.last = node; - } else { - var temp = this.first; + var hooks = { + persistentStateSave: plugin.saveValue, + persistentStateLoad: plugin.loadValue, + persistentStateReset: plugin.resetValue + }; - this.first = node; - node.next = temp; - temp.prev = node; - } + for (var hookName in hooks) { + if ((0, _object.hasOwnProperty)(hooks, hookName)) { + _pluginHooks2.default.getSingleton().register(hookName); } + } - /** - * In order traversal of the linked list. - * - * @param {Function} callback Callback which should be executed on each node. - */ - - }, { - key: "inorder", - value: function inorder(callback) { - var temp = this.first; + function addHooks() { + var instance = this; - while (temp) { - callback(temp); - temp = temp.next; + for (var hookName in hooks) { + if ((0, _object.hasOwnProperty)(hooks, hookName)) { + instance.addHook(hookName, hooks[hookName]); } } + } - /** - * Remove data from the linked list. - * - * @param {Object} data Data which should be removed. - * @returns {Boolean} Returns true if data has been removed. - */ + function removeHooks() { + var instance = this; - }, { - key: "remove", - value: function remove(data) { - if (this.first === null) { - return false; + for (var hookName in hooks) { + if ((0, _object.hasOwnProperty)(hooks, hookName)) { + instance.removeHook(hookName, hooks[hookName]); } + } + } +} - var temp = this.first; - var next = void 0; - var prev = void 0; +var htPersistentState = new HandsontablePersistentState(); - while (temp) { - if (temp.data === data) { - next = temp.next; - prev = temp.prev; +_pluginHooks2.default.getSingleton().add('beforeInit', htPersistentState.init); +_pluginHooks2.default.getSingleton().add('afterUpdateSettings', htPersistentState.init); - if (next) { - next.prev = prev; - } +exports.default = HandsontablePersistentState; - if (prev) { - prev.next = next; - } +/***/ }), +/* 305 */ +/***/ (function(module, exports, __webpack_require__) { - if (temp === this.first) { - this.first = next; - } +"use strict"; - if (temp === this.last) { - this.last = prev; - } - return true; - } +exports.__esModule = true; - temp = temp.next; - } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - return false; - } +var _pluginHooks = __webpack_require__(7); - /** - * Check if linked list contains cycle. - * - * @returns {Boolean} Returns true if linked list contains cycle. - */ +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); - }, { - key: "hasCycle", - value: function hasCycle() { - var fast = this.first; - var slow = this.first; +var _element = __webpack_require__(0); - while (true) { - if (fast === null) { - return false; - } +var _renderers = __webpack_require__(9); - fast = fast.next; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (fast === null) { - return false; - } +/** + * @private + * @plugin Search + */ +function Search(instance) { + this.query = function (queryStr, callback, queryMethod) { + var rowCount = instance.countRows(); + var colCount = instance.countCols(); + var queryResult = []; - fast = fast.next; - slow = slow.next; + if (!callback) { + callback = Search.global.getDefaultCallback(); + } - if (fast === slow) { - return true; - } - } + if (!queryMethod) { + queryMethod = Search.global.getDefaultQueryMethod(); } - }, { - key: "pop", + for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) { + for (var colIndex = 0; colIndex < colCount; colIndex++) { + var cellData = instance.getDataAtCell(rowIndex, colIndex); + var cellProperties = instance.getCellMeta(rowIndex, colIndex); + var cellCallback = cellProperties.search.callback || callback; + var cellQueryMethod = cellProperties.search.queryMethod || queryMethod; + var testResult = cellQueryMethod(queryStr, cellData); - /** - * Return last node from the linked list. - * - * @returns {NodeStructure} Last node. - */ - value: function pop() { - if (this.last === null) { - return null; - } + if (testResult) { + var singleResult = { + row: rowIndex, + col: colIndex, + data: cellData + }; - var temp = this.last; - this.last = this.last.prev; + queryResult.push(singleResult); + } - return temp; + if (cellCallback) { + cellCallback(instance, rowIndex, colIndex, cellData, testResult); + } + } } - }, { - key: "shift", - - /** - * Return first node from the linked list. - * - * @returns {NodeStructure} First node. - */ - value: function shift() { - if (this.first === null) { - return null; - } + return queryResult; + }; +}; - var temp = this.first; - this.first = this.first.next; +Search.DEFAULT_CALLBACK = function (instance, row, col, data, testResult) { + instance.getCellMeta(row, col).isSearchResult = testResult; +}; - return temp; - } - }, { - key: "recursiveReverse", +Search.DEFAULT_QUERY_METHOD = function (query, value) { + if (typeof query == 'undefined' || query == null || !query.toLowerCase || query.length === 0) { + return false; + } + if (typeof value == 'undefined' || value == null) { + return false; + } + return value.toString().toLowerCase().indexOf(query.toLowerCase()) != -1; +}; - /** - * Reverses the linked list recursively - */ - value: function recursiveReverse() { - function inverse(current, next) { - if (!next) { - return; - } - inverse(next, next.next); - next.next = current; - } +Search.DEFAULT_SEARCH_RESULT_CLASS = 'htSearchResult'; - if (!this.first) { - return; - } +Search.global = function () { - inverse(this.first, this.first.next); + var defaultCallback = Search.DEFAULT_CALLBACK; + var defaultQueryMethod = Search.DEFAULT_QUERY_METHOD; + var defaultSearchResultClass = Search.DEFAULT_SEARCH_RESULT_CLASS; - this.first.next = null; - var temp = this.first; - this.first = this.last; - this.last = temp; + return { + getDefaultCallback: function getDefaultCallback() { + return defaultCallback; + }, + setDefaultCallback: function setDefaultCallback(newDefaultCallback) { + defaultCallback = newDefaultCallback; + }, + getDefaultQueryMethod: function getDefaultQueryMethod() { + return defaultQueryMethod; + }, + setDefaultQueryMethod: function setDefaultQueryMethod(newDefaultQueryMethod) { + defaultQueryMethod = newDefaultQueryMethod; + }, + getDefaultSearchResultClass: function getDefaultSearchResultClass() { + return defaultSearchResultClass; + }, + setDefaultSearchResultClass: function setDefaultSearchResultClass(newSearchResultClass) { + defaultSearchResultClass = newSearchResultClass; } - }, { - key: "reverse", + }; +}(); +function SearchCellDecorator(instance, TD, row, col, prop, value, cellProperties) { + var searchResultClass = cellProperties.search !== null && _typeof(cellProperties.search) == 'object' && cellProperties.search.searchResultClass || Search.global.getDefaultSearchResultClass(); - /** - * Reverses the linked list iteratively - */ - value: function reverse() { - if (!this.first || !this.first.next) { - return; - } + if (cellProperties.isSearchResult) { + (0, _element.addClass)(TD, searchResultClass); + } else { + (0, _element.removeClass)(TD, searchResultClass); + } +}; - var current = this.first.next; - var prev = this.first; - var temp = void 0; +var originalBaseRenderer = (0, _renderers.getRenderer)('base'); - while (current) { - temp = current.next; - current.next = prev; - prev.prev = current; - prev = current; - current = temp; - } +(0, _renderers.registerRenderer)('base', function (instance, TD, row, col, prop, value, cellProperties) { + originalBaseRenderer.apply(this, arguments); + SearchCellDecorator.apply(this, arguments); +}); - this.first.next = null; - this.last.prev = null; - temp = this.first; - this.first = prev; - this.last = temp; - } - }]); +function init() { + var instance = this; - return LinkedList; -}(); + var pluginEnabled = !!instance.getSettings().search; -; + if (pluginEnabled) { + instance.search = new Search(instance); + } else { + delete instance.search; + } +} -exports.NodeStructure = NodeStructure; -exports.default = LinkedList; +_pluginHooks2.default.getSingleton().add('afterInit', init); +_pluginHooks2.default.getSingleton().add('afterUpdateSettings', init); + +exports.default = Search; /***/ }), -/* 273 */ +/* 306 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64974,974 +65259,911 @@ exports.__esModule = true; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -exports.parseDelay = parseDelay; +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _element = __webpack_require__(0); + +var _array = __webpack_require__(2); + +var _base = __webpack_require__(13); + +var _base2 = _interopRequireDefault(_base); + +var _plugins = __webpack_require__(5); var _feature = __webpack_require__(34); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + /** - * @class Interval - * @util + * @private + * @plugin TouchScroll + * @class TouchScroll */ -var Interval = function () { - _createClass(Interval, null, [{ - key: 'create', - value: function create(func, delay) { - return new Interval(func, delay); - } - }]); - - function Interval(func, delay) { - var _this = this; +var TouchScroll = function (_BasePlugin) { + _inherits(TouchScroll, _BasePlugin); - _classCallCheck(this, Interval); + function TouchScroll(hotInstance) { + _classCallCheck(this, TouchScroll); /** - * Animation frame request id. + * Collection of scrollbars to update. * - * @type {Number} + * @type {Array} */ - this.timer = null; + var _this = _possibleConstructorReturn(this, (TouchScroll.__proto__ || Object.getPrototypeOf(TouchScroll)).call(this, hotInstance)); + + _this.scrollbars = []; /** - * Function to invoke repeatedly. + * Collection of overlays to update. * - * @type {Function} + * @type {Array} */ - this.func = func; + _this.clones = []; /** - * Number of milliseconds that function should wait before next call. + * Flag which determines if collection of overlays should be refilled on every table render. + * + * @type {Boolean} + * @default false */ - this.delay = parseDelay(delay); + _this.lockedCollection = false; /** - * Flag which indicates if interval object was stopped. + * Flag which determines if walkontable should freeze overlays while scrolling. * * @type {Boolean} - * @default true + * @default false */ - this.stopped = true; + _this.freezeOverlays = false; + return _this; + } + + /** + * Check if plugin is enabled. + * + * @returns {Boolean} + */ + + + _createClass(TouchScroll, [{ + key: 'isEnabled', + value: function isEnabled() { + return (0, _feature.isTouchSupported)(); + } + /** - * Interval time (in milliseconds) of the last callback call. + * Enable the plugin. + */ + + }, { + key: 'enablePlugin', + value: function enablePlugin() { + var _this2 = this; + + if (this.enabled) { + return; + } + + this.addHook('afterRender', function () { + return _this2.onAfterRender(); + }); + this.registerEvents(); + + _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'enablePlugin', this).call(this); + } + + /** + * Updates the plugin to use the latest options you have specified. + */ + + }, { + key: 'updatePlugin', + value: function updatePlugin() { + this.lockedCollection = false; + + _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'updatePlugin', this).call(this); + } + + /** + * Disable plugin for this Handsontable instance. + */ + + }, { + key: 'disablePlugin', + value: function disablePlugin() { + _get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'disablePlugin', this).call(this); + } + + /** + * Register all necessary events. * * @private - * @type {Number} */ - this._then = null; + + }, { + key: 'registerEvents', + value: function registerEvents() { + var _this3 = this; + + this.addHook('beforeTouchScroll', function () { + return _this3.onBeforeTouchScroll(); + }); + this.addHook('afterMomentumScroll', function () { + return _this3.onAfterMomentumScroll(); + }); + } + /** - * Bounded function `func`. + * After render listener. * * @private - * @type {Function} */ - this._callback = function () { - return _this.__callback(); - }; - } - /** - * Start loop. - * - * @returns {Interval} - */ + }, { + key: 'onAfterRender', + value: function onAfterRender() { + if (this.lockedCollection) { + return; + } + var _hot$view$wt$wtOverla = this.hot.view.wt.wtOverlays, + topOverlay = _hot$view$wt$wtOverla.topOverlay, + bottomOverlay = _hot$view$wt$wtOverla.bottomOverlay, + leftOverlay = _hot$view$wt$wtOverla.leftOverlay, + topLeftCornerOverlay = _hot$view$wt$wtOverla.topLeftCornerOverlay, + bottomLeftCornerOverlay = _hot$view$wt$wtOverla.bottomLeftCornerOverlay; - _createClass(Interval, [{ - key: 'start', - value: function start() { - if (this.stopped) { - this._then = Date.now(); - this.stopped = false; - this.timer = (0, _feature.requestAnimationFrame)(this._callback); + + this.lockedCollection = true; + this.scrollbars.length = 0; + this.scrollbars.push(topOverlay); + + if (bottomOverlay.clone) { + this.scrollbars.push(bottomOverlay); + } + this.scrollbars.push(leftOverlay); + + if (topLeftCornerOverlay) { + this.scrollbars.push(topLeftCornerOverlay); + } + if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) { + this.scrollbars.push(bottomLeftCornerOverlay); } - return this; + this.clones.length = 0; + + if (topOverlay.needFullRender) { + this.clones.push(topOverlay.clone.wtTable.holder.parentNode); + } + if (bottomOverlay.needFullRender) { + this.clones.push(bottomOverlay.clone.wtTable.holder.parentNode); + } + if (leftOverlay.needFullRender) { + this.clones.push(leftOverlay.clone.wtTable.holder.parentNode); + } + if (topLeftCornerOverlay) { + this.clones.push(topLeftCornerOverlay.clone.wtTable.holder.parentNode); + } + if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) { + this.clones.push(bottomLeftCornerOverlay.clone.wtTable.holder.parentNode); + } } /** - * Stop looping. + * Touch scroll listener. * - * @returns {Interval} + * @private */ }, { - key: 'stop', - value: function stop() { - if (!this.stopped) { - this.stopped = true; - (0, _feature.cancelAnimationFrame)(this.timer); - this.timer = null; - } + key: 'onBeforeTouchScroll', + value: function onBeforeTouchScroll() { + this.freezeOverlays = true; - return this; + (0, _array.arrayEach)(this.clones, function (clone) { + (0, _element.addClass)(clone, 'hide-tween'); + }); } /** - * Loop callback, fired on every animation frame. + * After momentum scroll listener. * * @private */ - }, { - key: '__callback', - value: function __callback() { - this.timer = (0, _feature.requestAnimationFrame)(this._callback); + }, { + key: 'onAfterMomentumScroll', + value: function onAfterMomentumScroll() { + var _this4 = this; + + this.freezeOverlays = false; + + (0, _array.arrayEach)(this.clones, function (clone) { + (0, _element.removeClass)(clone, 'hide-tween'); + (0, _element.addClass)(clone, 'show-tween'); + }); + + setTimeout(function () { + (0, _array.arrayEach)(_this4.clones, function (clone) { + (0, _element.removeClass)(clone, 'show-tween'); + }); + }, 400); - if (this.delay) { - var now = Date.now(); - var elapsed = now - this._then; + (0, _array.arrayEach)(this.scrollbars, function (scrollbar) { + scrollbar.refresh(); + scrollbar.resetFixedPosition(); + }); - if (elapsed > this.delay) { - this._then = now - elapsed % this.delay; - this.func(); - } - } else { - this.func(); - } + this.hot.view.wt.wtOverlays.syncScrollWithMaster(); } }]); - return Interval; -}(); + return TouchScroll; +}(_base2.default); -exports.default = Interval; -function parseDelay(delay) { - if (typeof delay === 'string' && /fps$/.test(delay)) { - delay = 1000 / parseInt(delay.replace('fps', '') || 0, 10); - } +(0, _plugins.registerPlugin)('touchScroll', TouchScroll); - return delay; -} +exports.default = TouchScroll; /***/ }), -/* 274 */ +/* 307 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.__esModule = true; -exports.default = mergeSort; -exports.merge = merge; +var _pluginHooks = __webpack_require__(7); -var _linkedList = __webpack_require__(272); +var _pluginHooks2 = _interopRequireDefault(_pluginHooks); -var _linkedList2 = _interopRequireDefault(_linkedList); +var _array = __webpack_require__(2); + +var _number = __webpack_require__(6); + +var _object = __webpack_require__(1); + +var _event = __webpack_require__(8); + +var _src = __webpack_require__(12); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** - * Refactored implementation of mergeSort (part of javascript-algorithms project) by Github users: - * mgechev, AndriiHeonia and lekkas (part of javascript-algorithms project - all project contributors - * at repository website) + * @description + * Handsontable UndoRedo plugin. It allows to undo and redo certain actions done in the table. + * Please note, that not all actions are currently undo-able. * - * Link to repository: https://github.com/mgechev/javascript-algorithms + * @example + * ```js + * ... + * undo: true + * ... + * ``` + * @class UndoRedo + * @plugin UndoRedo */ - /** - * Specifies a function that defines the sort order. The array is sorted according to each - * character's Unicode code point value, according to the string conversion of each element. - * - * @param a {*} first compared element. - * @param b {*} second compared element. - * @returns {Number} + * Handsontable UndoRedo class */ -var defaultCompareFunction = function defaultCompareFunction(a, b) { - // sort lexically +function UndoRedo(instance) { + var plugin = this; + this.instance = instance; + this.doneActions = []; + this.undoneActions = []; + this.ignoreNewActions = false; - var firstValue = a.toString(); - var secondValue = b.toString(); + instance.addHook('afterChange', function (changes, source) { + if (changes && source !== 'UndoRedo.undo' && source !== 'UndoRedo.redo') { + plugin.done(new UndoRedo.ChangeAction(changes)); + } + }); - if (firstValue === secondValue) { - return 0; - } else if (firstValue < secondValue) { - return -1; - } - return 1; -}; + instance.addHook('afterCreateRow', function (index, amount, source) { + if (source === 'UndoRedo.undo' || source === 'UndoRedo.undo' || source === 'auto') { + return; + } -/** - * Mergesort method which is recursively called for sorting the input array. - * - * @param {Array} array The array which should be sorted. - * @param {Function} compareFunction Compares two items in an array. If compareFunction is not supplied, - * elements are sorted by converting them to strings and comparing strings in Unicode code point order. - * @param {Number} startIndex Left side of the subarray. - * @param {Number} endIndex Right side of the subarray. - * @returns {Array} Array with sorted subarray. - */ -function mergeSort(array) { - var compareFunction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultCompareFunction; - var startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - var endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length; + var action = new UndoRedo.CreateRowAction(index, amount); + plugin.done(action); + }); - if (Math.abs(endIndex - startIndex) <= 1) { - return []; - } + instance.addHook('beforeRemoveRow', function (index, amount, logicRows, source) { + if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') { + return; + } - var middleIndex = Math.ceil((startIndex + endIndex) / 2); + var originalData = plugin.instance.getSourceDataArray(); - mergeSort(array, compareFunction, startIndex, middleIndex); - mergeSort(array, compareFunction, middleIndex, endIndex); + index = (originalData.length + index) % originalData.length; - return merge(array, compareFunction, startIndex, middleIndex, endIndex); -} + var removedData = (0, _object.deepClone)(originalData.slice(index, index + amount)); -/** - * Devides and sort merges two subarrays of given array - * - * @param {Array} array The array which subarrays should be sorted. - * @param {Number} startIndex The start of the first subarray. - * This subarray is with end middle - 1. - * @param {Number} middleIndex The start of the second array. - * @param {Number} endIndex end - 1 is the end of the second array. - * @returns {Array} The array with sorted subarray. - */ -function merge(array, compareFunction, startIndex, middleIndex, endIndex) { - var leftElements = new _linkedList2.default(); - var rightElements = new _linkedList2.default(); - var leftSize = middleIndex - startIndex; - var rightSize = endIndex - middleIndex; - var maxSize = Math.max(leftSize, rightSize); - var size = endIndex - startIndex; + plugin.done(new UndoRedo.RemoveRowAction(index, removedData)); + }); - for (var _i = 0; _i < maxSize; _i += 1) { - if (_i < leftSize) { - leftElements.push(array[startIndex + _i]); + instance.addHook('afterCreateCol', function (index, amount, source) { + if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') { + return; } - if (_i < rightSize) { - rightElements.push(array[middleIndex + _i]); + plugin.done(new UndoRedo.CreateColumnAction(index, amount)); + }); + + instance.addHook('beforeRemoveCol', function (index, amount, logicColumns, source) { + if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') { + return; } - } - var i = 0; + var originalData = plugin.instance.getSourceDataArray(); - while (i < size) { - if (leftElements.first && rightElements.first) { - if (compareFunction(leftElements.first.data, rightElements.first.data) > 0) { - array[startIndex + i] = rightElements.shift().data; - } else { - array[startIndex + i] = leftElements.shift().data; - } - } else if (leftElements.first) { + index = (plugin.instance.countCols() + index) % plugin.instance.countCols(); - array[startIndex + i] = leftElements.shift().data; - } else { + var removedData = []; + var headers = []; + var indexes = []; - array[startIndex + i] = rightElements.shift().data; - } + (0, _number.rangeEach)(originalData.length - 1, function (i) { + var column = []; + var origRow = originalData[i]; - i += 1; - } + (0, _number.rangeEach)(index, index + (amount - 1), function (j) { + column.push(origRow[instance.runHooks('modifyCol', j)]); + }); + removedData.push(column); + }); - return array; -}; + (0, _number.rangeEach)(amount - 1, function (i) { + indexes.push(instance.runHooks('modifyCol', index + i)); + }); -/***/ }), -/* 275 */ -/***/ (function(module, exports, __webpack_require__) { + if (Array.isArray(instance.getSettings().colHeaders)) { + (0, _number.rangeEach)(amount - 1, function (i) { + headers.push(instance.getSettings().colHeaders[instance.runHooks('modifyCol', index + i)] || null); + }); + } -"use strict"; + var manualColumnMovePlugin = plugin.instance.getPlugin('manualColumnMove'); + var columnsMap = manualColumnMovePlugin.isEnabled() ? manualColumnMovePlugin.columnsMapper.__arrayMap : []; + var action = new UndoRedo.RemoveColumnAction(index, indexes, removedData, headers, columnsMap); -exports.__esModule = true; -exports.default = autocompleteValidator; -/** - * Autocomplete cell validator. - * - * @private - * @validator AutocompleteValidator - * @param {*} value - Value of edited cell - * @param {Function} callback - Callback called with validation result - */ -function autocompleteValidator(value, callback) { - if (value == null) { - value = ''; - } + plugin.done(action); + }); - if (this.allowEmpty && value === '') { - callback(true); + instance.addHook('beforeCellAlignment', function (stateBefore, range, type, alignment) { + var action = new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment); + plugin.done(action); + }); - return; - } + instance.addHook('beforeFilter', function (conditionsStack) { + plugin.done(new UndoRedo.FiltersAction(conditionsStack)); + }); - if (this.strict && this.source) { - if (typeof this.source === 'function') { - this.source(value, process(value, callback)); - } else { - process(value, callback)(this.source); + instance.addHook('beforeRowMove', function (movedRows, target) { + if (movedRows === false) { + return; } - } else { - callback(true); + + plugin.done(new UndoRedo.RowMoveAction(movedRows, target)); + }); +}; + +UndoRedo.prototype.done = function (action) { + if (!this.ignoreNewActions) { + this.doneActions.push(action); + this.undoneActions.length = 0; } }; /** - * Function responsible for validation of autocomplete value. + * Undo last edit. * - * @param {*} value - Value of edited cell - * @param {Function} callback - Callback called with validation result + * @function undo + * @memberof UndoRedo# */ -function process(value, callback) { - var originalVal = value; +UndoRedo.prototype.undo = function () { + if (this.isUndoAvailable()) { + var action = this.doneActions.pop(); + var actionClone = (0, _object.deepClone)(action); + var instance = this.instance; - return function (source) { - var found = false; + var continueAction = instance.runHooks('beforeUndo', actionClone); - for (var s = 0, slen = source.length; s < slen; s++) { - if (originalVal === source[s]) { - found = true; // perfect match - break; - } + if (continueAction === false) { + return; } - callback(found); - }; -} - -/***/ }), -/* 276 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.default = dateValidator; -exports.correctFormat = correctFormat; - -var _moment = __webpack_require__(61); - -var _moment2 = _interopRequireDefault(_moment); - -var _date = __webpack_require__(89); - -var _editors = __webpack_require__(14); + this.ignoreNewActions = true; + var that = this; + action.undo(this.instance, function () { + that.ignoreNewActions = false; + that.undoneActions.push(action); + }); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + instance.runHooks('afterUndo', actionClone); + } +}; /** - * Date cell validator + * Redo edit (used to reverse an undo). * - * @private - * @validator DateValidator - * @dependencies moment - * @param {*} value - Value of edited cell - * @param {Function} callback - Callback called with validation result + * @function redo + * @memberof UndoRedo# */ -function dateValidator(value, callback) { - var valid = true; - var dateEditor = (0, _editors.getEditorInstance)('date', this.instance); +UndoRedo.prototype.redo = function () { + if (this.isRedoAvailable()) { + var action = this.undoneActions.pop(); + var actionClone = (0, _object.deepClone)(action); + var instance = this.instance; - if (value == null) { - value = ''; - } - var isValidDate = (0, _moment2.default)(new Date(value)).isValid() || (0, _moment2.default)(value, dateEditor.defaultDateFormat).isValid(); - // is it in the specified format - var isValidFormat = (0, _moment2.default)(value, this.dateFormat || dateEditor.defaultDateFormat, true).isValid(); + var continueAction = instance.runHooks('beforeRedo', actionClone); - if (this.allowEmpty && value === '') { - isValidDate = true; - isValidFormat = true; - } - if (!isValidDate) { - valid = false; - } - if (!isValidDate && isValidFormat) { - valid = true; - } + if (continueAction === false) { + return; + } - if (isValidDate && !isValidFormat) { - if (this.correctFormat === true) { - // if format correction is enabled - var correctedValue = correctFormat(value, this.dateFormat); - var row = this.instance.runHooks('unmodifyRow', this.row); - var column = this.instance.runHooks('unmodifyCol', this.col); + this.ignoreNewActions = true; + var that = this; + action.redo(this.instance, function () { + that.ignoreNewActions = false; + that.doneActions.push(action); + }); - this.instance.setDataAtCell(row, column, correctedValue, 'dateValidator'); - valid = true; - } else { - valid = false; - } + instance.runHooks('afterRedo', actionClone); } - - callback(valid); }; /** - * Format the given string using moment.js' format feature + * Check if undo action is available. * - * @param {String} value - * @param {String} dateFormat - * @returns {String} + * @function isUndoAvailable + * @memberof UndoRedo# + * @return {Boolean} Return `true` if undo can be performed, `false` otherwise */ -function correctFormat(value, dateFormat) { - var dateFromDate = (0, _moment2.default)((0, _date.getNormalizedDate)(value)); - var dateFromMoment = (0, _moment2.default)(value, dateFormat); - var isAlphanumeric = value.search(/[A-z]/g) > -1; - var date = void 0; - - if (dateFromDate.isValid() && dateFromDate.format('x') === dateFromMoment.format('x') || !dateFromMoment.isValid() || isAlphanumeric) { - date = dateFromDate; - } else { - date = dateFromMoment; - } - - return date.format(dateFormat); +UndoRedo.prototype.isUndoAvailable = function () { + return this.doneActions.length > 0; }; -/***/ }), -/* 277 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.default = numericValidator; /** - * Numeric cell validator + * Check if redo action is available. * - * @private - * @validator NumericValidator - * @param {*} value - Value of edited cell - * @param {*} callback - Callback called with validation result + * @function isRedoAvailable + * @memberof UndoRedo# + * @return {Boolean} Return `true` if redo can be performed, `false` otherwise. */ -function numericValidator(value, callback) { - if (value == null) { - value = ''; - } - if (this.allowEmpty && value === '') { - callback(true); - } else if (value === '') { - callback(false); - } else { - callback(/^-?\d*(\.|,)?\d*$/.test(value)); - } +UndoRedo.prototype.isRedoAvailable = function () { + return this.undoneActions.length > 0; }; -/***/ }), -/* 278 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.default = timeValidator; - -var _moment = __webpack_require__(61); - -var _moment2 = _interopRequireDefault(_moment); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Formats which are correctly parsed to time (supported by momentjs) -var STRICT_FORMATS = ['YYYY-MM-DDTHH:mm:ss.SSSZ', 'X', // Unix timestamp -'x' // Unix ms timestamp -]; - /** - * Time cell validator + * Clears undo history. * - * @private - * @validator TimeValidator - * @dependencies moment - * @param {*} value - Value of edited cell - * @param {Function} callback - Callback called with validation result + * @function clear + * @memberof UndoRedo# */ -function timeValidator(value, callback) { - var valid = true; - var timeFormat = this.timeFormat || 'h:mm:ss a'; - - if (value === null) { - value = ''; - } - - value = /^\d{3,}$/.test(value) ? parseInt(value, 10) : value; - - var twoDigitValue = /^\d{1,2}$/.test(value); - - if (twoDigitValue) { - value += ':00'; - } - - var date = (0, _moment2.default)(value, STRICT_FORMATS, true).isValid() ? (0, _moment2.default)(value) : (0, _moment2.default)(value, timeFormat); - var isValidTime = date.isValid(); - - // is it in the specified format - var isValidFormat = (0, _moment2.default)(value, timeFormat, true).isValid() && !twoDigitValue; - - if (this.allowEmpty && value === '') { - isValidTime = true; - isValidFormat = true; - } - if (!isValidTime) { - valid = false; - } - if (!isValidTime && isValidFormat) { - valid = true; - } - if (isValidTime && !isValidFormat) { - if (this.correctFormat === true) { - // if format correction is enabled - var correctedValue = date.format(timeFormat); - var row = this.instance.runHooks('unmodifyRow', this.row); - var column = this.instance.runHooks('unmodifyCol', this.col); - - this.instance.setDataAtCell(row, column, correctedValue, 'timeValidator'); - valid = true; - } else { - valid = false; - } - } - - callback(valid); +UndoRedo.prototype.clear = function () { + this.doneActions.length = 0; + this.undoneActions.length = 0; }; -/***/ }), -/* 279 */ -/***/ (function(module, exports, __webpack_require__) { +UndoRedo.Action = function () {}; +UndoRedo.Action.prototype.undo = function () {}; +UndoRedo.Action.prototype.redo = function () {}; + +/** + * Change action. + */ +UndoRedo.ChangeAction = function (changes) { + this.changes = changes; + this.actionType = 'change'; +}; +(0, _object.inherit)(UndoRedo.ChangeAction, UndoRedo.Action); -"use strict"; -// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length) +UndoRedo.ChangeAction.prototype.undo = function (instance, undoneCallback) { + var data = (0, _object.deepClone)(this.changes), + emptyRowsAtTheEnd = instance.countEmptyRows(true), + emptyColsAtTheEnd = instance.countEmptyCols(true); -var toObject = __webpack_require__(41) - , toIndex = __webpack_require__(59) - , toLength = __webpack_require__(24); - -module.exports = [].copyWithin || function copyWithin(target/*= 0*/, start/*= 0, end = @length*/){ - var O = toObject(this) - , len = toLength(O.length) - , to = toIndex(target, len) - , from = toIndex(start, len) - , end = arguments.length > 2 ? arguments[2] : undefined - , count = Math.min((end === undefined ? len : toIndex(end, len)) - from, len - to) - , inc = 1; - if(from < to && to < from + count){ - inc = -1; - from += count - 1; - to += count - 1; + for (var i = 0, len = data.length; i < len; i++) { + data[i].splice(3, 1); } - while(count-- > 0){ - if(from in O)O[to] = O[from]; - else delete O[to]; - to += inc; - from += inc; - } return O; -}; -/***/ }), -/* 280 */ -/***/ (function(module, exports, __webpack_require__) { + instance.addHookOnce('afterChange', undoneCallback); -"use strict"; -// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length) + instance.setDataAtRowProp(data, null, null, 'UndoRedo.undo'); -var toObject = __webpack_require__(41) - , toIndex = __webpack_require__(59) - , toLength = __webpack_require__(24); -module.exports = function fill(value /*, start = 0, end = @length */){ - var O = toObject(this) - , length = toLength(O.length) - , aLen = arguments.length - , index = toIndex(aLen > 1 ? arguments[1] : undefined, length) - , end = aLen > 2 ? arguments[2] : undefined - , endPos = end === undefined ? length : toIndex(end, length); - while(endPos > index)O[index++] = value; - return O; -}; + for (var _i = 0, _len = data.length; _i < _len; _i++) { + if (instance.getSettings().minSpareRows && data[_i][0] + 1 + instance.getSettings().minSpareRows === instance.countRows() && emptyRowsAtTheEnd == instance.getSettings().minSpareRows) { -/***/ }), -/* 281 */ -/***/ (function(module, exports, __webpack_require__) { + instance.alter('remove_row', parseInt(data[_i][0] + 1, 10), instance.getSettings().minSpareRows); + instance.undoRedo.doneActions.pop(); + } -var isObject = __webpack_require__(15) - , isArray = __webpack_require__(163) - , SPECIES = __webpack_require__(10)('species'); + if (instance.getSettings().minSpareCols && data[_i][1] + 1 + instance.getSettings().minSpareCols === instance.countCols() && emptyColsAtTheEnd == instance.getSettings().minSpareCols) { -module.exports = function(original){ - var C; - if(isArray(original)){ - C = original.constructor; - // cross-realm fallback - if(typeof C == 'function' && (C === Array || isArray(C.prototype)))C = undefined; - if(isObject(C)){ - C = C[SPECIES]; - if(C === null)C = undefined; + instance.alter('remove_col', parseInt(data[_i][1] + 1, 10), instance.getSettings().minSpareCols); + instance.undoRedo.doneActions.pop(); } - } return C === undefined ? Array : C; + } }; +UndoRedo.ChangeAction.prototype.redo = function (instance, onFinishCallback) { + var data = (0, _object.deepClone)(this.changes); -/***/ }), -/* 282 */ -/***/ (function(module, exports, __webpack_require__) { - -// 9.4.2.3 ArraySpeciesCreate(originalArray, length) -var speciesConstructor = __webpack_require__(281); + for (var i = 0, len = data.length; i < len; i++) { + data[i].splice(2, 1); + } -module.exports = function(original, length){ - return new (speciesConstructor(original))(length); + instance.addHookOnce('afterChange', onFinishCallback); + instance.setDataAtRowProp(data, null, null, 'UndoRedo.redo'); }; -/***/ }), -/* 283 */ -/***/ (function(module, exports, __webpack_require__) { - -// all enumerable object keys, includes symbols -var getKeys = __webpack_require__(39) - , gOPS = __webpack_require__(57) - , pIE = __webpack_require__(47); -module.exports = function(it){ - var result = getKeys(it) - , getSymbols = gOPS.f; - if(getSymbols){ - var symbols = getSymbols(it) - , isEnum = pIE.f - , i = 0 - , key; - while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key); - } return result; +/** + * Create row action. + */ +UndoRedo.CreateRowAction = function (index, amount) { + this.index = index; + this.amount = amount; + this.actionType = 'insert_row'; }; +(0, _object.inherit)(UndoRedo.CreateRowAction, UndoRedo.Action); -/***/ }), -/* 284 */ -/***/ (function(module, exports, __webpack_require__) { +UndoRedo.CreateRowAction.prototype.undo = function (instance, undoneCallback) { + var rowCount = instance.countRows(), + minSpareRows = instance.getSettings().minSpareRows; -"use strict"; + if (this.index >= rowCount && this.index - minSpareRows < rowCount) { + this.index -= minSpareRows; // work around the situation where the needed row was removed due to an 'undo' of a made change + } -// 21.2.5.3 get RegExp.prototype.flags -var anObject = __webpack_require__(18); -module.exports = function(){ - var that = anObject(this) - , result = ''; - if(that.global) result += 'g'; - if(that.ignoreCase) result += 'i'; - if(that.multiline) result += 'm'; - if(that.unicode) result += 'u'; - if(that.sticky) result += 'y'; - return result; + instance.addHookOnce('afterRemoveRow', undoneCallback); + instance.alter('remove_row', this.index, this.amount, 'UndoRedo.undo'); +}; +UndoRedo.CreateRowAction.prototype.redo = function (instance, redoneCallback) { + instance.addHookOnce('afterCreateRow', redoneCallback); + instance.alter('insert_row', this.index, this.amount, 'UndoRedo.redo'); }; -/***/ }), -/* 285 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Remove row action. + */ +UndoRedo.RemoveRowAction = function (index, data) { + this.index = index; + this.data = data; + this.actionType = 'remove_row'; +}; +(0, _object.inherit)(UndoRedo.RemoveRowAction, UndoRedo.Action); -var isObject = __webpack_require__(15) - , setPrototypeOf = __webpack_require__(172).set; -module.exports = function(that, target, C){ - var P, S = target.constructor; - if(S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf){ - setPrototypeOf(that, P); - } return that; +UndoRedo.RemoveRowAction.prototype.undo = function (instance, undoneCallback) { + instance.alter('insert_row', this.index, this.data.length, 'UndoRedo.undo'); + instance.addHookOnce('afterRender', undoneCallback); + instance.populateFromArray(this.index, 0, this.data, void 0, void 0, 'UndoRedo.undo'); +}; +UndoRedo.RemoveRowAction.prototype.redo = function (instance, redoneCallback) { + instance.addHookOnce('afterRemoveRow', redoneCallback); + instance.alter('remove_row', this.index, this.data.length, 'UndoRedo.redo'); }; -/***/ }), -/* 286 */ -/***/ (function(module, exports) { +/** + * Create column action. + */ +UndoRedo.CreateColumnAction = function (index, amount) { + this.index = index; + this.amount = amount; + this.actionType = 'insert_col'; +}; +(0, _object.inherit)(UndoRedo.CreateColumnAction, UndoRedo.Action); -// fast apply, http://jsperf.lnkit.com/fast-apply/5 -module.exports = function(fn, args, that){ - var un = that === undefined; - switch(args.length){ - case 0: return un ? fn() - : fn.call(that); - case 1: return un ? fn(args[0]) - : fn.call(that, args[0]); - case 2: return un ? fn(args[0], args[1]) - : fn.call(that, args[0], args[1]); - case 3: return un ? fn(args[0], args[1], args[2]) - : fn.call(that, args[0], args[1], args[2]); - case 4: return un ? fn(args[0], args[1], args[2], args[3]) - : fn.call(that, args[0], args[1], args[2], args[3]); - } return fn.apply(that, args); +UndoRedo.CreateColumnAction.prototype.undo = function (instance, undoneCallback) { + instance.addHookOnce('afterRemoveCol', undoneCallback); + instance.alter('remove_col', this.index, this.amount, 'UndoRedo.undo'); +}; +UndoRedo.CreateColumnAction.prototype.redo = function (instance, redoneCallback) { + instance.addHookOnce('afterCreateCol', redoneCallback); + instance.alter('insert_col', this.index, this.amount, 'UndoRedo.redo'); }; -/***/ }), -/* 287 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Remove column action. + */ +UndoRedo.RemoveColumnAction = function (index, indexes, data, headers, columnPositions) { + this.index = index; + this.indexes = indexes; + this.data = data; + this.amount = this.data[0].length; + this.headers = headers; + this.columnPositions = columnPositions.slice(0); + this.actionType = 'remove_col'; +}; +(0, _object.inherit)(UndoRedo.RemoveColumnAction, UndoRedo.Action); -"use strict"; +UndoRedo.RemoveColumnAction.prototype.undo = function (instance, undoneCallback) { + var _this = this; -var create = __webpack_require__(79) - , descriptor = __webpack_require__(40) - , setToStringTag = __webpack_require__(48) - , IteratorPrototype = {}; + var row = void 0; + var ascendingIndexes = this.indexes.slice(0).sort(); + var sortByIndexes = function sortByIndexes(elem, j, arr) { + return arr[_this.indexes.indexOf(ascendingIndexes[j])]; + }; -// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() -__webpack_require__(32)(IteratorPrototype, __webpack_require__(10)('iterator'), function(){ return this; }); + var sortedData = []; + (0, _number.rangeEach)(this.data.length - 1, function (i) { + sortedData[i] = (0, _array.arrayMap)(_this.data[i], sortByIndexes); + }); -module.exports = function(Constructor, NAME, next){ - Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)}); - setToStringTag(Constructor, NAME + ' Iterator'); -}; + var sortedHeaders = []; + sortedHeaders = (0, _array.arrayMap)(this.headers, sortByIndexes); -/***/ }), -/* 288 */ -/***/ (function(module, exports, __webpack_require__) { + var changes = []; -var getKeys = __webpack_require__(39) - , toIObject = __webpack_require__(23); -module.exports = function(object, el){ - var O = toIObject(object) - , keys = getKeys(O) - , length = keys.length - , index = 0 - , key; - while(length > index)if(O[key = keys[index++]] === el)return key; -}; + // TODO: Temporary hook for undo/redo mess + instance.runHooks('beforeCreateCol', this.indexes[0], this.indexes[this.indexes.length - 1], 'UndoRedo.undo'); -/***/ }), -/* 289 */ -/***/ (function(module, exports, __webpack_require__) { + (0, _number.rangeEach)(this.data.length - 1, function (i) { + row = instance.getSourceDataAtRow(i); -var global = __webpack_require__(13) - , macrotask = __webpack_require__(85).set - , Observer = global.MutationObserver || global.WebKitMutationObserver - , process = global.process - , Promise = global.Promise - , isNode = __webpack_require__(38)(process) == 'process'; + (0, _number.rangeEach)(ascendingIndexes.length - 1, function (j) { + row.splice(ascendingIndexes[j], 0, sortedData[i][j]); + changes.push([i, ascendingIndexes[j], null, sortedData[i][j]]); + }); + }); -module.exports = function(){ - var head, last, notify; + // TODO: Temporary hook for undo/redo mess + if (instance.getPlugin('formulas')) { + instance.getPlugin('formulas').onAfterSetDataAtCell(changes); + } - var flush = function(){ - var parent, fn; - if(isNode && (parent = process.domain))parent.exit(); - while(head){ - fn = head.fn; - head = head.next; - try { - fn(); - } catch(e){ - if(head)notify(); - else last = undefined; - throw e; - } - } last = undefined; - if(parent)parent.enter(); - }; + if (typeof this.headers !== 'undefined') { + (0, _number.rangeEach)(sortedHeaders.length - 1, function (j) { + instance.getSettings().colHeaders.splice(ascendingIndexes[j], 0, sortedHeaders[j]); + }); + } - // Node.js - if(isNode){ - notify = function(){ - process.nextTick(flush); - }; - // browsers with MutationObserver - } else if(Observer){ - var toggle = true - , node = document.createTextNode(''); - new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new - notify = function(){ - node.data = toggle = !toggle; - }; - // environments with maybe non-completely correct, but existent Promise - } else if(Promise && Promise.resolve){ - var promise = Promise.resolve(); - notify = function(){ - promise.then(flush); - }; - // for other environments - macrotask based on: - // - setImmediate - // - MessageChannel - // - window.postMessag - // - onreadystatechange - // - setTimeout - } else { - notify = function(){ - // strange IE + webpack dev server bug - use .call(global) - macrotask.call(global, flush); - }; + if (instance.getPlugin('manualColumnMove')) { + instance.getPlugin('manualColumnMove').columnsMapper.__arrayMap = this.columnPositions; } - return function(fn){ - var task = {fn: fn, next: undefined}; - if(last)last.next = task; - if(!head){ - head = task; - notify(); - } last = task; - }; -}; + instance.addHookOnce('afterRender', undoneCallback); -/***/ }), -/* 290 */ -/***/ (function(module, exports, __webpack_require__) { + // TODO: Temporary hook for undo/redo mess + instance.runHooks('afterCreateCol', this.indexes[0], this.indexes[this.indexes.length - 1], 'UndoRedo.undo'); -var dP = __webpack_require__(19) - , anObject = __webpack_require__(18) - , getKeys = __webpack_require__(39); + if (instance.getPlugin('formulas')) { + instance.getPlugin('formulas').recalculateFull(); + } -module.exports = __webpack_require__(21) ? Object.defineProperties : function defineProperties(O, Properties){ - anObject(O); - var keys = getKeys(Properties) - , length = keys.length - , i = 0 - , P; - while(length > i)dP.f(O, P = keys[i++], Properties[P]); - return O; + instance.render(); }; -/***/ }), -/* 291 */ -/***/ (function(module, exports, __webpack_require__) { - -// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window -var toIObject = __webpack_require__(23) - , gOPN = __webpack_require__(81).f - , toString = {}.toString; - -var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames - ? Object.getOwnPropertyNames(window) : []; +UndoRedo.RemoveColumnAction.prototype.redo = function (instance, redoneCallback) { + instance.addHookOnce('afterRemoveCol', redoneCallback); + instance.alter('remove_col', this.index, this.amount, 'UndoRedo.redo'); +}; -var getWindowNames = function(it){ - try { - return gOPN(it); - } catch(e){ - return windowNames.slice(); +/** + * Cell alignment action. + */ +UndoRedo.CellAlignmentAction = function (stateBefore, range, type, alignment) { + this.stateBefore = stateBefore; + this.range = range; + this.type = type; + this.alignment = alignment; +}; +UndoRedo.CellAlignmentAction.prototype.undo = function (instance, undoneCallback) { + if (!instance.getPlugin('contextMenu').isEnabled()) { + return; + } + for (var row = this.range.from.row; row <= this.range.to.row; row++) { + for (var col = this.range.from.col; col <= this.range.to.col; col++) { + instance.setCellMeta(row, col, 'className', this.stateBefore[row][col] || ' htLeft'); + } } + + instance.addHookOnce('afterRender', undoneCallback); + instance.render(); }; +UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback) { + if (!instance.getPlugin('contextMenu').isEnabled()) { + return; + } + instance.selectCell(this.range.from.row, this.range.from.col, this.range.to.row, this.range.to.col); + instance.getPlugin('contextMenu').executeCommand('alignment:' + this.alignment.replace('ht', '').toLowerCase()); -module.exports.f = function getOwnPropertyNames(it){ - return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it)); + instance.addHookOnce('afterRender', undoneCallback); + instance.render(); }; +/** + * Filters action. + */ +UndoRedo.FiltersAction = function (conditionsStack) { + this.conditionsStack = conditionsStack; + this.actionType = 'filter'; +}; +(0, _object.inherit)(UndoRedo.FiltersAction, UndoRedo.Action); -/***/ }), -/* 292 */ -/***/ (function(module, exports, __webpack_require__) { +UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) { + var filters = instance.getPlugin('filters'); -// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) -var has = __webpack_require__(22) - , toObject = __webpack_require__(41) - , IE_PROTO = __webpack_require__(82)('IE_PROTO') - , ObjectProto = Object.prototype; + instance.addHookOnce('afterRender', undoneCallback); -module.exports = Object.getPrototypeOf || function(O){ - O = toObject(O); - if(has(O, IE_PROTO))return O[IE_PROTO]; - if(typeof O.constructor == 'function' && O instanceof O.constructor){ - return O.constructor.prototype; - } return O instanceof Object ? ObjectProto : null; + filters.conditionCollection.importAllConditions(this.conditionsStack.slice(0, this.conditionsStack.length - 1)); + filters.filter(); }; +UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) { + var filters = instance.getPlugin('filters'); -/***/ }), -/* 293 */ -/***/ (function(module, exports, __webpack_require__) { + instance.addHookOnce('afterRender', redoneCallback); -// all object keys, includes non-enumerable and symbols -var gOPN = __webpack_require__(81) - , gOPS = __webpack_require__(57) - , anObject = __webpack_require__(18) - , Reflect = __webpack_require__(13).Reflect; -module.exports = Reflect && Reflect.ownKeys || function ownKeys(it){ - var keys = gOPN.f(anObject(it)) - , getSymbols = gOPS.f; - return getSymbols ? keys.concat(getSymbols(it)) : keys; + filters.conditionCollection.importAllConditions(this.conditionsStack); + filters.filter(); }; -/***/ }), -/* 294 */ -/***/ (function(module, exports) { - -// 7.2.9 SameValue(x, y) -module.exports = Object.is || function is(x, y){ - return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y; +/** + * ManualRowMove action. + * @TODO: removeRow undo should works on logical index + */ +UndoRedo.RowMoveAction = function (movedRows, target) { + this.rows = movedRows.slice(); + this.target = target; }; +(0, _object.inherit)(UndoRedo.RowMoveAction, UndoRedo.Action); -/***/ }), -/* 295 */ -/***/ (function(module, exports, __webpack_require__) { +UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) { + var manualRowMove = instance.getPlugin('manualRowMove'); -// 7.3.20 SpeciesConstructor(O, defaultConstructor) -var anObject = __webpack_require__(18) - , aFunction = __webpack_require__(72) - , SPECIES = __webpack_require__(10)('species'); -module.exports = function(O, D){ - var C = anObject(O).constructor, S; - return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); -}; + instance.addHookOnce('afterRender', undoneCallback); + var mod = this.rows[0] < this.target ? -1 * this.rows.length : 0; + var newTarget = this.rows[0] > this.target ? this.rows[0] + this.rows.length : this.rows[0]; + var newRows = []; + var rowsLen = this.rows.length + mod; -/***/ }), -/* 296 */ -/***/ (function(module, exports, __webpack_require__) { + for (var i = mod; i < rowsLen; i++) { + newRows.push(this.target + i); + } + manualRowMove.moveRows(newRows.slice(), newTarget); + instance.render(); -var toInteger = __webpack_require__(60) - , defined = __webpack_require__(30); -// true -> String#at -// false -> String#codePointAt -module.exports = function(TO_STRING){ - return function(that, pos){ - var s = String(defined(that)) - , i = toInteger(pos) - , l = s.length - , a, b; - if(i < 0 || i >= l)return TO_STRING ? '' : undefined; - a = s.charCodeAt(i); - return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff - ? TO_STRING ? s.charAt(i) : a - : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; - }; + instance.selection.setRangeStartOnly(new _src.CellCoords(this.rows[0], 0)); + instance.selection.setRangeEnd(new _src.CellCoords(this.rows[this.rows.length - 1], instance.countCols() - 1)); }; +UndoRedo.RowMoveAction.prototype.redo = function (instance, redoneCallback) { + var manualRowMove = instance.getPlugin('manualRowMove'); -/***/ }), -/* 297 */ -/***/ (function(module, exports, __webpack_require__) { - -var global = __webpack_require__(13) - , core = __webpack_require__(44) - , LIBRARY = __webpack_require__(56) - , wksExt = __webpack_require__(176) - , defineProperty = __webpack_require__(19).f; -module.exports = function(name){ - var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {}); - if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)}); + instance.addHookOnce('afterRender', redoneCallback); + manualRowMove.moveRows(this.rows.slice(), this.target); + instance.render(); + var startSelection = this.rows[0] < this.target ? this.target - this.rows.length : this.target; + instance.selection.setRangeStartOnly(new _src.CellCoords(startSelection, 0)); + instance.selection.setRangeEnd(new _src.CellCoords(startSelection + this.rows.length - 1, instance.countCols() - 1)); }; -/***/ }), -/* 298 */ -/***/ (function(module, exports) { +function init() { + var instance = this; + var pluginEnabled = typeof instance.getSettings().undo == 'undefined' || instance.getSettings().undo; -// removed by extract-text-webpack-plugin + if (pluginEnabled) { + if (!instance.undoRedo) { + /** + * Instance of Handsontable.UndoRedo Plugin {@link Handsontable.UndoRedo} + * + * @alias undoRedo + * @memberof! Handsontable.Core# + * @type {UndoRedo} + */ + instance.undoRedo = new UndoRedo(instance); -/***/ }), -/* 299 */ -/***/ (function(module, exports) { + exposeUndoRedoMethods(instance); -// removed by extract-text-webpack-plugin + instance.addHook('beforeKeyDown', onBeforeKeyDown); + instance.addHook('afterChange', onAfterChange); + } + } else if (instance.undoRedo) { + delete instance.undoRedo; -/***/ }), -/* 300 */ -/***/ (function(module, exports) { + removeExposedUndoRedoMethods(instance); -// removed by extract-text-webpack-plugin + instance.removeHook('beforeKeyDown', onBeforeKeyDown); + instance.removeHook('afterChange', onAfterChange); + } +} -/***/ }), -/* 301 */ -/***/ (function(module, exports) { +function onBeforeKeyDown(event) { + var instance = this; -// removed by extract-text-webpack-plugin + var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; -/***/ }), -/* 302 */ -/***/ (function(module, exports) { + if (ctrlDown) { + if (event.keyCode === 89 || event.shiftKey && event.keyCode === 90) { + // CTRL + Y or CTRL + SHIFT + Z + instance.undoRedo.redo(); + (0, _event.stopImmediatePropagation)(event); + } else if (event.keyCode === 90) { + // CTRL + Z + instance.undoRedo.undo(); + (0, _event.stopImmediatePropagation)(event); + } + } +} -// removed by extract-text-webpack-plugin +function onAfterChange(changes, source) { + var instance = this; + if (source === 'loadData') { + return instance.undoRedo.clear(); + } +} -/***/ }), -/* 303 */ -/***/ (function(module, exports) { +function exposeUndoRedoMethods(instance) { + /** + * {@link UndoRedo#undo} + * @alias undo + * @memberof! Handsontable.Core# + */ + instance.undo = function () { + return instance.undoRedo.undo(); + }; -// removed by extract-text-webpack-plugin + /** + * {@link UndoRedo#redo} + * @alias redo + * @memberof! Handsontable.Core# + */ + instance.redo = function () { + return instance.undoRedo.redo(); + }; -/***/ }), -/* 304 */ -/***/ (function(module, exports) { + /** + * {@link UndoRedo#isUndoAvailable} + * @alias isUndoAvailable + * @memberof! Handsontable.Core# + */ + instance.isUndoAvailable = function () { + return instance.undoRedo.isUndoAvailable(); + }; + + /** + * {@link UndoRedo#isRedoAvailable} + * @alias isRedoAvailable + * @memberof! Handsontable.Core# + */ + instance.isRedoAvailable = function () { + return instance.undoRedo.isRedoAvailable(); + }; + + /** + * {@link UndoRedo#clear} + * @alias clearUndo + * @memberof! Handsontable.Core# + */ + instance.clearUndo = function () { + return instance.undoRedo.clear(); + }; +} + +function removeExposedUndoRedoMethods(instance) { + delete instance.undo; + delete instance.redo; + delete instance.isUndoAvailable; + delete instance.isRedoAvailable; + delete instance.clearUndo; +} + +var hook = _pluginHooks2.default.getSingleton(); -module.exports = __WEBPACK_EXTERNAL_MODULE_304__; +hook.add('afterInit', init); +hook.add('afterUpdateSettings', init); + +hook.register('beforeUndo'); +hook.register('afterUndo'); +hook.register('beforeRedo'); +hook.register('afterRedo'); /***/ }) -/******/ ]); +/******/ ])["default"]; }); //# sourceMappingURL=handsontable.js.map diff --git a/package.json b/package.json index 03b0dc7..9836eca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-handsontable", - "version": "1.0.0-beta1", + "version": "1.0.0-beta2", "description": "Official Angular 2 directive for Handsontable", "repository": { "type": "git",