From ad3789b11dcb90e64f357a5d260701a241b49a45 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Wed, 15 Nov 2017 20:49:00 -0800 Subject: [PATCH 01/20] Update to AdaptiveCards 1.0 --- package-lock.json | 678 +++++++++++++++++------------- package.json | 2 +- src/AdaptiveCardContainer.tsx | 9 +- src/CardBuilder.tsx | 2 +- src/adaptivecards-hostconfig.d.ts | 2 +- webpack.config.js | 2 +- webpack.production.config.js | 2 +- 7 files changed, 386 insertions(+), 311 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe7b8d447f..83d2155095 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,6 +82,12 @@ "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", "dev": true }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + }, "acorn-dynamic-import": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", @@ -99,14 +105,24 @@ } } }, + "adaptivecards": { + "version": "1.0.0-beta2", + "resolved": "https://registry.npmjs.org/adaptivecards/-/adaptivecards-1.0.0-beta2.tgz", + "integrity": "sha512-0U6rUDxMHCNI74WZGoz3lEn/HIFjvggqftB3UIiiYgaKbQF3CDy8sEia4qTF2RI5zeHhtaGzqQurpbiZGD+QDQ==", + "requires": { + "markdown-it": "8.3.1" + } + }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", + "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", "dev": true, "requires": { "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ajv-keywords": { @@ -254,9 +270,9 @@ } }, "aproba": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", - "integrity": "sha1-RcZikJTeTpb2k+9+q3SuB5wkD8E=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, "are-we-there-yet": { @@ -325,12 +341,12 @@ "dev": true }, "asn1.js": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", - "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", "dev": true, "requires": { - "bn.js": "4.11.7", + "bn.js": "4.11.8", "inherits": "2.0.3", "minimalistic-assert": "1.0.0" } @@ -345,9 +361,9 @@ } }, "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "assertion-error": { @@ -387,18 +403,18 @@ "dev": true, "requires": { "colors": "1.1.2", - "enhanced-resolve": "3.3.0", + "enhanced-resolve": "3.4.1", "loader-utils": "1.1.0", "lodash": "4.17.4", "mkdirp": "0.5.1", "object-assign": "4.1.1", - "source-map-support": "0.4.15" + "source-map-support": "0.4.18" } }, "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "aws4": { @@ -457,18 +473,18 @@ "dev": true }, "bn.js": { - "version": "4.11.7", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.7.tgz", - "integrity": "sha1-3bBI5Q2UgnkAlME+s/z8gzznq0Y=", + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "4.2.0" } }, "botframework-directlinejs": { @@ -502,16 +518,17 @@ "dev": true }, "browserify-aes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", - "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "dev": true, "requires": { "buffer-xor": "1.0.3", - "cipher-base": "1.0.3", + "cipher-base": "1.0.4", "create-hash": "1.1.3", - "evp_bytestokey": "1.0.0", - "inherits": "2.0.3" + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "browserify-cipher": { @@ -520,9 +537,9 @@ "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "dev": true, "requires": { - "browserify-aes": "1.0.6", + "browserify-aes": "1.1.1", "browserify-des": "1.0.0", - "evp_bytestokey": "1.0.0" + "evp_bytestokey": "1.0.3" } }, "browserify-des": { @@ -531,7 +548,7 @@ "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", "dev": true, "requires": { - "cipher-base": "1.0.3", + "cipher-base": "1.0.4", "des.js": "1.0.0", "inherits": "2.0.3" } @@ -542,7 +559,7 @@ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "bn.js": "4.11.7", + "bn.js": "4.11.8", "randombytes": "2.0.5" } }, @@ -552,7 +569,7 @@ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "bn.js": "4.11.7", + "bn.js": "4.11.8", "browserify-rsa": "4.0.1", "create-hash": "1.1.3", "create-hmac": "1.1.6", @@ -562,12 +579,12 @@ } }, "browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "pako": "0.2.9" + "pako": "1.0.6" } }, "buffer": { @@ -695,12 +712,13 @@ } }, "cipher-base": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", - "integrity": "sha1-7qvxlEGc6QDaMBjCB9IS8qbfCgc=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "cliui": { @@ -732,9 +750,9 @@ } }, "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", "dev": true }, "co": { @@ -812,7 +830,7 @@ "moment": "2.19.3", "rx": "2.3.24", "spawn-default-shell": "1.1.0", - "tree-kill": "1.1.0" + "tree-kill": "1.2.0" } }, "configstore": { @@ -883,7 +901,7 @@ "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", "dev": true, "requires": { - "bn.js": "4.11.7", + "bn.js": "4.11.8", "elliptic": "6.4.0" } }, @@ -893,10 +911,10 @@ "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", "dev": true, "requires": { - "cipher-base": "1.0.3", + "cipher-base": "1.0.4", "inherits": "2.0.3", "ripemd160": "2.0.1", - "sha.js": "2.4.8" + "sha.js": "2.4.9" } }, "create-hmac": { @@ -905,12 +923,12 @@ "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", "dev": true, "requires": { - "cipher-base": "1.0.3", + "cipher-base": "1.0.4", "create-hash": "1.1.3", "inherits": "2.0.3", "ripemd160": "2.0.1", "safe-buffer": "5.1.1", - "sha.js": "2.4.8" + "sha.js": "2.4.9" } }, "create-react-class": { @@ -934,18 +952,29 @@ } }, "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "dev": true, "requires": { - "boom": "2.10.1" + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + } } }, "crypto-browserify": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.0.tgz", - "integrity": "sha1-NlKgkGq5sqfgw85mpAjpV6JIVSI=", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { "browserify-cipher": "1.0.0", @@ -955,9 +984,10 @@ "create-hmac": "1.1.6", "diffie-hellman": "5.0.2", "inherits": "2.0.3", - "pbkdf2": "3.0.12", + "pbkdf2": "3.0.14", "public-encrypt": "4.0.0", - "randombytes": "2.0.5" + "randombytes": "2.0.5", + "randomfill": "1.0.3" } }, "css-color-names": { @@ -1077,7 +1107,7 @@ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "clone": "1.0.2" + "clone": "1.0.3" } }, "define-properties": { @@ -1126,8 +1156,8 @@ "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "dev": true, "requires": { - "bn.js": "4.11.7", - "miller-rabin": "4.0.0", + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", "randombytes": "2.0.5" } }, @@ -1166,20 +1196,20 @@ } }, "electron": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/electron/-/electron-1.6.11.tgz", - "integrity": "sha1-vnnA69zv7bW/KBF0CYAPpTus7/o=", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/electron/-/electron-1.7.9.tgz", + "integrity": "sha1-rdVOn4+D7QL2UZ7BATX2mLGTNs8=", "dev": true, "requires": { - "@types/node": "7.0.33", + "@types/node": "7.0.48", "electron-download": "3.3.0", - "extract-zip": "1.6.5" + "extract-zip": "1.6.6" }, "dependencies": { "@types/node": { - "version": "7.0.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.33.tgz", - "integrity": "sha512-8fVvl6Yyk3jZvSYxRMS9/AmZJ5RXCOP9N4xSlykyBViVESu751pxHYTN14Embn1Fem78YwEHdC7p7KGQQpwunw==", + "version": "7.0.48", + "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.48.tgz", + "integrity": "sha512-LLlXafM3BD52MH056tHxTXO8JFCnpJJQkdzIU3+m8ew+CXJY/5zIXgDNb4TK/QFvlI8QexLS5tL+sE0Qhegr1w==", "dev": true } } @@ -1203,7 +1233,7 @@ "dependencies": { "fs-extra": { "version": "0.30.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "dev": true, "requires": { @@ -1228,7 +1258,7 @@ "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "dev": true, "requires": { - "bn.js": "4.11.7", + "bn.js": "4.11.8", "brorand": "1.1.0", "hash.js": "1.1.3", "hmac-drbg": "1.0.1", @@ -1272,15 +1302,15 @@ } }, "enhanced-resolve": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.3.0.tgz", - "integrity": "sha1-lQlk7MfwMypCMhtnOzjcj/FVNbM=", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", "dev": true, "requires": { "graceful-fs": "4.1.11", "memory-fs": "0.4.1", "object-assign": "4.1.1", - "tapable": "0.2.6" + "tapable": "0.2.8" } }, "enqueue": { @@ -1386,12 +1416,13 @@ "dev": true }, "evp_bytestokey": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", - "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "create-hash": "1.1.3" + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" } }, "expand-range": { @@ -1458,24 +1489,32 @@ "dev": true }, "extract-zip": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz", - "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=", + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", "dev": true, "requires": { "concat-stream": "1.6.0", - "debug": "2.2.0", + "debug": "2.6.9", "mkdirp": "0.5.0", "yauzl": "2.4.1" }, "dependencies": { "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "mkdirp": { @@ -1490,15 +1529,26 @@ "ms": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" } } }, "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, "fbjs": { @@ -1575,9 +1625,9 @@ "dev": true }, "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", "dev": true, "requires": { "asynckit": "0.4.0", @@ -1593,7 +1643,7 @@ }, "fs-extra": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", "dev": true, "requires": { @@ -2542,7 +2592,7 @@ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "requires": { - "aproba": "1.1.2", + "aproba": "1.2.0", "console-control-strings": "1.1.0", "has-unicode": "2.0.1", "object-assign": "4.1.1", @@ -2612,20 +2662,12 @@ "dev": true, "requires": { "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -2711,19 +2753,19 @@ "dev": true }, "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "5.3.0", + "har-schema": "2.0.0" } }, "has": { @@ -2776,15 +2818,15 @@ } }, "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "dev": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" } }, "hmac-drbg": { @@ -2799,9 +2841,9 @@ } }, "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", "dev": true }, "hoist-non-react-statics": { @@ -2903,20 +2945,20 @@ } }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", + "assert-plus": "1.0.0", + "jsprim": "1.4.1", "sshpk": "1.13.1" } }, "https-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", - "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, "i": { @@ -2998,9 +3040,9 @@ "dev": true }, "interpret": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", + "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", "dev": true }, "invariant": { @@ -3245,9 +3287,9 @@ "dev": true }, "js-base64": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", - "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", + "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==", "dev": true }, "js-tokens": { @@ -3269,9 +3311,9 @@ "dev": true }, "json-loader": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.4.tgz", - "integrity": "sha1-i6oTZaYy9Yo8RtIBdfxgAsluN94=", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", "dev": true }, "json-schema": { @@ -3280,6 +3322,12 @@ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -3329,15 +3377,15 @@ "dev": true }, "jsprim": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", - "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { "assert-plus": "1.0.0", - "extsprintf": "1.0.2", + "extsprintf": "1.3.0", "json-schema": "0.2.3", - "verror": "1.3.6" + "verror": "1.10.0" }, "dependencies": { "assert-plus": { @@ -3603,7 +3651,7 @@ "lru-cache": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha1-Yi4y6CSItJJ5EUpPns9F581rulU=", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", "dev": true, "requires": { "pseudomap": "1.0.2", @@ -3634,6 +3682,28 @@ "uc.micro": "1.0.3" } }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -3675,14 +3745,6 @@ } } }, - "microsoft-adaptivecards": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/microsoft-adaptivecards/-/microsoft-adaptivecards-0.6.1.tgz", - "integrity": "sha512-TYNgO+DkXskpr+sspyiwcchaB/zh//is3BRCA5YtmjS0OeZCAlRZ3k1vzJfC639w/Ci+zft+MbIA/p6BuVbGEg==", - "requires": { - "markdown-it": "8.3.1" - } - }, "microsoft-adaptivecards-scss-to-json": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/microsoft-adaptivecards-scss-to-json/-/microsoft-adaptivecards-scss-to-json-1.2.0.tgz", @@ -3792,16 +3854,12 @@ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", "dev": true, "requires": { - "aws-sign2": "0.6.0", "aws4": "1.6.0", "caseless": "0.11.0", "combined-stream": "1.0.5", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.1.4", "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", @@ -3809,7 +3867,7 @@ "oauth-sign": "0.8.2", "qs": "6.3.2", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", + "tough-cookie": "2.3.3", "tunnel-agent": "0.4.3", "uuid": "3.1.0" } @@ -3843,12 +3901,12 @@ "integrity": "sha1-+n2NE9t6nGjRz+6YqWCrqHuBpiI=" }, "miller-rabin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", - "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { - "bn.js": "4.11.7", + "bn.js": "4.11.8", "brorand": "1.1.0" } }, @@ -3888,7 +3946,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "1.1.8" @@ -4045,7 +4103,7 @@ "debug": "2.6.8", "deep-defaults": "1.0.4", "defaults": "1.0.3", - "electron": "1.6.11", + "electron": "1.7.9", "enqueue": "1.0.2", "function-source": "0.1.0", "jsesc": "0.5.0", @@ -4054,7 +4112,7 @@ "once": "1.4.0", "rimraf": "2.6.1", "sliced": "1.0.1", - "split2": "2.1.1" + "split2": "2.2.0" } }, "nightmare-upload": { @@ -4099,7 +4157,7 @@ "nopt": "3.0.6", "npmlog": "4.1.2", "osenv": "0.1.4", - "request": "2.81.0", + "request": "2.83.0", "rimraf": "2.6.1", "semver": "5.3.0", "tar": "2.2.1", @@ -4107,21 +4165,21 @@ } }, "node-libs-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", - "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "dev": true, "requires": { "assert": "1.4.1", - "browserify-zlib": "0.1.4", + "browserify-zlib": "0.2.0", "buffer": "4.9.1", "console-browserify": "1.1.0", "constants-browserify": "1.0.0", - "crypto-browserify": "3.11.0", + "crypto-browserify": "3.12.0", "domain-browser": "1.1.7", "events": "1.1.1", - "https-browserify": "0.0.1", - "os-browserify": "0.2.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", "path-browserify": "0.0.0", "process": "0.11.10", "punycode": "1.4.1", @@ -4129,20 +4187,12 @@ "readable-stream": "2.3.3", "stream-browserify": "2.0.1", "stream-http": "2.7.2", - "string_decoder": "0.10.31", - "timers-browserify": "2.0.2", + "string_decoder": "1.0.3", + "timers-browserify": "2.0.4", "tty-browserify": "0.0.0", "url": "0.11.0", "util": "0.10.3", "vm-browserify": "0.0.4" - }, - "dependencies": { - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } } }, "node-sass": { @@ -4166,7 +4216,7 @@ "nan": "2.6.2", "node-gyp": "3.6.2", "npmlog": "4.1.2", - "request": "2.81.0", + "request": "2.83.0", "sass-graph": "2.2.4", "stdout-stream": "1.4.0" }, @@ -4379,7 +4429,7 @@ "minimist": "1.2.0", "pretty-bytes": "1.0.4", "progress-stream": "1.2.0", - "request": "2.81.0", + "request": "2.83.0", "single-line-log": "1.1.2", "throttleit": "0.0.2" }, @@ -4451,9 +4501,9 @@ } }, "os-browserify": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", - "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "os-homedir": { @@ -4498,9 +4548,9 @@ } }, "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", "dev": true }, "parse-asn1": { @@ -4509,11 +4559,11 @@ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "dev": true, "requires": { - "asn1.js": "4.9.1", - "browserify-aes": "1.0.6", + "asn1.js": "4.9.2", + "browserify-aes": "1.1.1", "create-hash": "1.1.3", - "evp_bytestokey": "1.0.0", - "pbkdf2": "3.0.12" + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" } }, "parse-glob": { @@ -4587,16 +4637,16 @@ } }, "pbkdf2": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.12.tgz", - "integrity": "sha1-vjZ4XFBn6kjYBv+SMojF91C2uKI=", + "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", "create-hmac": "1.1.6", "ripemd160": "2.0.1", "safe-buffer": "5.1.1", - "sha.js": "2.4.8" + "sha.js": "2.4.9" } }, "pend": { @@ -4606,9 +4656,9 @@ "dev": true }, "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "pify": { @@ -4726,7 +4776,7 @@ "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", "dev": true, "requires": { - "bn.js": "4.11.7", + "bn.js": "4.11.8", "browserify-rsa": "4.0.1", "create-hash": "1.1.3", "parse-asn1": "5.1.0", @@ -4739,12 +4789,6 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true - }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -4776,6 +4820,16 @@ "safe-buffer": "5.1.1" } }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "requires": { + "randombytes": "2.0.5", + "safe-buffer": "5.1.1" + } + }, "rc": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", @@ -5045,33 +5099,56 @@ } }, "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", "dev": true, "requires": { - "aws-sign2": "0.6.0", + "aws-sign2": "0.7.0", "aws4": "1.6.0", "caseless": "0.12.0", "combined-stream": "1.0.5", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", + "mime-types": "2.1.17", "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", + "performance-now": "2.1.0", + "qs": "6.5.1", "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", + "tough-cookie": "2.3.3", "tunnel-agent": "0.6.0", "uuid": "3.1.0" + }, + "dependencies": { + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "dev": true + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "dev": true, + "requires": { + "mime-db": "1.30.0" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + } } }, "require-directory": { @@ -5158,7 +5235,7 @@ "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", "dev": true, "requires": { - "js-base64": "2.1.9", + "js-base64": "2.3.2", "source-map": "0.4.4" }, "dependencies": { @@ -5206,12 +5283,13 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "sha.js": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", - "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "shell-quote": { @@ -5254,12 +5332,12 @@ "dev": true }, "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "4.2.0" } }, "source-list-map": { @@ -5269,9 +5347,9 @@ "dev": true }, "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-loader": { @@ -5309,12 +5387,12 @@ } }, "source-map-support": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", - "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", + "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.6" + "source-map": "0.5.7" } }, "spawn-default-shell": { @@ -5360,9 +5438,9 @@ } }, "split2": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.1.1.tgz", - "integrity": "sha1-eh9VHhdqkOzTNF9yRqDP4XXvT9A=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", "dev": true, "requires": { "through2": "2.0.3" @@ -5405,14 +5483,6 @@ "getpass": "0.1.7", "jsbn": "0.1.1", "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } } }, "stdout-stream": { @@ -5593,24 +5663,15 @@ "es6-promise": "4.1.1" } }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - }, "symbol-observable": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" }, "tapable": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.6.tgz", - "integrity": "sha1-IGvo4YiGC1FEJTdebxrom/sB/Y0=", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", "dev": true }, "tar": { @@ -5679,9 +5740,9 @@ "dev": true }, "timers-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz", - "integrity": "sha1-q0iDz1l9zVCvIRNJoA+8pWrIa4Y=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", "dev": true, "requires": { "setimmediate": "1.0.5" @@ -5714,18 +5775,18 @@ } }, "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", "dev": true, "requires": { "punycode": "1.4.1" } }, "tree-kill": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.1.0.tgz", - "integrity": "sha1-yWPc8DciiS7FnLpWnpQLcZVNFyk=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", + "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", "dev": true }, "trim-newlines": { @@ -5819,7 +5880,7 @@ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "requires": { - "source-map": "0.5.6", + "source-map": "0.5.7", "uglify-to-browserify": "1.0.2", "yargs": "3.10.0" }, @@ -6058,12 +6119,14 @@ } }, "verror": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", - "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "extsprintf": "1.0.2" + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" } }, "vm-browserify": { @@ -6112,20 +6175,20 @@ } }, "watchpack": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.3.1.tgz", - "integrity": "sha1-fYaTkHsozmAT5/NhCqKhrPB9rYc=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", "dev": true, "requires": { - "async": "2.5.0", + "async": "2.6.0", "chokidar": "1.7.0", "graceful-fs": "4.1.11" }, "dependencies": { "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha1-hDGQ/WtzV6C54clW7d3V7IRitU0=", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { "lodash": "4.17.4" @@ -6144,28 +6207,32 @@ "ajv": "4.11.8", "ajv-keywords": "1.5.1", "async": "2.6.0", - "enhanced-resolve": "3.3.0", - "interpret": "1.0.3", - "json-loader": "0.5.4", + "enhanced-resolve": "3.4.1", + "interpret": "1.0.4", + "json-loader": "0.5.7", "loader-runner": "2.3.0", "loader-utils": "0.2.17", "memory-fs": "0.4.1", "mkdirp": "0.5.1", - "node-libs-browser": "2.0.0", - "source-map": "0.5.6", + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", "supports-color": "3.2.3", - "tapable": "0.2.6", + "tapable": "0.2.8", "uglify-js": "2.8.29", - "watchpack": "1.3.1", + "watchpack": "1.4.0", "webpack-sources": "0.2.3", "yargs": "6.6.0" }, "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } }, "async": { "version": "2.6.0", @@ -6194,6 +6261,15 @@ "object-assign": "4.1.1" } }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + }, "yargs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", @@ -6233,7 +6309,7 @@ "dev": true, "requires": { "source-list-map": "1.1.2", - "source-map": "0.5.6" + "source-map": "0.5.7" } }, "whatwg-fetch": { diff --git a/package.json b/package.json index 51bf980e24..4b670f15f3 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,10 @@ "license": "MIT", "dependencies": { "@types/react": "15.0.38", + "adaptivecards": "^1.0.0-beta2", "botframework-directlinejs": "0.9.13", "core-js": "2.4.1", "markdown-it": "8.3.1", - "microsoft-adaptivecards": "0.6.1", "microsoft-speech-browser-sdk": "0.0.1", "react": "15.6.1", "react-dom": "15.6.1", diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index 2fa42736f0..a2c4fc21e3 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import * as AdaptiveCards from "microsoft-adaptivecards"; -import * as AdaptiveCardSchema from "microsoft-adaptivecards/built/schema"; +import * as AdaptiveCards from "adaptivecards"; +import * as AdaptiveCardSchema from "adaptivecards/built/schema"; import { CardAction } from "botframework-directlinejs/built/directLine"; import { classList, IDoCardAction } from "./Chat"; import { AjaxResponse, AjaxRequest } from 'rxjs/observable/dom/AjaxObservable'; @@ -52,7 +52,7 @@ function cardWithoutHttpActions(card: AdaptiveCardSchema.ICard) { return { ...card, actions }; } -AdaptiveCards.AdaptiveCard.onExecuteAction = (action: AdaptiveCards.ExternalAction) => { +AdaptiveCards.AdaptiveCard.onExecuteAction = (action: AdaptiveCards.Action) => { if (action instanceof AdaptiveCards.OpenUrlAction) { window.open(action.url); } else if (action instanceof AdaptiveCards.SubmitAction) { @@ -99,6 +99,7 @@ export class AdaptiveCardContainer extends React.Component { componentDidMount() { const adaptiveCard = new LinkedAdaptiveCard(this); + adaptiveCard.hostConfig = adaptivecardsHostConfig; adaptiveCard.parse(cardWithoutHttpActions(this.props.card)); const errors = adaptiveCard.validate(); if (errors.length === 0) { @@ -169,5 +170,3 @@ export class AdaptiveCardContainer extends React.Component { if (this.props.onImageLoad) this.props.onImageLoad(); } } - -AdaptiveCards.setHostConfig(adaptivecardsHostConfig); diff --git a/src/CardBuilder.tsx b/src/CardBuilder.tsx index 3118e7e579..1198d0ad66 100644 --- a/src/CardBuilder.tsx +++ b/src/CardBuilder.tsx @@ -1,5 +1,5 @@ import { Attachment, CardAction, HeroCard, Thumbnail, CardImage } from 'botframework-directlinejs'; -import * as AdaptiveCardSchema from "microsoft-adaptivecards/built/schema"; +import * as AdaptiveCardSchema from "adaptivecards/built/schema"; import { BotFrameworkCardAction } from './AdaptiveCardContainer'; interface IVersionedCard extends AdaptiveCardSchema.ICard { diff --git a/src/adaptivecards-hostconfig.d.ts b/src/adaptivecards-hostconfig.d.ts index 4a57f68106..365f96e10b 100644 --- a/src/adaptivecards-hostconfig.d.ts +++ b/src/adaptivecards-hostconfig.d.ts @@ -1,5 +1,5 @@ declare module "*/adaptivecards-hostconfig.json" { - import { IHostConfig } from "microsoft-adaptivecards"; + import { IHostConfig } from "adaptivecards"; const _: IHostConfig; export = _; } diff --git a/webpack.config.js b/webpack.config.js index c2d55837e1..5ada7e6375 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -21,7 +21,7 @@ var coreConfig = { exclude: [/node_modules/] }, { - test: require.resolve('microsoft-adaptivecards'), + test: require.resolve('adaptivecards'), use: [{ loader: 'expose-loader', options: 'AdaptiveCards' }] } ] diff --git a/webpack.production.config.js b/webpack.production.config.js index 78523ec9ab..d9abe0e68b 100644 --- a/webpack.production.config.js +++ b/webpack.production.config.js @@ -35,7 +35,7 @@ var coreConfig = { exclude: [/node_modules/] }, { - test: require.resolve('microsoft-adaptivecards'), + test: require.resolve('adaptivecards'), use: [{ loader: 'expose-loader', options: 'AdaptiveCards' }] } ] From 6975b146705395d3dd535407b0d2e7df4e1f071e Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Thu, 16 Nov 2017 16:26:43 -0800 Subject: [PATCH 02/20] new hostconfig schema --- adaptivecards-hostconfig.json | 205 ++++++++------------ src/scss/includes/adaptive-card-config.scss | 205 ++++++++------------ src/scss/includes/colors.scss | 1 + 3 files changed, 153 insertions(+), 258 deletions(-) diff --git a/adaptivecards-hostconfig.json b/adaptivecards-hostconfig.json index e9c62516f7..e18894fe71 100644 --- a/adaptivecards-hostconfig.json +++ b/adaptivecards-hostconfig.json @@ -1,174 +1,121 @@ { "supportsInteractivity": true, - "strongSeparation": { - "spacing": 40, + "spacing": { + "small": 4, + "default": 8, + "medium": 16, + "large": 24, + "extraLarge": 32, + "padding": 8 + }, + "separator": { "lineThickness": 1, - "lineColor": "#eeeeee" + "lineColor": "#cccccc" }, "fontFamily": "\"Segoe UI\", sans-serif", "fontSizes": { "small": 12, - "normal": 13, + "default": 13, "medium": 15, "large": 17, "extraLarge": 19 }, "fontWeights": { "lighter": 200, - "normal": 400, + "default": 400, "bolder": 700 }, - "colors": { - "dark": { - "normal": "#000000", - "subtle": "#808c95" - }, - "light": { - "normal": "#ffffff", - "subtle": "#88ffff" - }, - "accent": { - "normal": "#2e89fc", - "subtle": "#802E8901" - }, - "attention": { - "normal": "#ffd800", - "subtle": "#CCFFD800" - }, - "good": { - "normal": "#00ff00", - "subtle": "#CC00FF00" + "containerStyles": { + "default": { + "backgroundColor": "#00000000", + "fontColors": { + "default": { + "default": "#000000", + "subtle": "#808c95" + }, + "accent": { + "default": "#2e89fc", + "subtle": "#802E8901" + }, + "attention": { + "default": "#ffd800", + "subtle": "#CCFFD800" + }, + "good": { + "default": "#00ff00", + "subtle": "#CC00FF00" + }, + "warning": { + "default": "#ff0000", + "subtle": "#CCFF0000" + } + } }, - "warning": { - "normal": "#ff0000", - "subtle": "#CCFF0000" + "emphasis": { + "backgroundColor": "#08000000", + "fontColors": { + "default": { + "default": "#333333", + "subtle": "#EE333333" + }, + "accent": { + "default": "#2e89fc", + "subtle": "#882E89FC" + }, + "attention": { + "default": "#cc3300", + "subtle": "#DDCC3300" + }, + "good": { + "default": "#54a254", + "subtle": "#DD54A254" + }, + "warning": { + "default": "#e69500", + "subtle": "#DDE69500" + } + } } }, "imageSizes": { "small": 40, - "medium": 64, - "large": 96 + "medium": 80, + "large": 160 }, "actions": { - "maxActions": 100, - "separation": { - "spacing": 8 - }, + "maxActions": 5, + "spacing": "default", "buttonSpacing": 8, - "stretch": false, "showCard": { - "actionMode": "inlineEdgeToEdge", - "inlineTopMargin": 16, - "backgroundColor": "#00000000", - "padding": { - "top": 8, - "right": 8, - "bottom": 8, - "left": 8 - } + "actionMode": "inline", + "inlineTopMargin": 8 }, - "actionsOrientation": "vertical", - "actionAlignment": "left" + "actionsOrientation": "horizontal", + "actionAlignment": "stretch" }, "adaptiveCard": { - "backgroundColor": "#00000000", - "padding": { - "left": 8, - "top": 8, - "right": 8, - "bottom": 8 - } - }, - "container": { - "separation": { - "spacing": 8 - }, - "normal": { - "backgroundColor": "#00000000" - }, - "emphasis": { - "backgroundColor": "#eeeeee", - "borderColor": "#aaaaaa", - "borderThickness": { - "top": 1, - "right": 1, - "bottom": 1, - "left": 1 - }, - "padding": { - "top": 8, - "right": 8, - "bottom": 8, - "left": 8 - } - } - }, - "textBlock": { - "color": "dark", - "separations": { - "small": { - "spacing": 8 - }, - "normal": { - "spacing": 8 - }, - "medium": { - "spacing": 8 - }, - "large": { - "spacing": 8 - }, - "extraLarge": { - "spacing": 8 - } - } - }, - "image": { - "size": "medium", - "separation": { - "spacing": 8 - } + "allowCustomStyle": false }, "imageSet": { "imageSize": "medium", - "separation": { - "spacing": 8 - } + "maxImageHeight": 100 }, "factSet": { - "separation": { - "spacing": 8 - }, "title": { - "color": "dark", - "size": "normal", + "color": "default", + "size": "default", "isSubtle": false, "weight": "bolder", "wrap": true, "maxWidth": 150 }, "value": { - "color": "dark", - "size": "normal", + "color": "default", + "size": "default", "isSubtle": false, - "weight": "normal", + "weight": "default", "wrap": true }, "spacing": 8 - }, - "input": { - "separation": { - "spacing": 8 - } - }, - "columnSet": { - "separation": { - "spacing": 8 - } - }, - "column": { - "separation": { - "spacing": 8 - } } } \ No newline at end of file diff --git a/src/scss/includes/adaptive-card-config.scss b/src/scss/includes/adaptive-card-config.scss index 1e0b535f98..e1ad5a5c34 100644 --- a/src/scss/includes/adaptive-card-config.scss +++ b/src/scss/includes/adaptive-card-config.scss @@ -3,175 +3,122 @@ $hostConfig: ( supportsInteractivity: true, - strongSeparation: ( - spacing: 40px, + spacing: ( + small: ($separation / 2), + default: $separation, + medium: ($separation * 2), + large: ($separation * 3), + extraLarge: ($separation * 4), + padding: $separation + ), + separator: ( lineThickness: 1px, - lineColor: rgb(238, 238, 238) + lineColor: $c_line ), fontFamily: $fontFamily, fontSizes: ( small: ($card_fontSize - 1), - normal: $card_fontSize, + default: $card_fontSize, medium: ($card_fontSize + 2), large: ($card_fontSize + 4), extraLarge: ($card_fontSize + 6) ), fontWeights: ( lighter: 200, - normal: 400, + default: 400, bolder: 700 ), - colors: ( - dark: ( - normal: $c00, - subtle: $c08 - ), - light: ( - normal: rgb(255, 255, 255), - subtle: rgb(136, 255, 255) - ), - accent: ( - normal: rgb(46, 137, 252), - subtle: rgba(46, 137, 1, .5) - ), - attention: ( - normal: rgb(255, 216, 0), - subtle: rgba(255, 216, 0, .8) - ), - good: ( - normal: rgb(0, 255, 0), - subtle: rgba(0, 255, 0, .8) + containerStyles: ( + default: ( + backgroundColor: "#00000000", //using 8 digit hex Adaptive Card color format for transparent ("Transparent" will not be recognized) + fontColors: ( + default: ( + default: $c00, + subtle: $c08 + ), + accent: ( + default: rgb(46, 137, 252), + subtle: rgba(46, 137, 1, .5) + ), + attention: ( + default: rgb(255, 216,0), + subtle: rgba(255, 216, 0, .8) + ), + good: ( + default: rgb(0, 255, 0), + subtle: rgba(0, 255, 0, .8) + ), + warning: ( + default: rgb(255, 0, 0), + subtle: rgba(255, 0, 0, .8) + ) + ) ), - warning: ( - normal: rgb(255, 0, 0), - subtle: rgba(255, 0, 0, .8) + emphasis: ( + backgroundColor: rgba(0,0,0,0.03137254901960784), + fontColors: ( + default: ( + default: rgba(51,51,51,1), + subtle: rgba(51,51,51,0.9333333333333333) + ), + accent: ( + default: rgba(46,137,252,1), + subtle: rgba(46,137,252,0.5333333333333333) + ), + attention: ( + default: rgba(204,51,0,1), + subtle: rgba(204,51,0,0.8666666666666667) + ), + good: ( + default: rgba(84,162,84,1), + subtle: rgba(84,162,84,0.8666666666666667) + ), + warning: ( + default: rgba(230,149,0,1), + subtle: rgba(230,149,0,0.8666666666666667) + ) + ) ) ), imageSizes: ( small: 40px, - medium: 64px, - large: 96px + medium: 80px, + large: 160px ), actions: ( - maxActions: 100, - separation: ( - spacing: $separation - ), + maxActions: 5, + spacing: "default", buttonSpacing: $separation, - stretch: false, showCard: ( - actionMode: "inlineEdgeToEdge", - inlineTopMargin: 16px, - backgroundColor: "#00000000", //using 8 digit hex Adaptive Card color format for transparent ("Transparent" will not be recognized) - padding: ( - top: $separation, - right: $separation, - bottom: $separation, - left: $separation - ) + actionMode: "inline", + inlineTopMargin: $separation ), - actionsOrientation: "vertical", - actionAlignment: "left" + actionsOrientation: "horizontal", + actionAlignment: "stretch" ), adaptiveCard: ( - backgroundColor: "#00000000", //using 8 digit hex Adaptive Card color format for transparent ("Transparent" will not be recognized) - padding: ( - left: $card_padding, - top: $card_padding, - right: $card_padding, - bottom: $card_padding - ) - ), - container: ( - separation: ( - spacing: $separation - ), - normal: ( - backgroundColor: "#00000000", //using 8 digit hex Adaptive Card color format for transparent ("Transparent" will not be recognized) - ), - emphasis: ( - backgroundColor: rgb(238, 238, 238), - borderColor: rgb(170, 170, 170), - borderThickness: ( - top: $card_borderWidth, - right: $card_borderWidth, - bottom: $card_borderWidth, - left: $card_borderWidth - ), - padding: ( - top: $separation, - right: $separation, - bottom: $separation, - left: $separation - ) - ) - ), - textBlock: ( - color: "dark", - separations: ( - small: ( - spacing: $separation - ), - normal: ( - spacing: $separation - ), - medium: ( - spacing: $separation - ), - large: ( - spacing: $separation - ), - extraLarge: ( - spacing: $separation - ) - ) - ), - image: ( - size: "medium", - separation: ( - spacing: $separation - ) + allowCustomStyle: false ), imageSet: ( imageSize: "medium", - separation: ( - spacing: $separation - ) + maxImageHeight: 100px ), factSet: ( - separation: ( - spacing: $separation - ), title: ( - color: "dark", - size: "normal", + color: "default", + size: "default", isSubtle: false, weight: "bolder", wrap: true, maxWidth: 150px ), value: ( - color: "dark", - size: "normal", + color: "default", + size: "default", isSubtle: false, - weight: "normal", + weight: "default", wrap: true ), spacing: $separation - ), - input: ( - separation: ( - spacing: $separation - ) - ), - columnSet: ( - separation: ( - spacing: $separation - ) - ), - column: ( - separation: ( - spacing: $separation - ) ) ); diff --git a/src/scss/includes/colors.scss b/src/scss/includes/colors.scss index 3f259ec2e1..25eb399804 100644 --- a/src/scss/includes/colors.scss +++ b/src/scss/includes/colors.scss @@ -14,6 +14,7 @@ $c11: #d2dde5; $c12: #ffa333; $c_brand: $c07; +$c_line: $c05; $c_shadow: $c02; $c_chrome: $c10; $c_textHeading: $c08; From 9fa31210189557fae27b9d250c4cae178ddc9974 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Thu, 16 Nov 2017 16:26:58 -0800 Subject: [PATCH 03/20] removed cast to any --- src/CardBuilder.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CardBuilder.tsx b/src/CardBuilder.tsx index 1198d0ad66..187e59dd24 100644 --- a/src/CardBuilder.tsx +++ b/src/CardBuilder.tsx @@ -79,7 +79,7 @@ export class AdaptiveCardBuilder { addCommon(content: ICommonContent) { this.addTextBlock(content.title, { size: "medium", weight: "bolder" }); - this.addTextBlock(content.subtitle, { isSubtle: true, wrap: true, separation: "none" } as any); //TODO remove "as any" because separation is not defined + this.addTextBlock(content.subtitle, { isSubtle: true, wrap: true, separation: "none" }); this.addTextBlock(content.text, { wrap: true }); this.addButtons(content.buttons); } From e9eb7227195b25b6d9216474e6efd82fc7ea1c47 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Sat, 18 Nov 2017 09:41:01 -0800 Subject: [PATCH 04/20] removed carat --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b670f15f3..227050b7bd 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "license": "MIT", "dependencies": { "@types/react": "15.0.38", - "adaptivecards": "^1.0.0-beta2", + "adaptivecards": "1.0.0-beta2", "botframework-directlinejs": "0.9.13", "core-js": "2.4.1", "markdown-it": "8.3.1", From 0280752866b3ea1df78b36a023ec091466aa61ec Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Mon, 27 Nov 2017 16:02:57 -0800 Subject: [PATCH 05/20] update to beta5 --- package.json | 2 +- src/AdaptiveCardContainer.tsx | 2 +- src/adaptivecards-hostconfig.d.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 227050b7bd..3c514de48d 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "license": "MIT", "dependencies": { "@types/react": "15.0.38", - "adaptivecards": "1.0.0-beta2", + "adaptivecards": "1.0.0-beta5", "botframework-directlinejs": "0.9.13", "core-js": "2.4.1", "markdown-it": "8.3.1", diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index a2c4fc21e3..3937b4d7ab 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -99,7 +99,7 @@ export class AdaptiveCardContainer extends React.Component { componentDidMount() { const adaptiveCard = new LinkedAdaptiveCard(this); - adaptiveCard.hostConfig = adaptivecardsHostConfig; + adaptiveCard.hostConfig = new AdaptiveCards.HostConfig(adaptivecardsHostConfig); adaptiveCard.parse(cardWithoutHttpActions(this.props.card)); const errors = adaptiveCard.validate(); if (errors.length === 0) { diff --git a/src/adaptivecards-hostconfig.d.ts b/src/adaptivecards-hostconfig.d.ts index 365f96e10b..f2c7517ad8 100644 --- a/src/adaptivecards-hostconfig.d.ts +++ b/src/adaptivecards-hostconfig.d.ts @@ -1,5 +1,5 @@ declare module "*/adaptivecards-hostconfig.json" { - import { IHostConfig } from "adaptivecards"; - const _: IHostConfig; + import { HostConfig } from "adaptivecards"; + const _: HostConfig; export = _; } From c125aaab75374ebaa2ea78f9c9ce474a1423a27a Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Wed, 29 Nov 2017 17:13:59 -0800 Subject: [PATCH 06/20] vertical buttons --- adaptivecards-hostconfig.json | 2 +- src/scss/includes/adaptive-card-config.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adaptivecards-hostconfig.json b/adaptivecards-hostconfig.json index e18894fe71..3994d33338 100644 --- a/adaptivecards-hostconfig.json +++ b/adaptivecards-hostconfig.json @@ -90,7 +90,7 @@ "actionMode": "inline", "inlineTopMargin": 8 }, - "actionsOrientation": "horizontal", + "actionsOrientation": "vertical", "actionAlignment": "stretch" }, "adaptiveCard": { diff --git a/src/scss/includes/adaptive-card-config.scss b/src/scss/includes/adaptive-card-config.scss index e1ad5a5c34..e0b0535ee7 100644 --- a/src/scss/includes/adaptive-card-config.scss +++ b/src/scss/includes/adaptive-card-config.scss @@ -93,7 +93,7 @@ $hostConfig: ( actionMode: "inline", inlineTopMargin: $separation ), - actionsOrientation: "horizontal", + actionsOrientation: "vertical", actionAlignment: "stretch" ), adaptiveCard: ( From 9ed54218fdd7671be67b6e1685d9d5df92282fc6 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Wed, 29 Nov 2017 18:29:22 -0800 Subject: [PATCH 07/20] update to beta9 --- package.json | 2 +- src/AdaptiveCardContainer.tsx | 6 +++--- src/Attachment.tsx | 15 ++++++++------- src/CardBuilder.tsx | 8 ++++---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 3c514de48d..31af760fc1 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "license": "MIT", "dependencies": { "@types/react": "15.0.38", - "adaptivecards": "1.0.0-beta5", + "adaptivecards": "1.0.0-beta9", "botframework-directlinejs": "0.9.13", "core-js": "2.4.1", "markdown-it": "8.3.1", diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index 3937b4d7ab..ed02aa3485 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import * as AdaptiveCards from "adaptivecards"; -import * as AdaptiveCardSchema from "adaptivecards/built/schema"; +import * as AdaptiveCardSchema from "adaptivecards/lib/schema"; import { CardAction } from "botframework-directlinejs/built/directLine"; import { classList, IDoCardAction } from "./Chat"; import { AjaxResponse, AjaxRequest } from 'rxjs/observable/dom/AjaxObservable'; @@ -8,7 +8,7 @@ import * as adaptivecardsHostConfig from '../adaptivecards-hostconfig.json'; import * as konsole from './Konsole'; export interface Props { - card: AdaptiveCardSchema.ICard, + card: AdaptiveCardSchema.IAdaptiveCard, onImageLoad?: () => any, onClick?: (e: React.MouseEvent) => void, onCardAction: IDoCardAction, @@ -37,7 +37,7 @@ function getLinkedAdaptiveCard(action: AdaptiveCards.Action) { return element as LinkedAdaptiveCard; } -function cardWithoutHttpActions(card: AdaptiveCardSchema.ICard) { +function cardWithoutHttpActions(card: AdaptiveCardSchema.IAdaptiveCard) { if (!card.actions) return card; const actions: AdaptiveCardSchema.IActionBase[] = []; card.actions.forEach(action => { diff --git a/src/Attachment.tsx b/src/Attachment.tsx index 6a33a6fd01..c263eb33f3 100644 --- a/src/Attachment.tsx +++ b/src/Attachment.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import * as CardBuilder from './CardBuilder'; +import { HorizontalAlignment } from 'adaptivecards'; import { Attachment, CardAction, CardImage, KnownMedia, UnknownMedia } from 'botframework-directlinejs'; import { renderIfNonempty, IDoCardAction } from './Chat'; import { FormatState } from './Store'; @@ -180,7 +181,7 @@ export const AttachmentView = (props: { if (!content.media || content.media.length === 0) { return null; } - // rendering every media in the media array. Validates every type as image, video, audio or a function that returns those values. + // rendering every media in the media array. Validates every type as image, video, audio or a function that returns those values. return content.media.map((md, i) => { let t = (typeof type === 'string')? type : type(md.url); return { receiptCardBuilder.addTextBlock(fact.key, { color: 'default', size: 'medium' }, columns[0]); - receiptCardBuilder.addTextBlock(fact.value, { color: 'default', size: 'medium', horizontalAlignment: 'right' }, columns[1]); + receiptCardBuilder.addTextBlock(fact.value, { color: 'default', size: 'medium', horizontalAlignment: HorizontalAlignment.Right }, columns[1]); }); attachment.content.items && attachment.content.items.map((item, i) => { if (item.image) { @@ -274,28 +275,28 @@ export const AttachmentView = (props: { receiptCardBuilder.addImage(item.image, columns2[0]); receiptCardBuilder.addTextBlock(item.title, { size: "medium", weight: "bolder" }, columns2[1]); receiptCardBuilder.addTextBlock(item.subtitle, { color: 'default', size: 'medium' }, columns2[1]); - receiptCardBuilder.addTextBlock(item.price, { horizontalAlignment: 'right' }, columns2[2]); + receiptCardBuilder.addTextBlock(item.price, { horizontalAlignment: HorizontalAlignment.Right }, columns2[2]); } else { const columns3 = receiptCardBuilder.addColumnSet([75, 25]); receiptCardBuilder.addTextBlock(item.title, { size: "medium", weight: "bolder" }, columns3[0]); receiptCardBuilder.addTextBlock(item.subtitle, { color: 'default', size: 'medium' }, columns3[0]); - receiptCardBuilder.addTextBlock(item.price, { horizontalAlignment: 'right' }, columns3[1]); + receiptCardBuilder.addTextBlock(item.price, { horizontalAlignment: HorizontalAlignment.Right }, columns3[1]); } }); if (exists(attachment.content.vat)) { const vatCol = receiptCardBuilder.addColumnSet([75, 25]); receiptCardBuilder.addTextBlock(props.format.strings.receiptVat, { size: "medium", weight: "bolder" }, vatCol[0]); - receiptCardBuilder.addTextBlock(attachment.content.vat, { horizontalAlignment: 'right' }, vatCol[1]); + receiptCardBuilder.addTextBlock(attachment.content.vat, { horizontalAlignment: HorizontalAlignment.Right }, vatCol[1]); } if (exists(attachment.content.tax)) { const taxCol = receiptCardBuilder.addColumnSet([75, 25]); receiptCardBuilder.addTextBlock(props.format.strings.receiptTax, { size: "medium", weight: "bolder" }, taxCol[0]); - receiptCardBuilder.addTextBlock(attachment.content.tax, { horizontalAlignment: 'right' }, taxCol[1]); + receiptCardBuilder.addTextBlock(attachment.content.tax, { horizontalAlignment: HorizontalAlignment.Right }, taxCol[1]); } if (exists(attachment.content.total)) { const totalCol = receiptCardBuilder.addColumnSet([75, 25]); receiptCardBuilder.addTextBlock(props.format.strings.receiptTotal, { size: "medium", weight: "bolder" }, totalCol[0]); - receiptCardBuilder.addTextBlock(attachment.content.total, { horizontalAlignment: 'right', size: "medium", weight: "bolder" }, totalCol[1]); + receiptCardBuilder.addTextBlock(attachment.content.total, { horizontalAlignment: HorizontalAlignment.Right, size: "medium", weight: "bolder" }, totalCol[1]); } receiptCardBuilder.addButtons(attachment.content.buttons); return ( diff --git a/src/CardBuilder.tsx b/src/CardBuilder.tsx index 187e59dd24..59e1909fec 100644 --- a/src/CardBuilder.tsx +++ b/src/CardBuilder.tsx @@ -1,14 +1,14 @@ import { Attachment, CardAction, HeroCard, Thumbnail, CardImage } from 'botframework-directlinejs'; -import * as AdaptiveCardSchema from "adaptivecards/built/schema"; +import * as AdaptiveCardSchema from 'adaptivecards/lib/schema'; import { BotFrameworkCardAction } from './AdaptiveCardContainer'; -interface IVersionedCard extends AdaptiveCardSchema.ICard { +interface IVersionedCard extends AdaptiveCardSchema.IAdaptiveCard { version: string; } export class AdaptiveCardBuilder { public container: AdaptiveCardSchema.IContainer; - public card: AdaptiveCardSchema.ICard; + public card: AdaptiveCardSchema.IAdaptiveCard; constructor() { this.container = { @@ -106,7 +106,7 @@ export interface ICommonContent { buttons?: CardAction[] } -export const buildCommonCard = (content: ICommonContent): AdaptiveCardSchema.ICard => { +export const buildCommonCard = (content: ICommonContent): AdaptiveCardSchema.IAdaptiveCard => { if (!content) return null; const cardBuilder = new AdaptiveCardBuilder(); From 221077c3826c901c23171b807f6617f4878d54dd Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Fri, 1 Dec 2017 18:49:30 -0800 Subject: [PATCH 08/20] rename fontColors to foregroundColors --- adaptivecards-hostconfig.json | 4 ++-- src/scss/includes/adaptive-card-config.scss | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/adaptivecards-hostconfig.json b/adaptivecards-hostconfig.json index 3994d33338..ed8e6e79d6 100644 --- a/adaptivecards-hostconfig.json +++ b/adaptivecards-hostconfig.json @@ -28,7 +28,7 @@ "containerStyles": { "default": { "backgroundColor": "#00000000", - "fontColors": { + "foregroundColors": { "default": { "default": "#000000", "subtle": "#808c95" @@ -53,7 +53,7 @@ }, "emphasis": { "backgroundColor": "#08000000", - "fontColors": { + "foregroundColors": { "default": { "default": "#333333", "subtle": "#EE333333" diff --git a/src/scss/includes/adaptive-card-config.scss b/src/scss/includes/adaptive-card-config.scss index e0b0535ee7..e8974cfdf3 100644 --- a/src/scss/includes/adaptive-card-config.scss +++ b/src/scss/includes/adaptive-card-config.scss @@ -31,7 +31,7 @@ $hostConfig: ( containerStyles: ( default: ( backgroundColor: "#00000000", //using 8 digit hex Adaptive Card color format for transparent ("Transparent" will not be recognized) - fontColors: ( + foregroundColors: ( default: ( default: $c00, subtle: $c08 @@ -56,7 +56,7 @@ $hostConfig: ( ), emphasis: ( backgroundColor: rgba(0,0,0,0.03137254901960784), - fontColors: ( + foregroundColors: ( default: ( default: rgba(51,51,51,1), subtle: rgba(51,51,51,0.9333333333333333) From 04fe92ebf483d970133b7904fe71c6d50d2b689c Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Fri, 1 Dec 2017 18:51:26 -0800 Subject: [PATCH 09/20] use native AdaptiveCards lib --- src/AdaptiveCardContainer.tsx | 76 ++++++++------------ src/Attachment.tsx | 30 ++++---- src/CardBuilder.tsx | 130 +++++++++++++++++----------------- 3 files changed, 111 insertions(+), 125 deletions(-) diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index ed02aa3485..aa8be5855a 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import * as AdaptiveCards from "adaptivecards"; -import * as AdaptiveCardSchema from "adaptivecards/lib/schema"; +import { Action, AdaptiveCard, HostConfig, IValidationError, OpenUrlAction, SubmitAction } from "adaptivecards"; +import { IActionBase, IActionShowCard, IAdaptiveCard } from "adaptivecards/lib/schema"; import { CardAction } from "botframework-directlinejs/built/directLine"; import { classList, IDoCardAction } from "./Chat"; import { AjaxResponse, AjaxRequest } from 'rxjs/observable/dom/AjaxObservable'; @@ -8,7 +8,8 @@ import * as adaptivecardsHostConfig from '../adaptivecards-hostconfig.json'; import * as konsole from './Konsole'; export interface Props { - card: AdaptiveCardSchema.IAdaptiveCard, + card?: AdaptiveCard, + jcard?: IAdaptiveCard, onImageLoad?: () => any, onClick?: (e: React.MouseEvent) => void, onCardAction: IDoCardAction, @@ -19,32 +20,20 @@ export interface State { errors?: string[] } -class LinkedAdaptiveCard extends AdaptiveCards.AdaptiveCard { - constructor(public adaptiveCardContainer: AdaptiveCardContainer) { - super(); - } -} - export interface BotFrameworkCardAction extends CardAction { __isBotFrameworkCardAction: boolean } -function getLinkedAdaptiveCard(action: AdaptiveCards.Action) { - let element = action.parent; - while (element && !(element instanceof LinkedAdaptiveCard)) { - element = element.parent; - } - return element as LinkedAdaptiveCard; -} +const hostConfig = new HostConfig(adaptivecardsHostConfig); -function cardWithoutHttpActions(card: AdaptiveCardSchema.IAdaptiveCard) { +function cardWithoutHttpActions(card: IAdaptiveCard) { if (!card.actions) return card; - const actions: AdaptiveCardSchema.IActionBase[] = []; + const actions: IActionBase[] = []; card.actions.forEach(action => { //filter out http action buttons if (action.type === 'Action.Http') return; if (action.type === 'Action.ShowCard') { - const showCardAction = action as AdaptiveCardSchema.IActionShowCard; + const showCardAction = action as IActionShowCard; showCardAction.card = cardWithoutHttpActions(showCardAction.card); } actions.push(action); @@ -52,22 +41,6 @@ function cardWithoutHttpActions(card: AdaptiveCardSchema.IAdaptiveCard) { return { ...card, actions }; } -AdaptiveCards.AdaptiveCard.onExecuteAction = (action: AdaptiveCards.Action) => { - if (action instanceof AdaptiveCards.OpenUrlAction) { - window.open(action.url); - } else if (action instanceof AdaptiveCards.SubmitAction) { - const linkedAdaptiveCard = getLinkedAdaptiveCard(action); - if (linkedAdaptiveCard && action.data !== undefined) { - if (typeof action.data === 'object' && (action.data as BotFrameworkCardAction).__isBotFrameworkCardAction) { - const cardAction = (action.data as BotFrameworkCardAction); - linkedAdaptiveCard.adaptiveCardContainer.onCardAction(cardAction.type, cardAction.value); - } else { - linkedAdaptiveCard.adaptiveCardContainer.onCardAction(typeof action.data === 'string' ? 'imBack' : 'postBack', action.data); - } - } - } -}; - export class AdaptiveCardContainer extends React.Component { private div: HTMLDivElement; @@ -75,10 +48,6 @@ export class AdaptiveCardContainer extends React.Component { super(props); } - public onCardAction: IDoCardAction = (type, value) => { - this.props.onCardAction(type, value); - } - private onClick(e: React.MouseEvent) { if (!this.props.onClick) return; //do not allow form elements to trigger a parent click event @@ -97,23 +66,40 @@ export class AdaptiveCardContainer extends React.Component { } } + private onExecuteAction(action: Action) { + if (action instanceof OpenUrlAction) { + window.open(action.url); + } else if (action instanceof SubmitAction) { + if (action.data !== undefined) { + if (typeof action.data === 'object' && (action.data as BotFrameworkCardAction).__isBotFrameworkCardAction) { + const cardAction = (action.data as BotFrameworkCardAction); + this.props.onCardAction(cardAction.type, cardAction.value); + } else { + this.props.onCardAction(typeof action.data === 'string' ? 'imBack' : 'postBack', action.data); + } + } + } + } componentDidMount() { - const adaptiveCard = new LinkedAdaptiveCard(this); - adaptiveCard.hostConfig = new AdaptiveCards.HostConfig(adaptivecardsHostConfig); - adaptiveCard.parse(cardWithoutHttpActions(this.props.card)); - const errors = adaptiveCard.validate(); + const adaptiveCard = this.props.card || new AdaptiveCard(); + adaptiveCard.hostConfig = hostConfig; + let errors: IValidationError[] = []; + if (!this.props.card && this.props.jcard) { + adaptiveCard.parse(cardWithoutHttpActions(this.props.jcard)); + errors = adaptiveCard.validate(); + } + adaptiveCard.onExecuteAction = (action) => this.onExecuteAction(action); if (errors.length === 0) { let renderedCard: HTMLElement; try { renderedCard = adaptiveCard.render(); } catch (e) { - const ve: AdaptiveCards.IValidationError = { + const ve: IValidationError = { error: -1, message: e }; errors.push(ve); - if (e.stack) { ve.message += '\n' + e.stack; } diff --git a/src/Attachment.tsx b/src/Attachment.tsx index c263eb33f3..41465fa54d 100644 --- a/src/Attachment.tsx +++ b/src/Attachment.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import * as CardBuilder from './CardBuilder'; -import { HorizontalAlignment } from 'adaptivecards'; +import { HorizontalAlignment, TextSize, TextWeight } from 'adaptivecards'; import { Attachment, CardAction, CardImage, KnownMedia, UnknownMedia } from 'botframework-directlinejs'; import { renderIfNonempty, IDoCardAction } from './Chat'; import { FormatState } from './Store'; @@ -213,7 +213,7 @@ export const AttachmentView = (props: { const thumbnailCardBuilder = new CardBuilder.AdaptiveCardBuilder(); if (attachment.content.images && attachment.content.images.length > 0) { const columns = thumbnailCardBuilder.addColumnSet([75, 25]); - thumbnailCardBuilder.addTextBlock(attachment.content.title, { size: "medium", weight: "bolder" }, columns[0]); + thumbnailCardBuilder.addTextBlock(attachment.content.title, { size: TextSize.Medium, weight: TextWeight.Bolder }, columns[0]); thumbnailCardBuilder.addTextBlock(attachment.content.subtitle, { isSubtle: true, wrap: true }, columns[0]); thumbnailCardBuilder.addImage(attachment.content.images[0], columns[1]); thumbnailCardBuilder.addTextBlock(attachment.content.text, { wrap: true }); @@ -263,40 +263,40 @@ export const AttachmentView = (props: { if (!attachment.content) return null; const receiptCardBuilder = new CardBuilder.AdaptiveCardBuilder(); - receiptCardBuilder.addTextBlock(attachment.content.title, { size: "medium", weight: "bolder" }); + receiptCardBuilder.addTextBlock(attachment.content.title, { size: TextSize.Medium, weight: TextWeight.Bolder }); const columns = receiptCardBuilder.addColumnSet([75, 25]); attachment.content.facts && attachment.content.facts.map((fact, i) => { - receiptCardBuilder.addTextBlock(fact.key, { color: 'default', size: 'medium' }, columns[0]); - receiptCardBuilder.addTextBlock(fact.value, { color: 'default', size: 'medium', horizontalAlignment: HorizontalAlignment.Right }, columns[1]); + receiptCardBuilder.addTextBlock(fact.key, { size: TextSize.Medium }, columns[0]); + receiptCardBuilder.addTextBlock(fact.value, { size: TextSize.Medium, horizontalAlignment: HorizontalAlignment.Right }, columns[1]); }); attachment.content.items && attachment.content.items.map((item, i) => { if (item.image) { const columns2 = receiptCardBuilder.addColumnSet([15, 75, 10]); - receiptCardBuilder.addImage(item.image, columns2[0]); - receiptCardBuilder.addTextBlock(item.title, { size: "medium", weight: "bolder" }, columns2[1]); - receiptCardBuilder.addTextBlock(item.subtitle, { color: 'default', size: 'medium' }, columns2[1]); + receiptCardBuilder.addImage(item.image.url, columns2[0]); + receiptCardBuilder.addTextBlock(item.title, { size: TextSize.Medium, weight: TextWeight.Bolder, wrap: true }, columns2[1]); + receiptCardBuilder.addTextBlock(item.subtitle, { size: TextSize.Medium, wrap: true }, columns2[1]); receiptCardBuilder.addTextBlock(item.price, { horizontalAlignment: HorizontalAlignment.Right }, columns2[2]); } else { const columns3 = receiptCardBuilder.addColumnSet([75, 25]); - receiptCardBuilder.addTextBlock(item.title, { size: "medium", weight: "bolder" }, columns3[0]); - receiptCardBuilder.addTextBlock(item.subtitle, { color: 'default', size: 'medium' }, columns3[0]); + receiptCardBuilder.addTextBlock(item.title, { size: TextSize.Medium, weight: TextWeight.Bolder, wrap: true }, columns3[0]); + receiptCardBuilder.addTextBlock(item.subtitle, { size: TextSize.Medium, wrap: true }, columns3[0]); receiptCardBuilder.addTextBlock(item.price, { horizontalAlignment: HorizontalAlignment.Right }, columns3[1]); } }); if (exists(attachment.content.vat)) { const vatCol = receiptCardBuilder.addColumnSet([75, 25]); - receiptCardBuilder.addTextBlock(props.format.strings.receiptVat, { size: "medium", weight: "bolder" }, vatCol[0]); + receiptCardBuilder.addTextBlock(props.format.strings.receiptVat, { size: TextSize.Medium, weight: TextWeight.Bolder }, vatCol[0]); receiptCardBuilder.addTextBlock(attachment.content.vat, { horizontalAlignment: HorizontalAlignment.Right }, vatCol[1]); } if (exists(attachment.content.tax)) { const taxCol = receiptCardBuilder.addColumnSet([75, 25]); - receiptCardBuilder.addTextBlock(props.format.strings.receiptTax, { size: "medium", weight: "bolder" }, taxCol[0]); + receiptCardBuilder.addTextBlock(props.format.strings.receiptTax, { size: TextSize.Medium, weight: TextWeight.Bolder }, taxCol[0]); receiptCardBuilder.addTextBlock(attachment.content.tax, { horizontalAlignment: HorizontalAlignment.Right }, taxCol[1]); } if (exists(attachment.content.total)) { const totalCol = receiptCardBuilder.addColumnSet([75, 25]); - receiptCardBuilder.addTextBlock(props.format.strings.receiptTotal, { size: "medium", weight: "bolder" }, totalCol[0]); - receiptCardBuilder.addTextBlock(attachment.content.total, { horizontalAlignment: HorizontalAlignment.Right, size: "medium", weight: "bolder" }, totalCol[1]); + receiptCardBuilder.addTextBlock(props.format.strings.receiptTotal, { size: TextSize.Medium, weight: TextWeight.Bolder }, totalCol[0]); + receiptCardBuilder.addTextBlock(attachment.content.total, { horizontalAlignment: HorizontalAlignment.Right, size: TextSize.Medium, weight: TextWeight.Bolder }, totalCol[1]); } receiptCardBuilder.addButtons(attachment.content.buttons); return ( @@ -307,7 +307,7 @@ export const AttachmentView = (props: { if (!attachment.content) return null; return ( - + ); // Deprecated format for Skype channels. For testing legacy bots in Emulator only. diff --git a/src/CardBuilder.tsx b/src/CardBuilder.tsx index 59e1909fec..e8568178c3 100644 --- a/src/CardBuilder.tsx +++ b/src/CardBuilder.tsx @@ -1,100 +1,100 @@ import { Attachment, CardAction, HeroCard, Thumbnail, CardImage } from 'botframework-directlinejs'; -import * as AdaptiveCardSchema from 'adaptivecards/lib/schema'; +import { AdaptiveCard, CardElement, Column, ColumnSet, Container, Image, OpenUrlAction, Size, SubmitAction, TextBlock, TextSize, TextWeight } from 'adaptivecards'; import { BotFrameworkCardAction } from './AdaptiveCardContainer'; -interface IVersionedCard extends AdaptiveCardSchema.IAdaptiveCard { - version: string; -} +// interface IVersionedCard extends AdaptiveCardSchema.IAdaptiveCard { +// version: string; +// } export class AdaptiveCardBuilder { - public container: AdaptiveCardSchema.IContainer; - public card: AdaptiveCardSchema.IAdaptiveCard; + private container: Container; + public card: AdaptiveCard; constructor() { - this.container = { - type: "Container", - items: [] - }; - - this.card = { - type: "AdaptiveCard", - version: "0.5", - body: [this.container] - } as IVersionedCard; + this.card = new AdaptiveCard(); + + this.container = new Container(); + this.card.addItem(this.container); } - addColumnSet(sizes: number[], container = this.container) { - const columnSet: AdaptiveCardSchema.IColumnSet = { - type: 'ColumnSet', - columns: sizes.map((size): AdaptiveCardSchema.IColumn => { - return { - type: 'Column', - size: size.toString(), - items: [] - } - }) - }; - container.items.push(columnSet); - return columnSet.columns; + addColumnSet(sizes: number[], container?: Container) { + container = container || this.container; + const columnSet = new ColumnSet(); + container.addItem(columnSet); + const columns = sizes.map(size => { + const column = new Column(); + column.width = size; + columnSet.addColumn(column); + return column; + }) + return columns; } - addItems(elements: AdaptiveCardSchema.ICardElement[], container = this.container) { - container.items.push.apply(container.items, elements); + addItems(cardElements: CardElement[], container?: Container) { + container = container || this.container; + cardElements.forEach(cardElement => container.addItem(cardElement)); } - addTextBlock(text: string, template: Partial, container = this.container) { + addTextBlock(text: string, template: Partial, container?: Container) { + container = container || this.container; if (typeof text !== 'undefined') { - const textblock: AdaptiveCardSchema.ITextBlock = { - type: "TextBlock", - text: text, - ...template - }; - container.items.push(textblock); + const textblock = new TextBlock(); + for (let prop in template) { + (textblock as any)[prop] = (template as any)[prop]; + } + textblock.text = text; + container.addItem(textblock); } } - addButtons(buttons: CardAction[]) { - if (buttons) { - this.card.actions = buttons.map(AdaptiveCardBuilder.addCardAction); + addButtons(cardActions: CardAction[]) { + if (cardActions) { + cardActions.forEach(cardAction => { + this.card.addAction(AdaptiveCardBuilder.addCardAction(cardAction); + }); } } private static addCardAction(cardAction: CardAction) { if (cardAction.type === 'imBack' || cardAction.type === 'postBack') { + const action = new SubmitAction(); const botFrameworkCardAction: BotFrameworkCardAction = { __isBotFrameworkCardAction: true, ...cardAction }; - return { - title: cardAction.title, - type: "Action.Submit", - data: botFrameworkCardAction - }; - } - else { - return { - type: 'Action.OpenUrl', - title: cardAction.title, - url: cardAction.type === 'call' ? 'tel:' + cardAction.value : cardAction.value - }; + + action.data = botFrameworkCardAction; + action.title = cardAction.title; + + return action; + } else { + const action = new OpenUrlAction(); + const botFrameworkCardAction: BotFrameworkCardAction = { __isBotFrameworkCardAction: true, ...cardAction }; + + action.title = cardAction.title; + action.url = cardAction.type === 'call' ? 'tel:' + cardAction.value : cardAction.value; + + return action; } } addCommon(content: ICommonContent) { - this.addTextBlock(content.title, { size: "medium", weight: "bolder" }); - this.addTextBlock(content.subtitle, { isSubtle: true, wrap: true, separation: "none" }); + this.addTextBlock(content.title, { size: TextSize.Medium, weight: TextWeight.Bolder }); + this.addTextBlock(content.subtitle, { isSubtle: true, wrap: true }); this.addTextBlock(content.text, { wrap: true }); this.addButtons(content.buttons); } - addImage(image: CardImage, container = this.container) { - var img: AdaptiveCardSchema.IImage = { - type: "Image", - url: image.url, - size: "stretch", - }; + addImage(url: string, container?: Container, selectAction?: CardAction) { + container = container || this.container; + + const image = new Image(); - if (image.tap) { - img.selectAction = AdaptiveCardBuilder.addCardAction(image.tap); + image.url = url; + image.size = Size.Stretch; + + if (selectAction) { + image.selectAction = AdaptiveCardBuilder.addCardAction(selectAction); } - container.items.push(img); + + container.addItem(image); } } @@ -106,7 +106,7 @@ export interface ICommonContent { buttons?: CardAction[] } -export const buildCommonCard = (content: ICommonContent): AdaptiveCardSchema.IAdaptiveCard => { +export const buildCommonCard = (content: ICommonContent): AdaptiveCard => { if (!content) return null; const cardBuilder = new AdaptiveCardBuilder(); From e7ed11d83ecd3a38d7fd5bf204eb2cbe4ddcb48b Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Wed, 6 Dec 2017 11:52:54 -0800 Subject: [PATCH 10/20] rename interface --- src/AdaptiveCardContainer.tsx | 10 +++++----- src/Attachment.tsx | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index aa8be5855a..ce00662879 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -8,8 +8,8 @@ import * as adaptivecardsHostConfig from '../adaptivecards-hostconfig.json'; import * as konsole from './Konsole'; export interface Props { - card?: AdaptiveCard, - jcard?: IAdaptiveCard, + nativeCard?: AdaptiveCard, + jsonCard?: IAdaptiveCard, onImageLoad?: () => any, onClick?: (e: React.MouseEvent) => void, onCardAction: IDoCardAction, @@ -81,11 +81,11 @@ export class AdaptiveCardContainer extends React.Component { } } componentDidMount() { - const adaptiveCard = this.props.card || new AdaptiveCard(); + const adaptiveCard = this.props.nativeCard || new AdaptiveCard(); adaptiveCard.hostConfig = hostConfig; let errors: IValidationError[] = []; - if (!this.props.card && this.props.jcard) { - adaptiveCard.parse(cardWithoutHttpActions(this.props.jcard)); + if (!this.props.nativeCard && this.props.jsonCard) { + adaptiveCard.parse(cardWithoutHttpActions(this.props.jsonCard)); errors = adaptiveCard.validate(); } adaptiveCard.onExecuteAction = (action) => this.onExecuteAction(action); diff --git a/src/Attachment.tsx b/src/Attachment.tsx index 41465fa54d..e36d65b89c 100644 --- a/src/Attachment.tsx +++ b/src/Attachment.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import * as CardBuilder from './CardBuilder'; -import { HorizontalAlignment, TextSize, TextWeight } from 'adaptivecards'; +import { HorizontalAlignment, IAdaptiveCard, TextSize, TextWeight } from 'adaptivecards'; import { Attachment, CardAction, CardImage, KnownMedia, UnknownMedia } from 'botframework-directlinejs'; import { renderIfNonempty, IDoCardAction } from './Chat'; import { FormatState } from './Store'; @@ -204,7 +204,7 @@ export const AttachmentView = (props: { } heroCardBuilder.addCommon(attachment.content) return ( - + ); case "application/vnd.microsoft.card.thumbnail": @@ -222,14 +222,14 @@ export const AttachmentView = (props: { thumbnailCardBuilder.addCommon(attachment.content); } return ( - + ); case "application/vnd.microsoft.card.video": if (!attachment.content || !attachment.content.media || attachment.content.media.length === 0) return null; return ( - + {getRichCardContentMedia('video', attachment.content)} ); @@ -238,7 +238,7 @@ export const AttachmentView = (props: { if (!attachment.content || !attachment.content.media || attachment.content.media.length === 0) return null; return ( - + {getRichCardContentMedia(mediaType, attachment.content)} ); @@ -247,7 +247,7 @@ export const AttachmentView = (props: { if (!attachment.content || !attachment.content.media || attachment.content.media.length === 0) return null; return ( - + {getRichCardContentMedia('audio', attachment.content)} ); @@ -256,7 +256,7 @@ export const AttachmentView = (props: { if (!attachment.content) return null; return ( - + ); case "application/vnd.microsoft.card.receipt": @@ -300,14 +300,14 @@ export const AttachmentView = (props: { } receiptCardBuilder.addButtons(attachment.content.buttons); return ( - + ); case "application/vnd.microsoft.card.adaptive": if (!attachment.content) return null; return ( - + ); // Deprecated format for Skype channels. For testing legacy bots in Emulator only. @@ -315,7 +315,7 @@ export const AttachmentView = (props: { if (!attachment.content) return null; return ( - + { attachedImage(attachment.content.images) } ); From b7bdf9b158885e5cbfee9e2132b7cd050d1533d5 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Wed, 6 Dec 2017 13:24:09 -0800 Subject: [PATCH 11/20] removed comment --- src/CardBuilder.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/CardBuilder.tsx b/src/CardBuilder.tsx index e8568178c3..f24ebaad7c 100644 --- a/src/CardBuilder.tsx +++ b/src/CardBuilder.tsx @@ -2,10 +2,6 @@ import { Attachment, CardAction, HeroCard, Thumbnail, CardImage } from 'botframe import { AdaptiveCard, CardElement, Column, ColumnSet, Container, Image, OpenUrlAction, Size, SubmitAction, TextBlock, TextSize, TextWeight } from 'adaptivecards'; import { BotFrameworkCardAction } from './AdaptiveCardContainer'; -// interface IVersionedCard extends AdaptiveCardSchema.IAdaptiveCard { -// version: string; -// } - export class AdaptiveCardBuilder { private container: Container; public card: AdaptiveCard; From 2d375db61a6a035342ec5c2c494faa58c41d0b17 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Wed, 6 Dec 2017 15:00:44 -0800 Subject: [PATCH 12/20] set maxActions to 100 --- adaptivecards-hostconfig.json | 2 +- src/scss/includes/adaptive-card-config.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adaptivecards-hostconfig.json b/adaptivecards-hostconfig.json index ed8e6e79d6..2bad05e003 100644 --- a/adaptivecards-hostconfig.json +++ b/adaptivecards-hostconfig.json @@ -83,7 +83,7 @@ "large": 160 }, "actions": { - "maxActions": 5, + "maxActions": 100, "spacing": "default", "buttonSpacing": 8, "showCard": { diff --git a/src/scss/includes/adaptive-card-config.scss b/src/scss/includes/adaptive-card-config.scss index e8974cfdf3..729478c120 100644 --- a/src/scss/includes/adaptive-card-config.scss +++ b/src/scss/includes/adaptive-card-config.scss @@ -86,7 +86,7 @@ $hostConfig: ( large: 160px ), actions: ( - maxActions: 5, + maxActions: 100, spacing: "default", buttonSpacing: $separation, showCard: ( From c7f295a7fb93210d86041d1120ffc117944f04ef Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Wed, 6 Dec 2017 15:24:56 -0800 Subject: [PATCH 13/20] default version to 0.5 --- src/AdaptiveCardContainer.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index ce00662879..92f75500a0 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -85,6 +85,7 @@ export class AdaptiveCardContainer extends React.Component { adaptiveCard.hostConfig = hostConfig; let errors: IValidationError[] = []; if (!this.props.nativeCard && this.props.jsonCard) { + this.props.jsonCard.version = this.props.jsonCard.version || '0.5'; adaptiveCard.parse(cardWithoutHttpActions(this.props.jsonCard)); errors = adaptiveCard.validate(); } From f6e097e2ad1ea3d19885511574212d3d55d59d9a Mon Sep 17 00:00:00 2001 From: William Wong Date: Wed, 17 Jan 2018 12:45:37 -0800 Subject: [PATCH 14/20] Fix broken build --- src/AdaptiveCardContainer.tsx | 8 ++++---- src/Attachment.tsx | 4 ++-- src/CardBuilder.tsx | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index 92f75500a0..5f0496f294 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import { Action, AdaptiveCard, HostConfig, IValidationError, OpenUrlAction, SubmitAction } from "adaptivecards"; -import { IActionBase, IActionShowCard, IAdaptiveCard } from "adaptivecards/lib/schema"; -import { CardAction } from "botframework-directlinejs/built/directLine"; -import { classList, IDoCardAction } from "./Chat"; +import { Action, AdaptiveCard, HostConfig, IValidationError, OpenUrlAction, SubmitAction } from 'adaptivecards'; +import { IActionBase, IActionShowCard, IAdaptiveCard } from 'adaptivecards/lib/schema'; +import { CardAction } from 'botframework-directlinejs/built/directLine'; +import { classList, IDoCardAction } from './Chat'; import { AjaxResponse, AjaxRequest } from 'rxjs/observable/dom/AjaxObservable'; import * as adaptivecardsHostConfig from '../adaptivecards-hostconfig.json'; import * as konsole from './Konsole'; diff --git a/src/Attachment.tsx b/src/Attachment.tsx index e36d65b89c..fa5a315c37 100644 --- a/src/Attachment.tsx +++ b/src/Attachment.tsx @@ -200,7 +200,7 @@ export const AttachmentView = (props: { return null; const heroCardBuilder = new CardBuilder.AdaptiveCardBuilder(); if (attachment.content.images) { - attachment.content.images.forEach(img => heroCardBuilder.addImage(img)); + attachment.content.images.forEach(img => heroCardBuilder.addImage(img.url, null, img.tap)); } heroCardBuilder.addCommon(attachment.content) return ( @@ -215,7 +215,7 @@ export const AttachmentView = (props: { const columns = thumbnailCardBuilder.addColumnSet([75, 25]); thumbnailCardBuilder.addTextBlock(attachment.content.title, { size: TextSize.Medium, weight: TextWeight.Bolder }, columns[0]); thumbnailCardBuilder.addTextBlock(attachment.content.subtitle, { isSubtle: true, wrap: true }, columns[0]); - thumbnailCardBuilder.addImage(attachment.content.images[0], columns[1]); + thumbnailCardBuilder.addImage(attachment.content.images[0].url, columns[1], attachment.content.images[0].tap); thumbnailCardBuilder.addTextBlock(attachment.content.text, { wrap: true }); thumbnailCardBuilder.addButtons(attachment.content.buttons); } else { diff --git a/src/CardBuilder.tsx b/src/CardBuilder.tsx index f24ebaad7c..00c97c6d76 100644 --- a/src/CardBuilder.tsx +++ b/src/CardBuilder.tsx @@ -46,7 +46,7 @@ export class AdaptiveCardBuilder { addButtons(cardActions: CardAction[]) { if (cardActions) { cardActions.forEach(cardAction => { - this.card.addAction(AdaptiveCardBuilder.addCardAction(cardAction); + this.card.addAction(AdaptiveCardBuilder.addCardAction(cardAction)); }); } } From 915574f2914f242704355df7ffe5af7246d9a71b Mon Sep 17 00:00:00 2001 From: William Wong Date: Sat, 20 Jan 2018 21:21:59 -0800 Subject: [PATCH 15/20] Fix broken test --- src/Attachment.tsx | 2 +- test/commands_map.ts | 35 +++++++++++------------------------ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/Attachment.tsx b/src/Attachment.tsx index fa5a315c37..e155683e94 100644 --- a/src/Attachment.tsx +++ b/src/Attachment.tsx @@ -272,7 +272,7 @@ export const AttachmentView = (props: { attachment.content.items && attachment.content.items.map((item, i) => { if (item.image) { const columns2 = receiptCardBuilder.addColumnSet([15, 75, 10]); - receiptCardBuilder.addImage(item.image.url, columns2[0]); + receiptCardBuilder.addImage(item.image.url, columns2[0], item.image.tap); receiptCardBuilder.addTextBlock(item.title, { size: TextSize.Medium, weight: TextWeight.Bolder, wrap: true }, columns2[1]); receiptCardBuilder.addTextBlock(item.subtitle, { size: TextSize.Medium, wrap: true }, columns2[1]); receiptCardBuilder.addTextBlock(item.price, { horizontalAlignment: HorizontalAlignment.Right }, columns2[2]); diff --git a/test/commands_map.ts b/test/commands_map.ts index 91780a2d3e..64e7b9fc6e 100644 --- a/test/commands_map.ts +++ b/test/commands_map.ts @@ -132,9 +132,7 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - const new_win = await windows[1]; - console.log("Window 2 Title: " + new_win.title); - return new_win.title.indexOf('Bot Chat') === -1; + return windows.some(win => !~win.title.indexOf('Bot Chat')); }, server: function (conversationId, sendActivity) { sendActivity(conversationId, server_content.receipt_card); @@ -274,9 +272,7 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - const new_win = await windows[1]; - console.log("Window 2 Title: " + new_win.title); - return !!~new_win.title.indexOf('OpenUrl2'); + return windows.some(window => ~window.title.indexOf('OpenUrl2')); }, server: function (conversationId, sendActivity) { sendActivity(conversationId, server_content.hero_card); @@ -292,9 +288,7 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - const new_win = await windows[1]; - console.log("Window 2 Title: " + new_win.title); - return !!~new_win.title.indexOf('OpenUrl1'); + return windows.some(window => ~window.title.indexOf('OpenUrl1')); }, server: function (conversationId, sendActivity) { sendActivity(conversationId, server_content.hero_card); @@ -478,9 +472,7 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - const new_win = await windows[1]; - console.log("Window 2 Title: " + new_win.title); - return !!~new_win.title.indexOf('OpenUrl2'); + return windows.some(window => ~window.title.indexOf('OpenUrl2')); }, server: function (conversationId, sendActivity) { sendActivity(conversationId, server_content.receipt_card); @@ -496,9 +488,8 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - const new_win = await windows[1]; - console.log("Window 2 Title: " + new_win.title); - return !!~new_win.title.indexOf('OpenUrl1'); + console.log(windows); + return windows.some(window => ~window.title.indexOf('OpenUrl1')); }, server: function (conversationId, sendActivity) { sendActivity(conversationId, server_content.receipt_card); @@ -532,9 +523,7 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - const new_win = await windows[1]; - console.log("Window 2 Title: " + new_win.title); - return !!~new_win.title.indexOf('OpenUrl2'); + return windows.some(window => ~window.title.indexOf('OpenUrl2')); }, server: function (conversationId, sendActivity) { sendActivity(conversationId, server_content.thumbnail_card); @@ -550,9 +539,7 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - const new_win = await windows[1]; - console.log("Window 2 Title: " + new_win.title); - return !!~new_win.title.indexOf('OpenUrl1'); + return windows.some(window => ~window.title.indexOf('OpenUrl1')); }, server: function (conversationId, sendActivity) { sendActivity(conversationId, server_content.thumbnail_card); @@ -630,7 +617,7 @@ var commands_map: CommandValuesMap = { }, "card BingSports": { client: function () { - return (document.querySelector('.wc-adaptive-card .ac-container p').innerHTML === 'Seattle vs Panthers'); + return [].some.call(document.querySelectorAll('.wc-adaptive-card .ac-container div'), element => element.innerHTML === 'Seattle vs Panthers'); }, server: function (conversationId, sendActivity, json) { sendActivity(conversationId, server_content.adaptive_cardsFn(json)); @@ -650,7 +637,7 @@ var commands_map: CommandValuesMap = { }, "card Inputs": { client: function () { - return (document.querySelector('.wc-adaptive-card .ac-container p').innerHTML === 'Input.Text elements'); + return [].some.call(document.querySelectorAll('.wc-adaptive-card .ac-container div'), element => element.innerHTML === 'Input.Text elements'); }, server: function (res, sendActivity, json) { sendActivity(res, server_content.adaptive_cardsFn(json)); @@ -763,4 +750,4 @@ if (testOnly && testOnly.length > 0) { for (var key in commands_map) if (testOnly.indexOf(key) < 0) delete commands_map[key]; } -module.exports = commands_map; \ No newline at end of file +module.exports = commands_map; From fc7b6bdf173eb89598a5fa60849fb913ce9bd019 Mon Sep 17 00:00:00 2001 From: William Wong Date: Sun, 21 Jan 2018 00:13:47 -0800 Subject: [PATCH 16/20] Expose HostConfig in React props --- src/AdaptiveCardContainer.tsx | 108 +++++++++++++++++++++++++++------- src/Attachment.tsx | 2 +- src/Chat.tsx | 23 +++++++- src/Store.ts | 50 ++++++++++++---- 4 files changed, 150 insertions(+), 33 deletions(-) diff --git a/src/AdaptiveCardContainer.tsx b/src/AdaptiveCardContainer.tsx index 5f0496f294..e247eb2634 100644 --- a/src/AdaptiveCardContainer.tsx +++ b/src/AdaptiveCardContainer.tsx @@ -1,4 +1,6 @@ import * as React from 'react'; +import { findDOMNode } from 'react-dom'; +import { connect } from 'react-redux'; import { Action, AdaptiveCard, HostConfig, IValidationError, OpenUrlAction, SubmitAction } from 'adaptivecards'; import { IActionBase, IActionShowCard, IAdaptiveCard } from 'adaptivecards/lib/schema'; import { CardAction } from 'botframework-directlinejs/built/directLine'; @@ -6,14 +8,16 @@ import { classList, IDoCardAction } from './Chat'; import { AjaxResponse, AjaxRequest } from 'rxjs/observable/dom/AjaxObservable'; import * as adaptivecardsHostConfig from '../adaptivecards-hostconfig.json'; import * as konsole from './Konsole'; +import { ChatState, AdaptiveCardsState } from './Store'; export interface Props { - nativeCard?: AdaptiveCard, + className?: string, + hostConfig: HostConfig, jsonCard?: IAdaptiveCard, - onImageLoad?: () => any, - onClick?: (e: React.MouseEvent) => void, + nativeCard?: AdaptiveCard, onCardAction: IDoCardAction, - className?: string + onClick?: (e: React.MouseEvent) => void, + onImageLoad?: () => any, } export interface State { @@ -24,7 +28,7 @@ export interface BotFrameworkCardAction extends CardAction { __isBotFrameworkCardAction: boolean } -const hostConfig = new HostConfig(adaptivecardsHostConfig); +const defaultHostConfig = new HostConfig(adaptivecardsHostConfig); function cardWithoutHttpActions(card: IAdaptiveCard) { if (!card.actions) return card; @@ -41,15 +45,26 @@ function cardWithoutHttpActions(card: IAdaptiveCard) { return { ...card, actions }; } -export class AdaptiveCardContainer extends React.Component { - private div: HTMLDivElement; +class AdaptiveCardContainer extends React.Component { + private divRef: React.ReactInstance; constructor(props: Props) { super(props); + + this.handleImageLoad = this.handleImageLoad.bind(this); + this.onClick = this.onClick.bind(this); + this.saveDiv = this.saveDiv.bind(this); + } + + private saveDiv(divRef: React.ReactInstance) { + this.divRef = divRef; } private onClick(e: React.MouseEvent) { - if (!this.props.onClick) return; + if (!this.props.onClick) { + return; + } + //do not allow form elements to trigger a parent click event switch ((e.target as HTMLElement).tagName) { case 'A': @@ -61,6 +76,7 @@ export class AdaptiveCardContainer extends React.Component { case 'TEXTAREA': case 'SELECT': break; + default: this.props.onClick(e); } @@ -73,6 +89,7 @@ export class AdaptiveCardContainer extends React.Component { if (action.data !== undefined) { if (typeof action.data === 'object' && (action.data as BotFrameworkCardAction).__isBotFrameworkCardAction) { const cardAction = (action.data as BotFrameworkCardAction); + this.props.onCardAction(cardAction.type, cardAction.value); } else { this.props.onCardAction(typeof action.data === 'string' ? 'imBack' : 'postBack', action.data); @@ -80,44 +97,82 @@ export class AdaptiveCardContainer extends React.Component { } } } + componentDidMount() { + this.mountAdaptiveCards(); + } + + componentDidUpdate(prevProps: Props) { + if ( + prevProps.hostConfig !== this.props.hostConfig + || prevProps.jsonCard !== this.props.jsonCard + || prevProps.nativeCard !== this.props.nativeCard + ) { + this.unmountAdaptiveCards(); + this.mountAdaptiveCards(); + } + } + + handleImageLoad() { + this.props.onImageLoad && this.props.onImageLoad.apply(this, arguments); + } + + unmountAdaptiveCards() { + const divElement = findDOMNode(this.divRef); + + [].forEach.call(divElement.children, (child: any) => divElement.removeChild(child)); + } + + mountAdaptiveCards() { const adaptiveCard = this.props.nativeCard || new AdaptiveCard(); - adaptiveCard.hostConfig = hostConfig; + + adaptiveCard.hostConfig = this.props.hostConfig || defaultHostConfig; + let errors: IValidationError[] = []; + if (!this.props.nativeCard && this.props.jsonCard) { this.props.jsonCard.version = this.props.jsonCard.version || '0.5'; adaptiveCard.parse(cardWithoutHttpActions(this.props.jsonCard)); errors = adaptiveCard.validate(); } + adaptiveCard.onExecuteAction = (action) => this.onExecuteAction(action); + if (errors.length === 0) { let renderedCard: HTMLElement; + try { renderedCard = adaptiveCard.render(); - } - catch (e) { + } catch (e) { const ve: IValidationError = { error: -1, message: e }; + errors.push(ve); + if (e.stack) { ve.message += '\n' + e.stack; } } + if (renderedCard) { if (this.props.onImageLoad) { var imgs = renderedCard.querySelectorAll('img'); + if (imgs && imgs.length > 0) { Array.prototype.forEach.call(imgs, (img: HTMLImageElement) => { - img.addEventListener('load', this.props.onImageLoad); + img.addEventListener('load', this.handleImageLoad); }); } } - this.div.appendChild(renderedCard); + + findDOMNode(this.divRef).appendChild(renderedCard); + return; } } + if (errors.length > 0) { console.log('Error(s) rendering AdaptiveCard:'); errors.forEach(e => console.log(e.message)); @@ -128,6 +183,7 @@ export class AdaptiveCardContainer extends React.Component { render() { let wrappedChildren: JSX.Element; const hasErrors = this.state && this.state.errors && this.state.errors.length > 0; + if (hasErrors) { wrappedChildren = (
@@ -140,20 +196,32 @@ export class AdaptiveCardContainer extends React.Component { } else if (this.props.children) { wrappedChildren = (
- {this.props.children} + { this.props.children }
); } else { wrappedChildren = null; } + return ( -
this.div = div} onClick={e => this.onClick(e)}> - {wrappedChildren} +
+ { wrappedChildren } +
) } - - componentDidUpdate() { - if (this.props.onImageLoad) this.props.onImageLoad(); - } } + +export default connect( + (state: ChatState) => ({ + hostConfig: state.adaptiveCards.hostConfig + }), + {}, + (stateProps: any, dispatchProps: any, ownProps: any): Props => ({ + ...ownProps, + ...stateProps + }) +)(AdaptiveCardContainer); diff --git a/src/Attachment.tsx b/src/Attachment.tsx index e155683e94..5aace58a20 100644 --- a/src/Attachment.tsx +++ b/src/Attachment.tsx @@ -4,7 +4,7 @@ import { HorizontalAlignment, IAdaptiveCard, TextSize, TextWeight } from 'adapti import { Attachment, CardAction, CardImage, KnownMedia, UnknownMedia } from 'botframework-directlinejs'; import { renderIfNonempty, IDoCardAction } from './Chat'; import { FormatState } from './Store'; -import { AdaptiveCardContainer } from './AdaptiveCardContainer'; +import { default as AdaptiveCardContainer } from './AdaptiveCardContainer'; import * as konsole from './Konsole'; const regExpCard = /\^application\/vnd\.microsoft\.card\./i; diff --git a/src/Chat.tsx b/src/Chat.tsx index 8e6a8c9063..17829b2a9c 100644 --- a/src/Chat.tsx +++ b/src/Chat.tsx @@ -15,6 +15,7 @@ import * as konsole from './Konsole'; import { getTabIndex } from './getTabIndex'; export interface ChatProps { + adaptiveCardsHostConfig: any, user: User, bot: User, botConnection?: IBotConnection, @@ -62,11 +63,20 @@ export class Chat extends React.Component { locale: props.locale || (window.navigator as any)["userLanguage"] || window.navigator.language || 'en' }); - if (props.formatOptions) + if (props.adaptiveCardsHostConfig) { + this.store.dispatch({ + type: 'Set_AdaptiveCardsHostConfig', + payload: props.adaptiveCardsHostConfig + }); + } + + if (props.formatOptions) { this.store.dispatch({ type: 'Set_Format_Options', options: props.formatOptions }); + } - if (props.sendTyping) + if (props.sendTyping) { this.store.dispatch({ type: 'Set_Send_Typing', sendTyping: props.sendTyping }); + } if (props.speechOptions) { Speech.SpeechRecognizer.setSpeechRecognizer(props.speechOptions.speechRecognizer); @@ -207,6 +217,15 @@ export class Chat extends React.Component { window.removeEventListener('resize', this.resizeListener); } + componentWillReceiveProps(nextProps: ChatProps) { + if (this.props.adaptiveCardsHostConfig !== nextProps.adaptiveCardsHostConfig) { + this.store.dispatch({ + type: 'Set_AdaptiveCardsHostConfig', + payload: nextProps.adaptiveCardsHostConfig + }); + } + } + // At startup we do three render passes: // 1. To determine the dimensions of the chat panel (nothing needs to actually render here, so we don't) // 2. To determine the margins of any given carousel (we just render one mock activity so that we can measure it) diff --git a/src/Store.ts b/src/Store.ts index 13da314c22..dd0356037f 100644 --- a/src/Store.ts +++ b/src/Store.ts @@ -3,6 +3,7 @@ import { strings, defaultStrings, Strings } from './Strings'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Speech } from './SpeechModule'; import { ActivityOrID, FormatOptions } from './Types'; +import { HostConfig } from 'adaptivecards'; import * as konsole from './Konsole'; // Reducers - perform state transformations @@ -430,16 +431,45 @@ export const history: Reducer = ( } } -export type ChatActions = ShellAction | FormatAction | SizeAction | ConnectionAction | HistoryAction; +export interface AdaptiveCardsState { + hostConfig: HostConfig +} + +export type AdaptiveCardsAction = { + type: 'Set_AdaptiveCardsHostConfig', + payload: any +} + +export const adaptiveCards: Reducer = ( + state: AdaptiveCardsState = { + hostConfig: null + }, + action: AdaptiveCardsAction +) => { + switch (action.type) { + case 'Set_AdaptiveCardsHostConfig': + return { + ...state, + hostConfig: action.payload && (action.payload instanceof HostConfig ? action.payload : new HostConfig(action.payload)) + }; + + default: + return state; + } +} + + +export type ChatActions = ShellAction | FormatAction | SizeAction | ConnectionAction | HistoryAction | AdaptiveCardsAction; const nullAction = { type: null } as ChatActions; export interface ChatState { - shell: ShellState, - format: FormatState, - size: SizeState, + adaptiveCards: AdaptiveCardsState, connection: ConnectionState, - history: HistoryState + format: FormatState, + history: HistoryState, + shell: ShellState, + size: SizeState } const speakFromMsg = (msg: Message, fallbackLocale: string) => { @@ -639,11 +669,12 @@ import { combineEpics, createEpicMiddleware } from 'redux-observable'; export const createStore = () => reduxCreateStore( combineReducers({ - shell, - format, - size, + adaptiveCards, connection, - history + format, + history, + shell, + size }), applyMiddleware(createEpicMiddleware(combineEpics( updateSelectedActivityEpic, @@ -662,4 +693,3 @@ export const createStore = () => ); export type ChatStore = Store; - From 0df032ec658cdd052354c3f37230e2221af215bb Mon Sep 17 00:00:00 2001 From: William Wong Date: Mon, 22 Jan 2018 15:13:00 -0800 Subject: [PATCH 17/20] Add hostconfig test --- test/commands_map.ts | 17 ++++- test/test.html | 160 ++++++++++++++++++++++++++++++------------- 2 files changed, 127 insertions(+), 50 deletions(-) diff --git a/test/commands_map.ts b/test/commands_map.ts index 64e7b9fc6e..4f79d03721 100644 --- a/test/commands_map.ts +++ b/test/commands_map.ts @@ -488,7 +488,6 @@ var commands_map: CommandValuesMap = { evalOtherWindow: async function (nightmare) { const windows_fn = await nightmare['windows'].bind(nightmare); const windows = await windows_fn(); - console.log(windows); return windows.some(window => ~window.title.indexOf('OpenUrl1')); }, server: function (conversationId, sendActivity) { @@ -714,6 +713,22 @@ var commands_map: CommandValuesMap = { client: function () { return !!document.querySelector('.wc-message-groups:focus'); } + }, + 'hostconfig': { + server: function (conversationId, sendActivity) { + sendActivity(conversationId, server_content.hero_card); + }, + do: function (nightmare) { + nightmare + .evaluate(() => { + window['WebChatTest'].changeHostConfig({ fontFamily: 'serif' }); + }); + }, + client: function () { + var titleElement = [].find.call(document.querySelectorAll('.wc-adaptive-card .ac-container div'), element => element.innerHTML === 'Details about image 1'); + + return titleElement && window.getComputedStyle(titleElement)['font-family'] === 'serif'; + } } /* ** Add your commands to test here ** diff --git a/test/test.html b/test/test.html index d77fcffc48..1f8de0c6c9 100644 --- a/test/test.html +++ b/test/test.html @@ -1,81 +1,143 @@  - - - + - Bot Chat + Bot Chat + - - + + + + + +
+ - - - - \ No newline at end of file + + From 452de5c6d20d23720d83722e1d05a7493b1b93cd Mon Sep 17 00:00:00 2001 From: William Wong Date: Mon, 22 Jan 2018 15:34:35 -0800 Subject: [PATCH 18/20] Update package-lock.json --- package-lock.json | 92 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 83d2155095..03178a1261 100644 --- a/package-lock.json +++ b/package-lock.json @@ -106,12 +106,9 @@ } }, "adaptivecards": { - "version": "1.0.0-beta2", - "resolved": "https://registry.npmjs.org/adaptivecards/-/adaptivecards-1.0.0-beta2.tgz", - "integrity": "sha512-0U6rUDxMHCNI74WZGoz3lEn/HIFjvggqftB3UIiiYgaKbQF3CDy8sEia4qTF2RI5zeHhtaGzqQurpbiZGD+QDQ==", - "requires": { - "markdown-it": "8.3.1" - } + "version": "1.0.0-beta9", + "resolved": "https://registry.npmjs.org/adaptivecards/-/adaptivecards-1.0.0-beta9.tgz", + "integrity": "sha1-vCL2GXjFhmbI6GLJrVtLQ7C2H6g=" }, "ajv": { "version": "5.3.0", @@ -3769,6 +3766,27 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, "caseless": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", @@ -3794,6 +3812,26 @@ "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", "dev": true }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, "har-validator": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", @@ -3815,6 +3853,35 @@ "ansi-regex": "2.1.1" } }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, "node-sass": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.7.2.tgz", @@ -3854,12 +3921,16 @@ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", "dev": true, "requires": { + "aws-sign2": "0.6.0", "aws4": "1.6.0", "caseless": "0.11.0", "combined-stream": "1.0.5", "extend": "3.0.1", "forever-agent": "0.6.1", + "form-data": "2.1.4", "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", @@ -3872,6 +3943,15 @@ "uuid": "3.1.0" } }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", From 559f9743a049c9e204b505088196f1170bcc3b7c Mon Sep 17 00:00:00 2001 From: William Wong Date: Mon, 22 Jan 2018 15:40:22 -0800 Subject: [PATCH 19/20] Update README.md --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b4c02ffc3..1c71e173f5 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,23 @@ In the `/src/scss/` folder you will find the source files for generating `/botch #### Card Layout -Web Chat uses [AdaptiveCards](https://adaptivecards.io) that let the bot developer create cards with advanced layout and interactive capabilities. For more details, see [AdaptiveCards.md](AdaptiveCards.md) +Web Chat uses [Adaptive Cards](https://adaptivecards.io) that let the bot developer create cards with advanced layout and interactive capabilities. For more details, see [AdaptiveCards.md](AdaptiveCards.md) + +##### To customize styles with your own [`hostconfig.json`](https://docs.microsoft.com/en-us/adaptive-cards/display/hostconfig): + +```js +BotChat.App({ + adaptiveCardsHostConfig: { + fontFamily: '"Myriad Pro", sans-serif' + } +}, document.getElementById('BotChatGoesHere')); +``` + +Or alternatively, in React. + +```jsx + +``` #### Card Sizes / Responsiveness From a39918f92608ebf4cd76cfb88ff499d8be2b263f Mon Sep 17 00:00:00 2001 From: William Wong Date: Mon, 22 Jan 2018 15:49:28 -0800 Subject: [PATCH 20/20] Update README.md --- AdaptiveCards.md | 21 ++++++++++++++++----- README.md | 16 ---------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/AdaptiveCards.md b/AdaptiveCards.md index dfe4ada71b..0e3ba5c439 100644 --- a/AdaptiveCards.md +++ b/AdaptiveCards.md @@ -62,7 +62,7 @@ You may wish to create your Host Configuration using SCSS in this repo. This met ### Optional: Embed without webpack -It is also possible to supply an Adaptive Cards Host Configuration without the need to webpack. Start with the [basic example from the readme](https://github.com/Microsoft/BotFramework-WebChat#easy-in-your-non-react-website-run-web-chat-inline), then add some script prior to instantiating `BotChat.App`: +It is also possible to supply an Adaptive Cards Host Configuration without the need to webpack. Start with the [basic example from the readme](https://github.com/Microsoft/BotFramework-WebChat#easy-in-your-non-react-website-run-web-chat-inline), then add `adaptiveCardsHostConfig` prop when instantiating `BotChat.App`: ```HTML @@ -74,11 +74,10 @@ It is also possible to supply an Adaptive Cards Host Configuration without the n