diff options
author | bobzel <zzzman@gmail.com> | 2019-02-27 00:01:11 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-27 00:01:11 -0500 |
commit | 609dc8f234f6eafdd5c7ed3f7040fff169bf266a (patch) | |
tree | 133da1d566c0fb37e14c84494aa14edef7ed6bd8 | |
parent | 04ee2ad6e7ca887c3cfc7277c4b382f936c0fa6d (diff) | |
parent | 14d6495e4d4b9d38a37187a50ebeb84057abbc20 (diff) |
Merge pull request #7 from browngraphicslab/web_box
Web box
-rw-r--r-- | .DS_Store | bin | 0 -> 6148 bytes | |||
-rw-r--r-- | package-lock.json | 119 | ||||
-rw-r--r-- | src/.DS_Store | bin | 0 -> 6148 bytes | |||
-rw-r--r-- | src/client/documents/Documents.ts | 221 | ||||
-rw-r--r-- | src/client/util/DragManager.ts | 8 | ||||
-rw-r--r-- | src/client/views/Main.tsx | 18 | ||||
-rw-r--r-- | src/client/views/collections/CollectionFreeFormView.tsx | 7 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/nodes/FieldView.tsx | 13 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 1 | ||||
-rw-r--r-- | src/client/views/nodes/WebBox.scss | 14 | ||||
-rw-r--r-- | src/client/views/nodes/WebBox.tsx | 38 | ||||
-rw-r--r-- | src/client/views/nodes/WebView.tsx | 22 | ||||
-rw-r--r-- | src/fields/Document.ts | 5 | ||||
-rw-r--r-- | src/fields/WebField.ts | 30 | ||||
-rw-r--r-- | src/server/Message.ts | 2 | ||||
-rw-r--r-- | src/server/ServerUtil.ts | 3 |
17 files changed, 331 insertions, 176 deletions
diff --git a/.DS_Store b/.DS_Store Binary files differnew file mode 100644 index 000000000..8493b4a74 --- /dev/null +++ b/.DS_Store diff --git a/package-lock.json b/package-lock.json index d74c77819..4f3176751 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,8 @@ "integrity": "sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==", "requires": { "regenerator-runtime": "^0.12.0" +<<<<<<< HEAD +======= }, "dependencies": { "regenerator-runtime": { @@ -17,6 +19,7 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" } +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "@fortawesome/fontawesome-common-types": { @@ -67,6 +70,8 @@ "requires": { "@types/connect": "*", "@types/node": "*" +<<<<<<< HEAD +======= } }, "@types/bson": { @@ -75,6 +80,7 @@ "integrity": "sha512-j+UcCWI+FsbI5/FQP/Kj2CXyplWAz39ktHFkXk84h7dNblKRSoNJs95PZFRd96NQGqsPEPgeclqnznWZr14ZDA==", "requires": { "@types/node": "*" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "@types/caseless": { @@ -94,6 +100,8 @@ "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", "requires": { "@types/node": "*" +<<<<<<< HEAD +======= } }, "@types/connect-flash": { @@ -102,6 +110,7 @@ "integrity": "sha512-QC93TwnTZ0sk//bfT81o7U4GOedbOZAcgvqi0v1vJqCESC8tqIVnhzB1CHiAUBUWFjoxG5JQF0TYaNa6DMb6Ig==", "requires": { "@types/express": "*" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "@types/express": { @@ -112,6 +121,8 @@ "@types/body-parser": "*", "@types/express-serve-static-core": "*", "@types/serve-static": "*" +<<<<<<< HEAD +======= } }, "@types/express-flash": { @@ -121,6 +132,7 @@ "requires": { "@types/connect-flash": "*", "@types/express": "*" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "@types/express-serve-static-core": { @@ -130,6 +142,8 @@ "requires": { "@types/node": "*", "@types/range-parser": "*" +<<<<<<< HEAD +======= } }, "@types/express-session": { @@ -155,6 +169,7 @@ "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", "requires": { "@types/node": "*" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "@types/jquery": { @@ -163,6 +178,8 @@ "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", "requires": { "@types/sizzle": "*" +<<<<<<< HEAD +======= } }, "@types/jsonwebtoken": { @@ -171,6 +188,7 @@ "integrity": "sha512-YKnUTR4VxwljbPORPrRon9E3uel1aD8nUdvzqArCCdMTWPvo0gnI2UZkwIHN2QATdj6HYXV/Iq3/KcecAO42Ww==", "requires": { "@types/node": "*" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "@types/lodash": { @@ -378,6 +396,8 @@ "integrity": "sha512-XiYCcn/CBajrj18vLA3kO79AHr5yZTCJe2kl87ZNTRxLO14y9D0IGeGZ3xLsqhfYrJSkkVzAJV8v+bQ4nuKCRQ==", "requires": { "@types/react": "*" +<<<<<<< HEAD +======= } }, "@types/request": { @@ -389,6 +409,7 @@ "@types/form-data": "*", "@types/node": "*", "@types/tough-cookie": "*" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "@types/serve-static": { @@ -1204,6 +1225,8 @@ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "requires": { "tweetnacl": "^0.14.3" +<<<<<<< HEAD +======= } }, "better-assert": { @@ -1212,6 +1235,7 @@ "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", "requires": { "callsite": "1.0.0" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "big.js": { @@ -1639,6 +1663,8 @@ "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" +<<<<<<< HEAD +======= } }, "character-parser": { @@ -1647,6 +1673,7 @@ "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", "requires": { "is-regex": "^1.0.3" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "check-error": { @@ -2587,6 +2614,8 @@ "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" +<<<<<<< HEAD +======= } }, "ecdsa-sig-formatter": { @@ -2595,6 +2624,7 @@ "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", "requires": { "safe-buffer": "^5.0.1" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "ee-first": { @@ -2639,6 +2669,8 @@ "dev": true, "requires": { "once": "^1.4.0" +<<<<<<< HEAD +======= } }, "engine.io": { @@ -2702,6 +2734,7 @@ "base64-arraybuffer": "0.1.5", "blob": "0.0.5", "has-binary2": "~1.0.2" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "enhanced-resolve": { @@ -2991,6 +3024,8 @@ "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", "requires": { +<<<<<<< HEAD +======= "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", @@ -3026,6 +3061,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "requires": { +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" }, @@ -3139,6 +3175,8 @@ "promise": "^7.0.3", "ua-parser-js": "^0.7.9", "whatwg-fetch": "^0.9.0" +<<<<<<< HEAD +======= }, "dependencies": { "core-js": { @@ -3146,6 +3184,7 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" } +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "figgy-pudding": { @@ -4074,6 +4113,8 @@ "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" +<<<<<<< HEAD +======= } }, "has": { @@ -4082,6 +4123,7 @@ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "requires": { "function-bind": "^1.1.1" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "has-ansi": { @@ -4090,6 +4132,8 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { "ansi-regex": "^2.0.0" +<<<<<<< HEAD +======= } }, "has-binary2": { @@ -4105,6 +4149,7 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" } +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "has-cors": { @@ -4853,6 +4898,8 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "requires": { "minimist": "^1.2.0" +<<<<<<< HEAD +======= } }, "jsonwebtoken": { @@ -4876,6 +4923,7 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" } +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "jsprim": { @@ -5540,6 +5588,8 @@ "dev": true, "requires": { "has-flag": "^3.0.0" +<<<<<<< HEAD +======= } } } @@ -5589,6 +5639,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "requires": { "lodash": "^4.17.10" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "ms": { @@ -5615,6 +5666,8 @@ "mkdirp": "^0.5.1", "rimraf": "^2.5.4", "run-queue": "^1.0.3" +<<<<<<< HEAD +======= } }, "mpath": { @@ -5647,6 +5700,7 @@ "ms": "2.0.0" } } +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "ms": { @@ -6553,8 +6607,12 @@ }, "copy-concurrently": { "version": "1.0.5", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", @@ -7020,8 +7078,12 @@ }, "gauge": { "version": "2.7.4", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -7057,8 +7119,12 @@ }, "gentle-fs": { "version": "2.0.1", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/gentle-fs/-/gentle-fs-2.0.1.tgz", "integrity": "sha512-cEng5+3fuARewXktTEGbwsktcldA+YsnUEaXZwcK/3pjSE1X9ObnTs+/8rYf8s+RnIcQm2D5x3rwpN7Zom8Bew==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "aproba": "^1.1.2", "fs-vacuum": "^1.2.10", @@ -7126,8 +7192,12 @@ }, "got": { "version": "6.7.1", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "create-error-class": "^3.0.0", "duplexer3": "^0.1.4", @@ -7470,8 +7540,12 @@ }, "libcipm": { "version": "3.0.3", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/libcipm/-/libcipm-3.0.3.tgz", "integrity": "sha512-71V5CpTI+zFydTc5IjJ/tx8JHbXEJvmYF2zaSVW1V3X1rRnRjXqh44iuiyry1xgi3ProUQ1vX1uwFiWs00+2og==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "bin-links": "^1.1.2", "bluebird": "^3.5.1", @@ -7492,8 +7566,12 @@ }, "libnpm": { "version": "2.0.1", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/libnpm/-/libnpm-2.0.1.tgz", "integrity": "sha512-qTKoxyJvpBxHZQB6k0AhSLajyXq9ZE/lUsZzuHAplr2Bpv9G+k4YuYlExYdUCeVRRGqcJt8hvkPh4tBwKoV98w==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "bin-links": "^1.1.2", "bluebird": "^3.5.3", @@ -7795,8 +7873,12 @@ }, "make-fetch-happen": { "version": "4.0.1", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz", "integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "agentkeepalive": "^3.4.1", "cacache": "^11.0.1", @@ -7906,8 +7988,12 @@ }, "move-concurrently": { "version": "1.0.1", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "aproba": "^1.1.1", "copy-concurrently": "^1.0.0", @@ -7946,8 +8032,12 @@ }, "node-gyp": { "version": "3.8.0", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "fstream": "^1.0.0", "glob": "^7.0.3", @@ -8037,8 +8127,12 @@ }, "npm-lifecycle": { "version": "2.1.0", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-2.1.0.tgz", "integrity": "sha512-QbBfLlGBKsktwBZLj6AviHC6Q9Y3R/AY4a2PYSIRhSKSS0/CxRyD/PfxEX6tPeOCXQgMSNdwGeECacstgptc+g==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "byline": "^5.0.0", "graceful-fs": "^4.1.11", @@ -8228,8 +8322,12 @@ }, "pacote": { "version": "9.4.0", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.0.tgz", "integrity": "sha512-WQ1KL/phGMkedYEQx9ODsjj7xvwLSpdFJJdEXrLyw5SILMxcTNt5DTxT2Z93fXuLFYJBlZJdnwdalrQdB/rX5w==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "bluebird": "^3.5.3", "cacache": "^11.3.2", @@ -8586,8 +8684,12 @@ }, "request": { "version": "2.88.0", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -8986,8 +9088,12 @@ }, "tar": { "version": "4.4.8", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", @@ -9334,8 +9440,12 @@ }, "yargs": { "version": "11.0.0", +<<<<<<< HEAD + "bundled": true, +======= "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 "requires": { "cliui": "^4.0.0", "decamelize": "^1.1.1", @@ -10103,6 +10213,8 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" +<<<<<<< HEAD +======= } }, "pug": { @@ -10212,6 +10324,7 @@ "integrity": "sha1-8VWVkiBu3G+FMQ2s9K+0igJa9Z8=", "requires": { "pug-error": "^1.3.2" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "pug-walk": { @@ -11138,6 +11251,8 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { "is-buffer": "^1.1.5" +<<<<<<< HEAD +======= } } } @@ -11222,6 +11337,7 @@ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { "ms": "2.0.0" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "isarray": { @@ -13247,6 +13363,8 @@ "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "signal-exit": "^3.0.2" +<<<<<<< HEAD +======= } }, "ws": { @@ -13255,6 +13373,7 @@ "integrity": "sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg==", "requires": { "async-limiter": "~1.0.0" +>>>>>>> bb418216efa9cc2e191b970e4cbe5080f4fd2b87 } }, "xdg-basedir": { diff --git a/src/.DS_Store b/src/.DS_Store Binary files differnew file mode 100644 index 000000000..4d6acb95a --- /dev/null +++ b/src/.DS_Store diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 9770e5cdc..8b733507b 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -7,10 +7,12 @@ import { ListField } from "../../fields/ListField"; import { FormattedTextBox } from "../views/nodes/FormattedTextBox"; import { ImageField } from "../../fields/ImageField"; import { ImageBox } from "../views/nodes/ImageBox"; +import { WebField } from "../../fields/WebField"; +import { WebBox } from "../views/nodes/WebBox"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; -import { FieldView } from "../views/nodes/FieldView"; import { HtmlField } from "../../fields/HtmlField"; -import { WebView } from "../views/nodes/WebView"; +import { Key } from "../../fields/Key" +import { Field } from "../../fields/Field"; export interface DocumentOptions { x?: number; @@ -20,109 +22,110 @@ export interface DocumentOptions { nativeWidth?: number; nativeHeight?: number; title?: string; + panx?: number; + pany?: number; + scale?: number; + layout?: string; + layoutKeys?: Key[]; + viewType?: number; } export namespace Documents { + let textProto: Document; + let imageProto: Document; + let webProto: Document; + let collProto: Document; + const textProtoId = "textProto"; + const imageProtoId = "imageProto"; + const webProtoId = "webProto"; + const collProtoId = "collectionProto"; + export function initProtos(callback: () => void) { - Server.GetFields([collectionProtoId, textProtoId, imageProtoId], (fields) => { - collectionProto = fields[collectionProtoId] as Document; + Server.GetFields([collProtoId, textProtoId, imageProtoId], (fields) => { + collProto = fields[collProtoId] as Document; imageProto = fields[imageProtoId] as Document; textProto = fields[textProtoId] as Document; + webProto = fields[webProtoId] as Document; callback() }); } + function assignOptions(doc: Document, options: DocumentOptions): Document { + if (options.x !== undefined) { doc.SetNumber(KeyStore.X, options.x); } + if (options.y !== undefined) { doc.SetNumber(KeyStore.Y, options.y); } + if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); } + if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); } + if (options.nativeWidth !== undefined) { doc.SetNumber(KeyStore.NativeWidth, options.nativeWidth); } + if (options.nativeHeight !== undefined) { doc.SetNumber(KeyStore.NativeHeight, options.nativeHeight); } + if (options.title !== undefined) { doc.SetText(KeyStore.Title, options.title); } + if (options.panx !== undefined) { doc.SetNumber(KeyStore.PanX, options.panx); } + if (options.pany !== undefined) { doc.SetNumber(KeyStore.PanY, options.pany); } + if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); } + if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); } + if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); } + if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); } + return doc; + } + function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document { + return assignOptions(new Document(protoId), { ...options, title: title, layout: layout }); + } + function SetInstanceOptions<T, U extends Field & { Data: T }>(doc: Document, options: DocumentOptions, value: T, ctor: { new(): U }, id?: string) { + var deleg = doc.MakeDelegate(id); + deleg.SetData(KeyStore.Data, value, ctor); + return assignOptions(deleg, options); + } - function setupOptions(doc: Document, options: DocumentOptions): void { - if (options.x !== undefined) { - doc.SetData(KeyStore.X, options.x, NumberField); - } - if (options.y !== undefined) { - doc.SetData(KeyStore.Y, options.y, NumberField); - } - if (options.width !== undefined) { - doc.SetData(KeyStore.Width, options.width, NumberField); - } - if (options.height !== undefined) { - doc.SetData(KeyStore.Height, options.height, NumberField); - } - if (options.nativeWidth !== undefined) { - doc.SetData(KeyStore.NativeWidth, options.nativeWidth, NumberField); - } - if (options.nativeHeight !== undefined) { - doc.SetData(KeyStore.NativeHeight, options.nativeHeight, NumberField); - } - if (options.title !== undefined) { - doc.SetData(KeyStore.Title, options.title, TextField); + function GetImagePrototype(): Document { + if (!imageProto) { + imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"), + { x: 0, y: 0, nativeWidth: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); + imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString()); } - doc.SetData(KeyStore.Scale, 1, NumberField); - doc.SetData(KeyStore.PanX, 0, NumberField); - doc.SetData(KeyStore.PanY, 0, NumberField); + return imageProto; } - - let textProto: Document; - const textProtoId = "textProto"; function GetTextPrototype(): Document { - if (!textProto) { - textProto = new Document(textProtoId); - textProto.Set(KeyStore.X, new NumberField(0)); - textProto.Set(KeyStore.Y, new NumberField(0)); - textProto.Set(KeyStore.Width, new NumberField(300)); - textProto.Set(KeyStore.Height, new NumberField(150)); - textProto.Set(KeyStore.Layout, new TextField(FormattedTextBox.LayoutString())); - textProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); - } - return textProto; + return textProto ? textProto : + textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }); } - - export function TextDocument(options: DocumentOptions = {}): Document { - let doc = GetTextPrototype().MakeDelegate(); - setupOptions(doc, options); - // doc.SetField(KeyStore.Data, new RichTextField()); - return doc; + function GetWebPrototype(): Document { + return webProto ? webProto : + webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 300, layoutKeys: [KeyStore.Data] }); } - - let htmlProto: Document; - const htmlProtoId = "htmlProto"; - function GetHtmlPrototype(): Document { - if (!htmlProto) { - htmlProto = new Document(htmlProtoId); - htmlProto.Set(KeyStore.X, new NumberField(0)); - htmlProto.Set(KeyStore.Y, new NumberField(0)); - htmlProto.Set(KeyStore.Width, new NumberField(300)); - htmlProto.Set(KeyStore.Height, new NumberField(150)); - htmlProto.Set(KeyStore.Layout, new TextField(WebView.LayoutString())); - htmlProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); - } - return htmlProto; + function GetCollectionPrototype(): Document { + return collProto ? collProto : + collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"), + { panx: 0, pany: 0, scale: 1, layoutKeys: [KeyStore.Data] }); } - export function HtmlDocument(html: string, options: DocumentOptions = {}): Document { - let doc = GetHtmlPrototype().MakeDelegate(); - setupOptions(doc, options); - doc.Set(KeyStore.Data, new HtmlField(html)); + export function ImageDocument(url: string, options: DocumentOptions = {}) { + let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, + new URL(url), ImageField); + doc.SetText(KeyStore.Caption, "my caption..."); + doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption()); + doc.SetText(KeyStore.OverlayLayout, FixedCaption()); return doc; } + export function TextDocument(options: DocumentOptions = {}) { + return SetInstanceOptions(GetTextPrototype(), options, "", TextField); + } + export function WebDocument(url: string, options: DocumentOptions = {}) { + return SetInstanceOptions(GetWebPrototype(), options, new URL(url), WebField); + } + export function HtmlDocument(html: string, options: DocumentOptions = {}) { + return SetInstanceOptions(GetWebPrototype(), options, html, HtmlField); + } + export function FreeformDocument(documents: Array<Document>, options: DocumentOptions, id?: string) { + return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, documents, ListField, id) + } + export function SchemaDocument(documents: Array<Document>, options: DocumentOptions, id?: string) { + return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Schema }, documents, ListField, id) + } + export function DockDocument(config: string, options: DocumentOptions, id?: string) { + return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, config, TextField, id) + } - let imageProto: Document; - const imageProtoId = "imageProto"; - function GetImagePrototype(): Document { - if (!imageProto) { - imageProto = new Document(imageProtoId); - imageProto.Set(KeyStore.Title, new TextField("IMAGE PROTO")); - imageProto.Set(KeyStore.X, new NumberField(0)); - imageProto.Set(KeyStore.Y, new NumberField(0)); - imageProto.Set(KeyStore.NativeWidth, new NumberField(300)); - imageProto.Set(KeyStore.Width, new NumberField(300)); - imageProto.Set(KeyStore.Layout, new TextField(CollectionView.LayoutString("AnnotationsKey"))); - imageProto.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) - imageProto.Set(KeyStore.BackgroundLayout, new TextField(ImageBox.LayoutString())); - // imageProto.SetField(KeyStore.Layout, new TextField('<div style={"background-image: " + {Data}} />')); - imageProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations])); - return imageProto; - } - return imageProto; - } // example of custom display string for an image that shows a caption. function EmbeddedCaption() { @@ -140,54 +143,4 @@ export namespace Documents { + FormattedTextBox.LayoutString("CaptionKey") + `</div> </div>` }; - - export function ImageDocument(url: string, options: DocumentOptions = {}): Document { - let doc = GetImagePrototype().MakeDelegate(); - setupOptions(doc, options); - doc.Set(KeyStore.Data, new ImageField(new URL(url))); - doc.Set(KeyStore.Caption, new TextField("my caption...")); - doc.Set(KeyStore.BackgroundLayout, new TextField(EmbeddedCaption())); - doc.Set(KeyStore.OverlayLayout, new TextField(FixedCaption())); - doc.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations, KeyStore.Caption])); - console.log("" + doc.GetNumber(KeyStore.Height, 311)); - return doc; - } - - let collectionProto: Document; - const collectionProtoId = "collectionProto"; - function GetCollectionPrototype(): Document { - if (!collectionProto) { - collectionProto = new Document(collectionProtoId); - collectionProto.Set(KeyStore.Scale, new NumberField(1)); - collectionProto.Set(KeyStore.PanX, new NumberField(0)); - collectionProto.Set(KeyStore.PanY, new NumberField(0)); - collectionProto.Set(KeyStore.Layout, new TextField(CollectionView.LayoutString("DataKey"))); - collectionProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); - } - return collectionProto; - } - - export function CollectionDocument(data: Array<Document> | string, viewType: CollectionViewType, options: DocumentOptions = {}, id?: string): Document { - let doc = GetCollectionPrototype().MakeDelegate(id); - setupOptions(doc, options); - if (typeof data === "string") { - doc.SetText(KeyStore.Data, data); - } else { - doc.SetData(KeyStore.Data, data, ListField); - } - doc.SetNumber(KeyStore.ViewType, viewType); - return doc; - } - - export function FreeformDocument(documents: Array<Document>, options: DocumentOptions, id?: string) { - return CollectionDocument(documents, CollectionViewType.Freeform, options, id) - } - - export function SchemaDocument(documents: Array<Document>, options: DocumentOptions, id?: string) { - return CollectionDocument(documents, CollectionViewType.Schema, options, id) - } - - export function DockDocument(config: string, options: DocumentOptions, id?: string) { - return CollectionDocument(config, CollectionViewType.Docking, options, id) - } }
\ No newline at end of file diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6b4b8ca57..60910a40b 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -133,7 +133,6 @@ export namespace DragManager { if (hideSource) { ele.hidden = true; } - const moveHandler = (e: PointerEvent) => { e.stopPropagation(); e.preventDefault(); @@ -158,14 +157,19 @@ export namespace DragManager { } const upHandler = (e: PointerEvent) => { abortDrag(); - FinishDrag(dragElement, e, dragData, options); + FinishDrag(ele, e, dragData, options); }; document.addEventListener("pointermove", moveHandler, true); document.addEventListener("pointerup", upHandler); } function FinishDrag(dragEle: HTMLElement, e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions) { + let parent = dragEle.parentElement; + if (parent) + parent.removeChild(dragEle); const target = document.elementFromPoint(e.x, e.y); + if (parent) + parent.appendChild(dragEle); if (!target) { return; } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 7ef4b6132..578aecd1e 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -84,6 +84,9 @@ Documents.initProtos(() => { let addImageNode = action(() => Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { width: 200, height: 200, title: "an image of a cat" })); + let addWebNode = action(() => Documents.WebDocument("https://cs.brown.edu/courses/cs166/", { + width: 200, height: 200, title: "a sample web page" + })); let addClick = (creator: any) => action(() => { var img = creator(); @@ -93,6 +96,7 @@ Documents.initProtos(() => { }); let imgRef = React.createRef<HTMLDivElement>(); + let webRef = React.createRef<HTMLDivElement>(); let textRef = React.createRef<HTMLDivElement>(); let schemaRef = React.createRef<HTMLDivElement>(); let colRef = React.createRef<HTMLDivElement>(); @@ -110,15 +114,17 @@ Documents.initProtos(() => { <ContextMenu /> <div style={{ position: 'absolute', bottom: '0px', left: '0px', width: '150px' }} ref={imgRef} > <button onPointerDown={setupDrag(imgRef, addImageNode)} onClick={addClick(addImageNode)}>Add Image</button></div> - <div style={{ position: 'absolute', bottom: '25px', left: '0px', width: '150px' }} ref={textRef}> + <div style={{ position: 'absolute', bottom: '25px', left: '0px', width: '150px' }} ref={webRef} > + <button onPointerDown={setupDrag(webRef, addWebNode)} onClick={addClick(addWebNode)}>Add Web</button></div> + <div style={{ position: 'absolute', bottom: '50px', left: '0px', width: '150px' }} ref={textRef}> <button onPointerDown={setupDrag(textRef, addTextNode)} onClick={addClick(addTextNode)}>Add Text</button></div> - <div style={{ position: 'absolute', bottom: '50px', left: '0px', width: '150px' }} ref={colRef}> + <div style={{ position: 'absolute', bottom: '75px', left: '0px', width: '150px' }} ref={colRef}> <button onPointerDown={setupDrag(colRef, addColNode)} onClick={addClick(addColNode)}>Add Collection</button></div> - <div style={{ position: 'absolute', bottom: '75px', left: '0px', width: '150px' }} ref={schemaRef}> + <div style={{ position: 'absolute', bottom: '100px', left: '0px', width: '150px' }} ref={schemaRef}> <button onPointerDown={setupDrag(schemaRef, addSchemaNode)} onClick={addClick(addSchemaNode)}>Add Schema</button></div> - <button style={{ position: 'absolute', bottom: '100px', left: '0px', width: '150px' }} onClick={clearDatabase}>Clear Database</button> - <button style={{ position: 'absolute', bottom: '25', right: '0px', width: '150px' }} onClick={() => UndoManager.Undo()}>Undo</button> - <button style={{ position: 'absolute', bottom: '0', right: '0px', width: '150px' }} onClick={() => UndoManager.Redo()}>Redo</button> + <button style={{ position: 'absolute', bottom: '125px', left: '0px', width: '150px' }} onClick={clearDatabase}>Clear Database</button> + <button style={{ position: 'absolute', bottom: '25px', right: '0px', width: '150px' }} onClick={() => UndoManager.Undo()}>Undo</button> + <button style={{ position: 'absolute', bottom: '0px', right: '0px', width: '150px' }} onClick={() => UndoManager.Redo()}>Redo</button> </div>), document.getElementById('root')); }) diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 12909c151..2edd5d953 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -10,13 +10,12 @@ import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; -import { CollectionTreeView } from "../collections/CollectionTreeView"; import { CollectionView } from "../collections/CollectionView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; -import { WebView } from "../nodes/WebView"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; +import { WebBox } from "../nodes/WebBox"; import "./CollectionFreeFormView.scss"; import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { CollectionViewBase } from "./CollectionViewBase"; @@ -200,7 +199,7 @@ export class CollectionFreeFormView extends CollectionViewBase { get backgroundView() { return !this.backgroundLayout ? (null) : (<JsxParser - components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebView }} + components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox }} bindings={this.props.bindings} jsx={this.backgroundLayout} showWarnings={true} @@ -211,7 +210,7 @@ export class CollectionFreeFormView extends CollectionViewBase { get overlayView() { return !this.overlayLayout ? (null) : (<JsxParser - components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView }} + components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox }} bindings={this.props.bindings} jsx={this.overlayLayout} showWarnings={true} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index feecde921..c929f9d54 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -12,10 +12,10 @@ import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; -import { WebView } from "./WebView"; import { ContextMenu } from "../ContextMenu"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; +import { WebBox } from "../nodes/WebBox"; import "./DocumentView.scss"; import React = require("react"); const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? @@ -119,6 +119,8 @@ export class DocumentView extends React.Component<DocumentViewProps> { return; } if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { + document.removeEventListener("pointermove", this.onPointerMove) + document.removeEventListener("pointerup", this.onPointerUp) this._contextMenuCanOpen = false; if (this._mainCont.current != null && !this.topMost) { this._contextMenuCanOpen = false; @@ -195,7 +197,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { @computed get mainContent() { var val = this.props.Document.Id; return <JsxParser - components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebView }} + components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox }} bindings={this._documentBindings} jsx={this.layout} showWarnings={true} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index b71309bf5..a883fa672 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -7,11 +7,12 @@ import { TextField } from "../../../fields/TextField"; import { NumberField } from "../../../fields/NumberField"; import { RichTextField } from "../../../fields/RichTextField"; import { ImageField } from "../../../fields/ImageField"; +import { WebField } from "../../../fields/WebField"; import { Key } from "../../../fields/Key"; import { FormattedTextBox } from "./FormattedTextBox"; import { ImageBox } from "./ImageBox"; +import { WebBox } from "./WebBox"; import { HtmlField } from "../../../fields/HtmlField"; -import { WebView } from "./WebView"; // // these properties get assigned through the render() method of the DocumentView when it creates this node. @@ -50,12 +51,16 @@ export class FieldView extends React.Component<FieldViewProps> { else if (field instanceof ImageField) { return <ImageBox {...this.props} /> } + else if (field instanceof WebField) { + return <WebBox {...this.props} /> + } + // bcz: this belongs here, but it doesn't render well so taking it out for now + // else if (field instanceof HtmlField) { + // return <WebBox {...this.props} /> + // } else if (field instanceof NumberField) { return <p>{field.Data}</p> } - else if (field instanceof HtmlField) { - return <WebView {...this.props} /> - } else if (field != FieldWaiting) { return <p>{JSON.stringify(field.GetValue())}</p> } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 4fe73fb8d..e206bf8d5 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -9,7 +9,6 @@ import { FieldWaiting } from '../../../fields/Field'; import { observer } from "mobx-react" import { observable, action } from 'mobx'; import { KeyStore } from '../../../fields/KeyStore'; -import { element } from 'prop-types'; @observer export class ImageBox extends React.Component<FieldViewProps> { diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss new file mode 100644 index 000000000..e72b3c4da --- /dev/null +++ b/src/client/views/nodes/WebBox.scss @@ -0,0 +1,14 @@ + +.webBox-cont { + padding: 0vw; + position: absolute; + width: 100%; + height: 100%; +} + +.webBox-button { + padding : 0vw; + border: none; + width : 100%; + height: 100%; +}
\ No newline at end of file diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx new file mode 100644 index 000000000..2ca8d49ce --- /dev/null +++ b/src/client/views/nodes/WebBox.tsx @@ -0,0 +1,38 @@ +import "./WebBox.scss"; +import React = require("react") +import { WebField } from '../../../fields/WebField'; +import { FieldViewProps, FieldView } from './FieldView'; +import { FieldWaiting } from '../../../fields/Field'; +import { observer } from "mobx-react" +import { computed } from 'mobx'; +import { KeyStore } from '../../../fields/KeyStore'; + +@observer +export class WebBox extends React.Component<FieldViewProps> { + + public static LayoutString() { return FieldView.LayoutString(WebBox); } + + constructor(props: FieldViewProps) { + super(props); + } + + @computed get html(): string { return this.props.doc.GetHtml(KeyStore.Data, ""); } + + render() { + let field = this.props.doc.Get(this.props.fieldKey); + let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : + field instanceof WebField ? field.Data.href : "https://crossorigin.me/" + "https://cs.brown.edu"; + + let content = this.html ? + <span dangerouslySetInnerHTML={{ __html: this.html }}></span> : + <div style={{ width: "100%", height: "100%", position: "absolute" }}> + <iframe src={path} style={{ position: "absolute", width: "100%", height: "100%" }}></iframe> + {this.props.isSelected() ? (null) : <div style={{ width: "100%", height: "100%", position: "absolute" }} />} + </div>; + + return ( + <div className="webBox-cont" > + {content} + </div>) + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/WebView.tsx b/src/client/views/nodes/WebView.tsx deleted file mode 100644 index 717aa8bf5..000000000 --- a/src/client/views/nodes/WebView.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { FieldViewProps, FieldView } from "./FieldView"; -import { computed } from "mobx"; -import { observer } from "mobx-react"; -import { KeyStore } from "../../../fields/KeyStore"; -import React = require('react') -import { TextField } from "../../../fields/TextField"; -import { HtmlField } from "../../../fields/HtmlField"; -import { RichTextField } from "../../../fields/RichTextField"; - -@observer -export class WebView extends React.Component<FieldViewProps> { - public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(WebView, fieldStr) } - - @computed - get html(): string { - return this.props.doc.GetData(KeyStore.Data, HtmlField, "" as string); - } - - render() { - return <span dangerouslySetInnerHTML={{ __html: this.html }}></span> - } -}
\ No newline at end of file diff --git a/src/fields/Document.ts b/src/fields/Document.ts index 6193ea56c..5b91de6ed 100644 --- a/src/fields/Document.ts +++ b/src/fields/Document.ts @@ -8,6 +8,7 @@ import { ListField } from "./ListField"; import { Server } from "../client/Server"; import { Types } from "../server/Message"; import { UndoManager } from "../client/util/UndoManager"; +import { HtmlField } from "./HtmlField"; export class Document extends Field { public fields: ObservableMap<string, { key: Key, field: Field }> = new ObservableMap(); @@ -125,6 +126,10 @@ export class Document extends Field { return vval; } + GetHtml(key: Key, defaultVal: string): string { + return this.GetData(key, HtmlField, defaultVal); + } + GetNumber(key: Key, defaultVal: number): number { return this.GetData(key, NumberField, defaultVal); } diff --git a/src/fields/WebField.ts b/src/fields/WebField.ts new file mode 100644 index 000000000..8f945d686 --- /dev/null +++ b/src/fields/WebField.ts @@ -0,0 +1,30 @@ +import { BasicField } from "./BasicField"; +import { Field, FieldId } from "./Field"; +import { Types } from "../server/Message"; + +export class WebField extends BasicField<URL> { + constructor(data: URL | undefined = undefined, id?: FieldId, save: boolean = true) { + super(data == undefined ? new URL("https://crossorigin.me/" + "https://cs.brown.edu/") : data, save, id); + } + + toString(): string { + return this.Data.href; + } + + ToScriptString(): string { + return `new WebField("${this.Data}")`; + } + + Copy(): Field { + return new WebField(this.Data); + } + + ToJson(): { type: Types, data: URL, _id: string } { + return { + type: Types.Web, + data: this.Data, + _id: this.Id + } + } + +}
\ No newline at end of file diff --git a/src/server/Message.ts b/src/server/Message.ts index 80fc9a80d..148e6e723 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -45,7 +45,7 @@ export class GetFieldArgs { } export enum Types { - Number, List, Key, Image, Document, Text, RichText, DocumentReference, Html + Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html } export class DocumentTransfer implements Transferable { diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index 08e72fdae..a53fb5d2b 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -10,6 +10,7 @@ import { Server } from './../client/Server'; import { Types } from './Message'; import { Utils } from '../Utils'; import { HtmlField } from '../fields/HtmlField'; +import { WebField } from '../fields/WebField'; export class ServerUtils { public static FromJson(json: any): Field { @@ -30,6 +31,8 @@ export class ServerUtils { return new TextField(data, id, false) case Types.Html: return new HtmlField(data, id, false) + case Types.Web: + return new WebField(new URL(data), id, false) case Types.RichText: return new RichTextField(data, id, false) case Types.Key: |