solid-ui 2.6.1 → 3.0.0-63a1640
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +3 -1
- package/README.md +236 -30
- package/dist/acl/access-controller.js +238 -0
- package/dist/acl/access-controller.js.map +1 -0
- package/{lib → dist}/acl/access-groups.d.ts +2 -2
- package/{lib → dist}/acl/access-groups.d.ts.map +1 -1
- package/dist/acl/access-groups.js +323 -0
- package/dist/acl/access-groups.js.map +1 -0
- package/dist/acl/acl-control.js +173 -0
- package/dist/acl/acl-control.js.map +1 -0
- package/dist/acl/acl.js +495 -0
- package/dist/acl/acl.js.map +1 -0
- package/dist/acl/add-agent-buttons.js +217 -0
- package/dist/acl/add-agent-buttons.js.map +1 -0
- package/dist/acl/index.js +32 -0
- package/dist/acl/index.js.map +1 -0
- package/dist/acl/types.js +6 -0
- package/dist/acl/types.js.map +1 -0
- package/dist/chat/keys.js +106 -0
- package/dist/chat/keys.js.map +1 -0
- package/dist/chat/signature.js +63 -0
- package/dist/chat/signature.js.map +1 -0
- package/dist/create/create.js +249 -0
- package/dist/create/create.js.map +1 -0
- package/dist/create/index.js +5 -0
- package/dist/create/index.js.map +1 -0
- package/dist/create/types.js +2 -0
- package/dist/create/types.js.map +1 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +13 -0
- package/dist/debug.js.map +1 -0
- package/dist/footer/index.js +67 -0
- package/dist/footer/index.js.map +1 -0
- package/dist/header/empty-profile.js +11 -0
- package/dist/header/empty-profile.js.map +1 -0
- package/dist/header/index.js +260 -0
- package/dist/header/index.js.map +1 -0
- package/dist/iconBase.js +37 -0
- package/dist/iconBase.js.map +1 -0
- package/dist/icons/solid_logo.js.map +1 -0
- package/{lib → dist}/index.d.ts +7 -9
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/{lib → dist}/log.d.ts.map +1 -1
- package/dist/log.js +182 -0
- package/dist/log.js.map +1 -0
- package/dist/login/login.js +858 -0
- package/dist/login/login.js.map +1 -0
- package/dist/matrix/index.js +5 -0
- package/dist/matrix/index.js.map +1 -0
- package/dist/matrix/matrix.js +217 -0
- package/dist/matrix/matrix.js.map +1 -0
- package/dist/matrix/types.js +2 -0
- package/dist/matrix/types.js.map +1 -0
- package/dist/media/index.js +6 -0
- package/dist/media/index.js.map +1 -0
- package/dist/media/media-capture.js +161 -0
- package/dist/media/media-capture.js.map +1 -0
- package/dist/pad.js +775 -0
- package/dist/pad.js.map +1 -0
- package/{lib → dist}/participation.d.ts.map +1 -1
- package/dist/participation.js +184 -0
- package/dist/participation.js.map +1 -0
- package/dist/solid-ui.esm.js +25531 -0
- package/dist/solid-ui.esm.js.map +1 -0
- package/dist/solid-ui.esm.min.js +43 -0
- package/dist/solid-ui.esm.min.js.map +1 -0
- package/dist/solid-ui.js +23479 -68931
- package/dist/solid-ui.js.map +1 -1
- package/dist/solid-ui.min.js +40 -2
- package/dist/solid-ui.min.js.map +1 -1
- package/dist/tabs.js +388 -0
- package/dist/tabs.js.map +1 -0
- package/{lib → dist}/utils/headerFooterHelpers.d.ts.map +1 -1
- package/dist/utils/headerFooterHelpers.js +114 -0
- package/dist/utils/headerFooterHelpers.js.map +1 -0
- package/dist/utils/keyHelpers/accessData.js +64 -0
- package/dist/utils/keyHelpers/accessData.js.map +1 -0
- package/dist/utils/keyHelpers/acl.js +74 -0
- package/dist/utils/keyHelpers/acl.js.map +1 -0
- package/dist/utils/keyHelpers/otherHelpers.js +13 -0
- package/dist/utils/keyHelpers/otherHelpers.js.map +1 -0
- package/dist/utils/label.js +111 -0
- package/dist/utils/label.js.map +1 -0
- package/dist/versionInfo.js +30 -0
- package/dist/versionInfo.js.map +1 -0
- package/dist/widgets/buttons/iconLinks.js +44 -0
- package/dist/widgets/buttons/iconLinks.js.map +1 -0
- package/dist/widgets/buttons.js +1280 -0
- package/dist/widgets/buttons.js.map +1 -0
- package/dist/widgets/error.d.ts +14 -0
- package/dist/widgets/error.d.ts.map +1 -0
- package/dist/widgets/error.js +35 -0
- package/dist/widgets/error.js.map +1 -0
- package/dist/widgets/forms/autocomplete/autocompleteBar.js +123 -0
- package/dist/widgets/forms/autocomplete/autocompleteBar.js.map +1 -0
- package/dist/widgets/forms/autocomplete/autocompleteField.js +199 -0
- package/dist/widgets/forms/autocomplete/autocompleteField.js.map +1 -0
- package/dist/widgets/forms/autocomplete/autocompletePicker.js +256 -0
- package/dist/widgets/forms/autocomplete/autocompletePicker.js.map +1 -0
- package/dist/widgets/forms/autocomplete/language.js +104 -0
- package/dist/widgets/forms/autocomplete/language.js.map +1 -0
- package/dist/widgets/forms/autocomplete/publicData.js +460 -0
- package/dist/widgets/forms/autocomplete/publicData.js.map +1 -0
- package/dist/widgets/forms/basic.js +241 -0
- package/dist/widgets/forms/basic.js.map +1 -0
- package/dist/widgets/forms/comment.js +46 -0
- package/dist/widgets/forms/comment.js.map +1 -0
- package/dist/widgets/forms/fieldFunction.js +44 -0
- package/dist/widgets/forms/fieldFunction.js.map +1 -0
- package/dist/widgets/forms/fieldParams.js +89 -0
- package/dist/widgets/forms/fieldParams.js.map +1 -0
- package/{lib → dist}/widgets/forms/formStyle.d.ts.map +1 -1
- package/dist/widgets/forms/formStyle.js +36 -0
- package/dist/widgets/forms/formStyle.js.map +1 -0
- package/{lib → dist}/widgets/widgetHelpers.d.ts.map +1 -1
- package/{lib → dist}/widgets/widgetHelpers.js +14 -25
- package/dist/widgets/widgetHelpers.js.map +1 -0
- package/package.json +48 -52
- package/dist/789.solid-ui.min.js +0 -1
- package/dist/841.solid-ui.min.js +0 -3
- package/dist/841.solid-ui.min.js.LICENSE.txt +0 -58
- package/dist/841.solid-ui.min.js.map +0 -1
- package/dist/_2b19.solid-ui.js +0 -14
- package/dist/_2b19.solid-ui.js.map +0 -1
- package/dist/index.html +0 -1
- package/dist/solid-ui.min.js.LICENSE.txt +0 -57
- package/dist/vendors-node_modules_jsonld_lib_jsonld_js.solid-ui.js +0 -12247
- package/dist/vendors-node_modules_jsonld_lib_jsonld_js.solid-ui.js.map +0 -1
- package/lib/acl/access-controller.js +0 -391
- package/lib/acl/access-controller.js.map +0 -1
- package/lib/acl/access-groups.js +0 -507
- package/lib/acl/access-groups.js.map +0 -1
- package/lib/acl/acl-control.js +0 -237
- package/lib/acl/acl-control.js.map +0 -1
- package/lib/acl/acl.js +0 -517
- package/lib/acl/acl.js.map +0 -1
- package/lib/acl/add-agent-buttons.js +0 -434
- package/lib/acl/add-agent-buttons.js.map +0 -1
- package/lib/acl/index.js +0 -39
- package/lib/acl/index.js.map +0 -1
- package/lib/acl/types.js +0 -6
- package/lib/acl/types.js.map +0 -1
- package/lib/chat/bookmarks.js +0 -303
- package/lib/chat/bookmarks.js.map +0 -1
- package/lib/chat/chatLogic.js +0 -420
- package/lib/chat/chatLogic.js.map +0 -1
- package/lib/chat/dateFolder.js +0 -328
- package/lib/chat/dateFolder.js.map +0 -1
- package/lib/chat/infinite.js +0 -994
- package/lib/chat/infinite.js.map +0 -1
- package/lib/chat/keys.js +0 -232
- package/lib/chat/keys.js.map +0 -1
- package/lib/chat/message.js +0 -715
- package/lib/chat/message.js.map +0 -1
- package/lib/chat/messageTools.js +0 -538
- package/lib/chat/messageTools.js.map +0 -1
- package/lib/chat/signature.js +0 -109
- package/lib/chat/signature.js.map +0 -1
- package/lib/chat/thread.js +0 -535
- package/lib/chat/thread.js.map +0 -1
- package/lib/create/create.js +0 -242
- package/lib/create/create.js.map +0 -1
- package/lib/create/index.js +0 -11
- package/lib/create/index.js.map +0 -1
- package/lib/create/types.js +0 -6
- package/lib/create/types.js.map +0 -1
- package/lib/debug.d.ts.map +0 -1
- package/lib/debug.js +0 -30
- package/lib/debug.js.map +0 -1
- package/lib/folders.js +0 -132
- package/lib/folders.js.map +0 -1
- package/lib/footer/index.js +0 -123
- package/lib/footer/index.js.map +0 -1
- package/lib/header/empty-profile.js +0 -8
- package/lib/header/empty-profile.js.map +0 -1
- package/lib/header/index.js +0 -375
- package/lib/header/index.js.map +0 -1
- package/lib/iconBase.js +0 -44
- package/lib/iconBase.js.map +0 -1
- package/lib/icons/solid_logo.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -223
- package/lib/index.js.map +0 -1
- package/lib/log.js +0 -213
- package/lib/log.js.map +0 -1
- package/lib/login/login.js +0 -1241
- package/lib/login/login.js.map +0 -1
- package/lib/matrix/index.js +0 -11
- package/lib/matrix/index.js.map +0 -1
- package/lib/matrix/matrix.js +0 -216
- package/lib/matrix/matrix.js.map +0 -1
- package/lib/matrix/types.js +0 -6
- package/lib/matrix/types.js.map +0 -1
- package/lib/media/index.js +0 -12
- package/lib/media/index.js.map +0 -1
- package/lib/media/media-capture.js +0 -194
- package/lib/media/media-capture.js.map +0 -1
- package/lib/messageArea.js +0 -319
- package/lib/messageArea.js.map +0 -1
- package/lib/noun_Camera_1618446_000000.js +0 -8
- package/lib/noun_Camera_1618446_000000.js.map +0 -1
- package/lib/ns.js +0 -17
- package/lib/ns.js.map +0 -1
- package/lib/pad.js +0 -805
- package/lib/pad.js.map +0 -1
- package/lib/participation.js +0 -219
- package/lib/participation.js.map +0 -1
- package/lib/preferences.js +0 -215
- package/lib/preferences.js.map +0 -1
- package/lib/signup/config-default.js +0 -43
- package/lib/signup/config-default.js.map +0 -1
- package/lib/signup/signup.js +0 -74
- package/lib/signup/signup.js.map +0 -1
- package/lib/stories/decorators.js +0 -10
- package/lib/stories/decorators.js.map +0 -1
- package/lib/style.js +0 -158
- package/lib/style.js.map +0 -1
- package/lib/styleConstants.js +0 -35
- package/lib/styleConstants.js.map +0 -1
- package/lib/style_multiSelect.js +0 -62
- package/lib/style_multiSelect.js.map +0 -1
- package/lib/table.js +0 -1573
- package/lib/table.js.map +0 -1
- package/lib/tabs.js +0 -448
- package/lib/tabs.js.map +0 -1
- package/lib/typings.d.js +0 -2
- package/lib/typings.d.js.map +0 -1
- package/lib/utils/headerFooterHelpers.js +0 -165
- package/lib/utils/headerFooterHelpers.js.map +0 -1
- package/lib/utils/index.js +0 -527
- package/lib/utils/index.js.map +0 -1
- package/lib/utils/keyHelpers/accessData.js +0 -131
- package/lib/utils/keyHelpers/accessData.js.map +0 -1
- package/lib/utils/keyHelpers/acl.js +0 -90
- package/lib/utils/keyHelpers/acl.js.map +0 -1
- package/lib/utils/keyHelpers/otherHelpers.js +0 -21
- package/lib/utils/keyHelpers/otherHelpers.js.map +0 -1
- package/lib/utils/label.js +0 -103
- package/lib/utils/label.js.map +0 -1
- package/lib/versionInfo.d.ts +0 -32
- package/lib/versionInfo.d.ts.map +0 -1
- package/lib/versionInfo.js +0 -37
- package/lib/versionInfo.js.map +0 -1
- package/lib/widgets/buttons/iconLinks.js +0 -53
- package/lib/widgets/buttons/iconLinks.js.map +0 -1
- package/lib/widgets/buttons.js +0 -1306
- package/lib/widgets/buttons.js.map +0 -1
- package/lib/widgets/dragAndDrop.js +0 -194
- package/lib/widgets/dragAndDrop.js.map +0 -1
- package/lib/widgets/error.d.ts +0 -2
- package/lib/widgets/error.d.ts.map +0 -1
- package/lib/widgets/error.js +0 -46
- package/lib/widgets/error.js.map +0 -1
- package/lib/widgets/forms/autocomplete/autocompleteBar.js +0 -271
- package/lib/widgets/forms/autocomplete/autocompleteBar.js.map +0 -1
- package/lib/widgets/forms/autocomplete/autocompleteField.js +0 -258
- package/lib/widgets/forms/autocomplete/autocompleteField.js.map +0 -1
- package/lib/widgets/forms/autocomplete/autocompletePicker.js +0 -436
- package/lib/widgets/forms/autocomplete/autocompletePicker.js.map +0 -1
- package/lib/widgets/forms/autocomplete/language.js +0 -189
- package/lib/widgets/forms/autocomplete/language.js.map +0 -1
- package/lib/widgets/forms/autocomplete/publicData.js +0 -636
- package/lib/widgets/forms/autocomplete/publicData.js.map +0 -1
- package/lib/widgets/forms/basic.js +0 -254
- package/lib/widgets/forms/basic.js.map +0 -1
- package/lib/widgets/forms/comment.js +0 -54
- package/lib/widgets/forms/comment.js.map +0 -1
- package/lib/widgets/forms/fieldFunction.js +0 -52
- package/lib/widgets/forms/fieldFunction.js.map +0 -1
- package/lib/widgets/forms/fieldParams.js +0 -77
- package/lib/widgets/forms/fieldParams.js.map +0 -1
- package/lib/widgets/forms/formStyle.js +0 -44
- package/lib/widgets/forms/formStyle.js.map +0 -1
- package/lib/widgets/forms.js +0 -2045
- package/lib/widgets/forms.js.map +0 -1
- package/lib/widgets/index.js +0 -110
- package/lib/widgets/index.js.map +0 -1
- package/lib/widgets/multiSelect.js +0 -658
- package/lib/widgets/multiSelect.js.map +0 -1
- package/lib/widgets/peoplePicker.js +0 -467
- package/lib/widgets/peoplePicker.js.map +0 -1
- package/lib/widgets/widgetHelpers.js.map +0 -1
- /package/{lib → dist}/acl/access-controller.d.ts +0 -0
- /package/{lib → dist}/acl/access-controller.d.ts.map +0 -0
- /package/{lib → dist}/acl/acl-control.d.ts +0 -0
- /package/{lib → dist}/acl/acl-control.d.ts.map +0 -0
- /package/{lib → dist}/acl/acl.d.ts +0 -0
- /package/{lib → dist}/acl/acl.d.ts.map +0 -0
- /package/{lib → dist}/acl/add-agent-buttons.d.ts +0 -0
- /package/{lib → dist}/acl/add-agent-buttons.d.ts.map +0 -0
- /package/{lib → dist}/acl/index.d.ts +0 -0
- /package/{lib → dist}/acl/index.d.ts.map +0 -0
- /package/{lib → dist}/acl/types.d.ts +0 -0
- /package/{lib → dist}/acl/types.d.ts.map +0 -0
- /package/{lib → dist}/chat/keys.d.ts +0 -0
- /package/{lib → dist}/chat/keys.d.ts.map +0 -0
- /package/{lib → dist}/chat/signature.d.ts +0 -0
- /package/{lib → dist}/chat/signature.d.ts.map +0 -0
- /package/{lib → dist}/create/create.d.ts +0 -0
- /package/{lib → dist}/create/create.d.ts.map +0 -0
- /package/{lib → dist}/create/index.d.ts +0 -0
- /package/{lib → dist}/create/index.d.ts.map +0 -0
- /package/{lib → dist}/create/types.d.ts +0 -0
- /package/{lib → dist}/create/types.d.ts.map +0 -0
- /package/{lib → dist}/debug.d.ts +0 -0
- /package/{lib → dist}/footer/index.d.ts +0 -0
- /package/{lib → dist}/footer/index.d.ts.map +0 -0
- /package/{lib → dist}/header/empty-profile.d.ts +0 -0
- /package/{lib → dist}/header/empty-profile.d.ts.map +0 -0
- /package/{lib → dist}/header/index.d.ts +0 -0
- /package/{lib → dist}/header/index.d.ts.map +0 -0
- /package/{lib → dist}/iconBase.d.ts +0 -0
- /package/{lib → dist}/iconBase.d.ts.map +0 -0
- /package/{lib → dist}/icons/solid_logo.d.ts +0 -0
- /package/{lib → dist}/icons/solid_logo.d.ts.map +0 -0
- /package/{lib → dist}/icons/solid_logo.js +0 -0
- /package/{lib → dist}/log.d.ts +0 -0
- /package/{lib → dist}/login/login.d.ts +0 -0
- /package/{lib → dist}/login/login.d.ts.map +0 -0
- /package/{lib → dist}/matrix/index.d.ts +0 -0
- /package/{lib → dist}/matrix/index.d.ts.map +0 -0
- /package/{lib → dist}/matrix/matrix.d.ts +0 -0
- /package/{lib → dist}/matrix/matrix.d.ts.map +0 -0
- /package/{lib → dist}/matrix/types.d.ts +0 -0
- /package/{lib → dist}/matrix/types.d.ts.map +0 -0
- /package/{lib → dist}/media/index.d.ts +0 -0
- /package/{lib → dist}/media/index.d.ts.map +0 -0
- /package/{lib → dist}/media/media-capture.d.ts +0 -0
- /package/{lib → dist}/media/media-capture.d.ts.map +0 -0
- /package/{lib → dist}/pad.d.ts +0 -0
- /package/{lib → dist}/pad.d.ts.map +0 -0
- /package/{lib → dist}/participation.d.ts +0 -0
- /package/{lib → dist}/tabs.d.ts +0 -0
- /package/{lib → dist}/tabs.d.ts.map +0 -0
- /package/{lib → dist}/utils/headerFooterHelpers.d.ts +0 -0
- /package/{lib → dist}/utils/keyHelpers/accessData.d.ts +0 -0
- /package/{lib → dist}/utils/keyHelpers/accessData.d.ts.map +0 -0
- /package/{lib → dist}/utils/keyHelpers/acl.d.ts +0 -0
- /package/{lib → dist}/utils/keyHelpers/acl.d.ts.map +0 -0
- /package/{lib → dist}/utils/keyHelpers/otherHelpers.d.ts +0 -0
- /package/{lib → dist}/utils/keyHelpers/otherHelpers.d.ts.map +0 -0
- /package/{lib → dist}/utils/label.d.ts +0 -0
- /package/{lib → dist}/utils/label.d.ts.map +0 -0
- /package/{lib → dist}/widgets/buttons/iconLinks.d.ts +0 -0
- /package/{lib → dist}/widgets/buttons/iconLinks.d.ts.map +0 -0
- /package/{lib → dist}/widgets/buttons.d.ts +0 -0
- /package/{lib → dist}/widgets/buttons.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/autocompleteBar.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/autocompleteBar.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/autocompleteField.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/autocompleteField.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/autocompletePicker.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/autocompletePicker.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/language.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/language.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/publicData.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/autocomplete/publicData.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/basic.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/basic.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/comment.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/comment.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/fieldFunction.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/fieldFunction.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/fieldParams.d.ts +0 -0
- /package/{lib → dist}/widgets/forms/fieldParams.d.ts.map +0 -0
- /package/{lib → dist}/widgets/forms/formStyle.d.ts +0 -0
- /package/{lib → dist}/widgets/widgetHelpers.d.ts +0 -0
package/lib/table.js
DELETED
|
@@ -1,1573 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.renderTableViewPane = renderTableViewPane;
|
|
8
|
-
var debug = _interopRequireWildcard(require("./debug"));
|
|
9
|
-
var _iconBase = require("./iconBase");
|
|
10
|
-
var _solidLogic = require("solid-logic");
|
|
11
|
-
var log = _interopRequireWildcard(require("./log"));
|
|
12
|
-
var ns = _interopRequireWildcard(require("./ns"));
|
|
13
|
-
var rdf = _interopRequireWildcard(require("rdflib"));
|
|
14
|
-
var utils = _interopRequireWildcard(require("./utils"));
|
|
15
|
-
var widgets = _interopRequireWildcard(require("./widgets"));
|
|
16
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
17
|
-
// Table Widget: Format an array of RDF statements as an HTML table.
|
|
18
|
-
//
|
|
19
|
-
// This can operate in one of three modes: when the class of object is given
|
|
20
|
-
// or when the source document from whuch data is taken is given,
|
|
21
|
-
// or if a prepared query object is given.
|
|
22
|
-
// (In principle it could operate with neither class nor document
|
|
23
|
-
// given but typically
|
|
24
|
-
// there would be too much data.)
|
|
25
|
-
// When the tableClass is not given, it looks for common classes in the data,
|
|
26
|
-
// and gives the user the option.
|
|
27
|
-
//
|
|
28
|
-
// 2008 Written, Ilaria Liccardi as the tableViewPane.js
|
|
29
|
-
// 2014 Core table widget moved into common/table.js - timbl
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
// pull in first avoid cross-refs
|
|
33
|
-
|
|
34
|
-
var UI = {
|
|
35
|
-
icons: _iconBase.icons,
|
|
36
|
-
log: log,
|
|
37
|
-
ns: ns,
|
|
38
|
-
utils: utils,
|
|
39
|
-
widgets: widgets
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// UI.widgets.renderTableViewPane
|
|
43
|
-
function renderTableViewPane(doc, options) {
|
|
44
|
-
var sourceDocument = options.sourceDocument;
|
|
45
|
-
var tableClass = options.tableClass;
|
|
46
|
-
var givenQuery = options.query;
|
|
47
|
-
var RDFS_LITERAL = 'http://www.w3.org/2000/01/rdf-schema#Literal';
|
|
48
|
-
var ns = UI.ns;
|
|
49
|
-
var kb = _solidLogic.store;
|
|
50
|
-
var rowsLookup = {}; // Persistent mapping of subject URI to dom TR
|
|
51
|
-
|
|
52
|
-
// Predicates that are never made into columns:
|
|
53
|
-
|
|
54
|
-
var FORBIDDEN_COLUMNS = {
|
|
55
|
-
'http://www.w3.org/2002/07/owl#sameAs': true,
|
|
56
|
-
'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': true
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Number types defined in the XML schema:
|
|
60
|
-
|
|
61
|
-
var XSD_NUMBER_TYPES = {
|
|
62
|
-
'http://www.w3.org/2001/XMLSchema#decimal': true,
|
|
63
|
-
'http://www.w3.org/2001/XMLSchema#float': true,
|
|
64
|
-
'http://www.w3.org/2001/XMLSchema#double': true,
|
|
65
|
-
'http://www.w3.org/2001/XMLSchema#integer': true,
|
|
66
|
-
'http://www.w3.org/2001/XMLSchema#nonNegativeInteger': true,
|
|
67
|
-
'http://www.w3.org/2001/XMLSchema#positiveInteger': true,
|
|
68
|
-
'http://www.w3.org/2001/XMLSchema#nonPositiveInteger': true,
|
|
69
|
-
'http://www.w3.org/2001/XMLSchema#negativeInteger': true,
|
|
70
|
-
'http://www.w3.org/2001/XMLSchema#long': true,
|
|
71
|
-
'http://www.w3.org/2001/XMLSchema#int': true,
|
|
72
|
-
'http://www.w3.org/2001/XMLSchema#short': true,
|
|
73
|
-
'http://www.w3.org/2001/XMLSchema#byte': true,
|
|
74
|
-
'http://www.w3.org/2001/XMLSchema#unsignedLong': true,
|
|
75
|
-
'http://www.w3.org/2001/XMLSchema#unsignedInt': true,
|
|
76
|
-
'http://www.w3.org/2001/XMLSchema#unsignedShort': true,
|
|
77
|
-
'http://www.w3.org/2001/XMLSchema#unsignedByte': true
|
|
78
|
-
};
|
|
79
|
-
var XSD_DATE_TYPES = {
|
|
80
|
-
'http://www.w3.org/2001/XMLSchema#dateTime': true,
|
|
81
|
-
'http://www.w3.org/2001/XMLSchema#date': true
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Classes that indicate an image:
|
|
85
|
-
|
|
86
|
-
var IMAGE_TYPES = {
|
|
87
|
-
'http://xmlns.com/foaf/0.1/Image': true,
|
|
88
|
-
'http://purl.org/dc/terms/Image': true
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// Name of the column used as a "key" value to look up the row.
|
|
92
|
-
// This is necessary because in the normal view, the columns are
|
|
93
|
-
// all "optional" values, meaning that we will get a result set
|
|
94
|
-
// for every individual value that is found. The row key acts
|
|
95
|
-
// as an anchor that can be used to combine this information
|
|
96
|
-
// back into the same row.
|
|
97
|
-
|
|
98
|
-
var keyVariable = options.keyVariable || '?_row';
|
|
99
|
-
var subjectIdCounter = 0;
|
|
100
|
-
var allType, types;
|
|
101
|
-
var typeSelectorDiv, addColumnDiv;
|
|
102
|
-
|
|
103
|
-
// The last SPARQL query used:
|
|
104
|
-
var lastQuery = null;
|
|
105
|
-
var mostCommonType = null;
|
|
106
|
-
var resultDiv = doc.createElement('div');
|
|
107
|
-
resultDiv.className = 'tableViewPane';
|
|
108
|
-
resultDiv.appendChild(generateControlBar()); // sets typeSelectorDiv
|
|
109
|
-
|
|
110
|
-
var tableDiv = doc.createElement('div');
|
|
111
|
-
resultDiv.appendChild(tableDiv);
|
|
112
|
-
|
|
113
|
-
// Save a refresh function for use by caller
|
|
114
|
-
resultDiv.refresh = function () {
|
|
115
|
-
runQuery(table.query, table.logicalRows, table.columns, table);
|
|
116
|
-
// updateTable(givenQuery, mostCommonType) // This could be a lot more incremental and efficient
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// A specifically asked-for query
|
|
120
|
-
var table;
|
|
121
|
-
if (givenQuery) {
|
|
122
|
-
table = renderTableForQuery(givenQuery);
|
|
123
|
-
// lastQuery = givenQuery
|
|
124
|
-
tableDiv.appendChild(table);
|
|
125
|
-
} else {
|
|
126
|
-
// Find the most common type and select it by default
|
|
127
|
-
|
|
128
|
-
var s = calculateTable();
|
|
129
|
-
allType = s[0];
|
|
130
|
-
types = s[1];
|
|
131
|
-
if (!tableClass) {
|
|
132
|
-
typeSelectorDiv.appendChild(generateTypeSelector(allType, types));
|
|
133
|
-
}
|
|
134
|
-
mostCommonType = getMostCommonType(types);
|
|
135
|
-
if (mostCommonType) {
|
|
136
|
-
buildFilteredTable(mostCommonType);
|
|
137
|
-
} else {
|
|
138
|
-
buildFilteredTable(allType);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return resultDiv;
|
|
142
|
-
|
|
143
|
-
// /////////////////////////////////////////////////////////////////
|
|
144
|
-
/*
|
|
145
|
-
function closeDialog (dialog) {
|
|
146
|
-
dialog.parentNode.removeChild(dialog)
|
|
147
|
-
}
|
|
148
|
-
function createActionButton (label, callback) {
|
|
149
|
-
var button = doc.createElement('input')
|
|
150
|
-
button.setAttribute('type', 'submit')
|
|
151
|
-
button.setAttribute('value', label)
|
|
152
|
-
button.addEventListener('click', callback, false)
|
|
153
|
-
return button
|
|
154
|
-
}
|
|
155
|
-
// @@ Tdo: put these buttonsback in,
|
|
156
|
-
// to allow user to see and edit and save the sparql query for the table they are looking at
|
|
157
|
-
//
|
|
158
|
-
function createSparqlWindow () {
|
|
159
|
-
var dialog = doc.createElement('div')
|
|
160
|
-
dialog.setAttribute('class', 'sparqlDialog')
|
|
161
|
-
var title = doc.createElement('h3')
|
|
162
|
-
title.appendChild(doc.createTextNode('Edit SPARQL query'))
|
|
163
|
-
var inputbox = doc.createElement('textarea')
|
|
164
|
-
inputbox.value = rdf.queryToSPARQL(lastQuery)
|
|
165
|
-
dialog.appendChild(title)
|
|
166
|
-
dialog.appendChild(inputbox)
|
|
167
|
-
dialog.appendChild(createActionButton('Query', function () {
|
|
168
|
-
var query = rdf.SPARQLToQuery(inputbox.value)
|
|
169
|
-
updateTable(query)
|
|
170
|
-
closeDialog(dialog)
|
|
171
|
-
}))
|
|
172
|
-
dialog.appendChild(createActionButton('Close', function () {
|
|
173
|
-
closeDialog(dialog)
|
|
174
|
-
}))
|
|
175
|
-
return dialog
|
|
176
|
-
}
|
|
177
|
-
function sparqlButtonPressed () {
|
|
178
|
-
var dialog = createSparqlWindow()
|
|
179
|
-
resultDiv.appendChild(dialog)
|
|
180
|
-
}
|
|
181
|
-
function generateSparqlButton () {
|
|
182
|
-
var image = doc.createElement('img')
|
|
183
|
-
image.setAttribute('class', 'sparqlButton')
|
|
184
|
-
image.setAttribute('src', UI.iconBase + 'icons/1pt5a.gif')
|
|
185
|
-
image.setAttribute('alt', 'Edit SPARQL query')
|
|
186
|
-
image.addEventListener('click', sparqlButtonPressed, false)
|
|
187
|
-
return image
|
|
188
|
-
}
|
|
189
|
-
*/
|
|
190
|
-
// Generate the control bar displayed at the top of the screen.
|
|
191
|
-
|
|
192
|
-
function generateControlBar() {
|
|
193
|
-
var result = doc.createElement('table');
|
|
194
|
-
result.setAttribute('class', 'toolbar');
|
|
195
|
-
var tr = doc.createElement('tr');
|
|
196
|
-
|
|
197
|
-
/* @@ Add in later -- not debugged yet
|
|
198
|
-
var sparqlButtonDiv = doc.createElement("td")
|
|
199
|
-
sparqlButtonDiv.appendChild(generateSparqlButton())
|
|
200
|
-
tr.appendChild(sparqlButtonDiv)
|
|
201
|
-
*/
|
|
202
|
-
typeSelectorDiv = doc.createElement('td');
|
|
203
|
-
tr.appendChild(typeSelectorDiv);
|
|
204
|
-
addColumnDiv = doc.createElement('td');
|
|
205
|
-
tr.appendChild(addColumnDiv);
|
|
206
|
-
result.appendChild(tr);
|
|
207
|
-
return result;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Add the SELECT details to the query being built.
|
|
211
|
-
|
|
212
|
-
function addSelectToQuery(query, type) {
|
|
213
|
-
var selectedColumns = type.getColumns();
|
|
214
|
-
for (var i = 0; i < selectedColumns.length; ++i) {
|
|
215
|
-
// TODO: autogenerate nicer names for variables
|
|
216
|
-
// variables have to be unambiguous
|
|
217
|
-
|
|
218
|
-
var variable = kb.variable('_col' + i);
|
|
219
|
-
query.vars.push(variable);
|
|
220
|
-
selectedColumns[i].setVariable(variable);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Add WHERE details to the query being built.
|
|
225
|
-
|
|
226
|
-
function addWhereToQuery(query, rowVar, type) {
|
|
227
|
-
var queryType = type.type;
|
|
228
|
-
if (!queryType) {
|
|
229
|
-
queryType = kb.variable('_any');
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// _row a type
|
|
233
|
-
query.pat.add(rowVar, UI.ns.rdf('type'), queryType);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Generate OPTIONAL column selectors.
|
|
237
|
-
|
|
238
|
-
function addColumnsToQuery(query, rowVar, type) {
|
|
239
|
-
var selectedColumns = type.getColumns();
|
|
240
|
-
for (var i = 0; i < selectedColumns.length; ++i) {
|
|
241
|
-
var column = selectedColumns[i];
|
|
242
|
-
var formula = kb.formula();
|
|
243
|
-
formula.add(rowVar, column.predicate, column.getVariable());
|
|
244
|
-
query.pat.optional.push(formula);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Generate a query object from the currently-selected type
|
|
249
|
-
// object.
|
|
250
|
-
|
|
251
|
-
function generateQuery(type) {
|
|
252
|
-
var query = new rdf.Query();
|
|
253
|
-
var rowVar = kb.variable(keyVariable.slice(1)); // don't pass '?'
|
|
254
|
-
|
|
255
|
-
addSelectToQuery(query, type);
|
|
256
|
-
addWhereToQuery(query, rowVar, type);
|
|
257
|
-
addColumnsToQuery(query, rowVar, type);
|
|
258
|
-
return query;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// Build the contents of the tableDiv element, filtered according
|
|
262
|
-
// to the specified type.
|
|
263
|
-
|
|
264
|
-
function buildFilteredTable(type) {
|
|
265
|
-
// Generate "add column" cell.
|
|
266
|
-
|
|
267
|
-
clearElement(addColumnDiv);
|
|
268
|
-
addColumnDiv.appendChild(generateColumnAddDropdown(type));
|
|
269
|
-
var query = generateQuery(type);
|
|
270
|
-
updateTable(query, type);
|
|
271
|
-
}
|
|
272
|
-
function updateTable(query, type) {
|
|
273
|
-
// Stop the previous query from doing any updates.
|
|
274
|
-
|
|
275
|
-
if (lastQuery) {
|
|
276
|
-
lastQuery.running = false;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Render the HTML table.
|
|
280
|
-
|
|
281
|
-
var htmlTable = renderTableForQuery(query, type);
|
|
282
|
-
|
|
283
|
-
// Clear the tableDiv element, and replace with the new table.
|
|
284
|
-
|
|
285
|
-
clearElement(tableDiv);
|
|
286
|
-
tableDiv.appendChild(htmlTable);
|
|
287
|
-
|
|
288
|
-
// Save the query for the edit dialog.
|
|
289
|
-
|
|
290
|
-
lastQuery = query;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Remove all subelements of the specified element.
|
|
294
|
-
|
|
295
|
-
function clearElement(element) {
|
|
296
|
-
while (element.childNodes.length > 0) {
|
|
297
|
-
element.removeChild(element.childNodes[0]);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// A SubjectType is created for each rdf:type discovered.
|
|
302
|
-
|
|
303
|
-
function SubjectType(type) {
|
|
304
|
-
this.type = type;
|
|
305
|
-
this.columns = null;
|
|
306
|
-
this.allColumns = [];
|
|
307
|
-
this.useCount = 0;
|
|
308
|
-
|
|
309
|
-
// Get a list of all columns used by this type.
|
|
310
|
-
|
|
311
|
-
this.getAllColumns = function () {
|
|
312
|
-
return this.allColumns;
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
// Get a list of the current columns used by this type
|
|
316
|
-
// (subset of allColumns)
|
|
317
|
-
|
|
318
|
-
this.getColumns = function () {
|
|
319
|
-
// The first time through, get a list of all the columns
|
|
320
|
-
// and select only the six most popular columns.
|
|
321
|
-
|
|
322
|
-
if (!this.columns) {
|
|
323
|
-
var allColumns = this.getAllColumns();
|
|
324
|
-
this.columns = allColumns.slice(0, 7);
|
|
325
|
-
}
|
|
326
|
-
return this.columns;
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
// Get a list of unused columns
|
|
330
|
-
|
|
331
|
-
this.getUnusedColumns = function () {
|
|
332
|
-
var allColumns = this.getAllColumns();
|
|
333
|
-
var columns = this.getColumns();
|
|
334
|
-
var result = [];
|
|
335
|
-
for (var i = 0; i < allColumns.length; ++i) {
|
|
336
|
-
if (columns.indexOf(allColumns[i]) === -1) {
|
|
337
|
-
result.push(allColumns[i]);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return result;
|
|
341
|
-
};
|
|
342
|
-
this.addColumn = function (column) {
|
|
343
|
-
this.columns.push(column);
|
|
344
|
-
};
|
|
345
|
-
this.removeColumn = function (column) {
|
|
346
|
-
this.columns = this.columns.filter(function (x) {
|
|
347
|
-
return x !== column;
|
|
348
|
-
});
|
|
349
|
-
};
|
|
350
|
-
this.getLabel = function () {
|
|
351
|
-
return utils.label(this.type);
|
|
352
|
-
};
|
|
353
|
-
this.addUse = function () {
|
|
354
|
-
this.useCount += 1;
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Class representing a column in the table.
|
|
359
|
-
|
|
360
|
-
function Column() {
|
|
361
|
-
this.useCount = 0;
|
|
362
|
-
|
|
363
|
-
// Have we checked any values for this column yet?
|
|
364
|
-
|
|
365
|
-
this.checkedAnyValues = false;
|
|
366
|
-
|
|
367
|
-
// If the range is unknown, but we just get literals in this
|
|
368
|
-
// column, then we can generate a literal selector.
|
|
369
|
-
|
|
370
|
-
this.possiblyLiteral = true;
|
|
371
|
-
|
|
372
|
-
// If the range is unknown, but we just get literals and they
|
|
373
|
-
// match the regular expression for numbers, we can generate
|
|
374
|
-
// a number selector.
|
|
375
|
-
|
|
376
|
-
this.possiblyNumber = true;
|
|
377
|
-
|
|
378
|
-
// We accumulate classes which things in the column must be a member of
|
|
379
|
-
|
|
380
|
-
this.constraints = [];
|
|
381
|
-
|
|
382
|
-
// Check values as they are read. If we don't know what the
|
|
383
|
-
// range is, we might be able to infer that it is a literal
|
|
384
|
-
// if all of the values are literals. Similarly, we might
|
|
385
|
-
// be able to determine if the literal values are actually
|
|
386
|
-
// numbers (using regexps).
|
|
387
|
-
|
|
388
|
-
this.checkValue = function (term) {
|
|
389
|
-
var termType = term.termType;
|
|
390
|
-
if (this.possiblyLiteral && termType !== 'Literal' && termType !== 'NamedNode') {
|
|
391
|
-
this.possiblyNumber = false;
|
|
392
|
-
this.possiblyLiteral = false;
|
|
393
|
-
} else if (this.possiblyNumber) {
|
|
394
|
-
if (termType !== 'Literal') {
|
|
395
|
-
this.possiblyNumber = false;
|
|
396
|
-
} else {
|
|
397
|
-
var literalValue = term.value;
|
|
398
|
-
if (!literalValue.match(/^-?\d+(\.\d*)?$/)) {
|
|
399
|
-
this.possiblyNumber = false;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
this.checkedAnyValues = true;
|
|
404
|
-
};
|
|
405
|
-
this.getVariable = function () {
|
|
406
|
-
return this.variable;
|
|
407
|
-
};
|
|
408
|
-
this.setVariable = function (variable) {
|
|
409
|
-
this.variable = variable;
|
|
410
|
-
};
|
|
411
|
-
this.getKey = function () {
|
|
412
|
-
return this.variable.toString();
|
|
413
|
-
};
|
|
414
|
-
this.addUse = function () {
|
|
415
|
-
this.useCount += 1;
|
|
416
|
-
};
|
|
417
|
-
this.getHints = function () {
|
|
418
|
-
if (options && options.hints && this.variable && options.hints[this.variable.toNT()]) {
|
|
419
|
-
return options.hints[this.variable.toNT()];
|
|
420
|
-
}
|
|
421
|
-
return {};
|
|
422
|
-
};
|
|
423
|
-
this.getLabel = function () {
|
|
424
|
-
if (this.getHints().label) {
|
|
425
|
-
return this.getHints().label;
|
|
426
|
-
}
|
|
427
|
-
if (this.predicate) {
|
|
428
|
-
if (this.predicate.sameTerm(ns.rdf('type')) && this.superClass) {
|
|
429
|
-
return utils.label(this.superClass, true); // do initial cap
|
|
430
|
-
}
|
|
431
|
-
return utils.label(this.predicate);
|
|
432
|
-
} else if (this.variable) {
|
|
433
|
-
return this.variable.toString();
|
|
434
|
-
} else {
|
|
435
|
-
return 'unlabeled column?';
|
|
436
|
-
}
|
|
437
|
-
};
|
|
438
|
-
this.setPredicate = function (predicate, inverse, other) {
|
|
439
|
-
if (inverse) {
|
|
440
|
-
// variable is in the subject pos
|
|
441
|
-
this.inverse = predicate;
|
|
442
|
-
this.constraints = this.constraints.concat(kb.each(predicate, UI.ns.rdfs('domain')));
|
|
443
|
-
if (predicate.sameTerm(ns.rdfs('subClassOf')) && other.termType === 'NamedNode') {
|
|
444
|
-
this.superClass = other;
|
|
445
|
-
this.alternatives = kb.each(undefined, ns.rdfs('subClassOf'), other);
|
|
446
|
-
}
|
|
447
|
-
} else {
|
|
448
|
-
// variable is the object
|
|
449
|
-
this.predicate = predicate;
|
|
450
|
-
this.constraints = this.constraints.concat(kb.each(predicate, UI.ns.rdfs('range')));
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
this.getConstraints = function () {
|
|
454
|
-
return this.constraints;
|
|
455
|
-
};
|
|
456
|
-
this.filterFunction = function () {
|
|
457
|
-
return true;
|
|
458
|
-
};
|
|
459
|
-
this.sortKey = function () {
|
|
460
|
-
return this.getLabel().toLowerCase();
|
|
461
|
-
};
|
|
462
|
-
this.isImageColumn = function () {
|
|
463
|
-
for (var i = 0; i < this.constraints.length; i++) {
|
|
464
|
-
if (this.constraints[i].uri in IMAGE_TYPES) return true;
|
|
465
|
-
}
|
|
466
|
-
return false;
|
|
467
|
-
};
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// Convert an object to an array.
|
|
471
|
-
|
|
472
|
-
function objectToArray(obj, filter) {
|
|
473
|
-
var result = [];
|
|
474
|
-
for (var property in obj) {
|
|
475
|
-
// @@@ have to guard against methods
|
|
476
|
-
var value = obj[property];
|
|
477
|
-
if (!filter || filter(property, value)) {
|
|
478
|
-
result.push(value);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
return result;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Generate an <option> in a drop-down list.
|
|
485
|
-
|
|
486
|
-
function optionElement(label, value) {
|
|
487
|
-
var result = doc.createElement('option');
|
|
488
|
-
result.setAttribute('value', value);
|
|
489
|
-
result.appendChild(doc.createTextNode(label));
|
|
490
|
-
return result;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Generate drop-down list box for choosing type of data displayed
|
|
494
|
-
|
|
495
|
-
function generateTypeSelector(allType, types) {
|
|
496
|
-
var resultDiv = doc.createElement('div');
|
|
497
|
-
resultDiv.appendChild(doc.createTextNode('Select type: '));
|
|
498
|
-
var dropdown = doc.createElement('select');
|
|
499
|
-
dropdown.appendChild(optionElement('All types', 'null'));
|
|
500
|
-
for (var uri in types) {
|
|
501
|
-
dropdown.appendChild(optionElement(types[uri].getLabel(), uri));
|
|
502
|
-
}
|
|
503
|
-
dropdown.addEventListener('click', function () {
|
|
504
|
-
var type;
|
|
505
|
-
if (dropdown.value === 'null') {
|
|
506
|
-
type = allType;
|
|
507
|
-
} else {
|
|
508
|
-
type = types[dropdown.value];
|
|
509
|
-
}
|
|
510
|
-
typeSelectorChanged(type);
|
|
511
|
-
}, false);
|
|
512
|
-
resultDiv.appendChild(dropdown);
|
|
513
|
-
return resultDiv;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// Callback invoked when the type selector drop-down list is changed.
|
|
517
|
-
|
|
518
|
-
function typeSelectorChanged(selectedType) {
|
|
519
|
-
buildFilteredTable(selectedType);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
// Build drop-down list to add a new column
|
|
523
|
-
|
|
524
|
-
function generateColumnAddDropdown(type) {
|
|
525
|
-
var resultDiv = doc.createElement('div');
|
|
526
|
-
var unusedColumns = type.getUnusedColumns();
|
|
527
|
-
unusedColumns.sort(function (a, b) {
|
|
528
|
-
var aLabel = a.sortKey();
|
|
529
|
-
var bLabel = b.sortKey();
|
|
530
|
-
return (aLabel > bLabel) - (aLabel < bLabel);
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
// If there are no unused columns, the div is empty.
|
|
534
|
-
|
|
535
|
-
if (unusedColumns.length > 0) {
|
|
536
|
-
resultDiv.appendChild(doc.createTextNode('Add column: '));
|
|
537
|
-
|
|
538
|
-
// Build dropdown list of unused columns.
|
|
539
|
-
|
|
540
|
-
var dropdown = doc.createElement('select');
|
|
541
|
-
dropdown.appendChild(optionElement('', '-1'));
|
|
542
|
-
for (var i = 0; i < unusedColumns.length; ++i) {
|
|
543
|
-
var column = unusedColumns[i];
|
|
544
|
-
dropdown.appendChild(optionElement(column.getLabel(), '' + i));
|
|
545
|
-
}
|
|
546
|
-
resultDiv.appendChild(dropdown);
|
|
547
|
-
|
|
548
|
-
// Invoke callback when the dropdown is changed, to add
|
|
549
|
-
// the column and reload the table.
|
|
550
|
-
|
|
551
|
-
dropdown.addEventListener('click', function () {
|
|
552
|
-
var columnIndex = Number(dropdown.value);
|
|
553
|
-
if (columnIndex >= 0) {
|
|
554
|
-
type.addColumn(unusedColumns[columnIndex]);
|
|
555
|
-
buildFilteredTable(type);
|
|
556
|
-
}
|
|
557
|
-
}, false);
|
|
558
|
-
}
|
|
559
|
-
return resultDiv;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// Find the column for a given variable
|
|
563
|
-
|
|
564
|
-
function getColumnForVariable(columns, variableNT) {
|
|
565
|
-
for (var predicateUri in columns) {
|
|
566
|
-
var column = columns[predicateUri];
|
|
567
|
-
if (column.variable.toNT() === variableNT) {
|
|
568
|
-
return column;
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
throw new Error("getColumnForVariable: no column for variable ".concat(variableNT));
|
|
572
|
-
// return null
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
// Find the column for a given predicate, creating a new column object
|
|
576
|
-
// if necessary.
|
|
577
|
-
|
|
578
|
-
function getColumnForPredicate(columns, predicate) {
|
|
579
|
-
var column;
|
|
580
|
-
if (predicate.uri in columns) {
|
|
581
|
-
column = columns[predicate.uri];
|
|
582
|
-
} else {
|
|
583
|
-
column = new Column();
|
|
584
|
-
column.setPredicate(predicate);
|
|
585
|
-
columns[predicate.uri] = column;
|
|
586
|
-
}
|
|
587
|
-
return column;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// Find a type by its URI, creating a new SubjectType object if
|
|
591
|
-
// necessary.
|
|
592
|
-
|
|
593
|
-
function getTypeForObject(types, type) {
|
|
594
|
-
var subjectType;
|
|
595
|
-
if (type.uri in types) {
|
|
596
|
-
subjectType = types[type.uri];
|
|
597
|
-
} else {
|
|
598
|
-
subjectType = new SubjectType(type);
|
|
599
|
-
types[type.uri] = subjectType;
|
|
600
|
-
}
|
|
601
|
-
return subjectType;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
// Discover types and subjects for search.
|
|
605
|
-
|
|
606
|
-
function discoverTypes() {
|
|
607
|
-
// rdf:type properties of subjects, indexed by URI for the type.
|
|
608
|
-
|
|
609
|
-
var types = {};
|
|
610
|
-
|
|
611
|
-
// Get a list of statements that match: ? rdfs:type ?
|
|
612
|
-
// From this we can get a list of subjects and types.
|
|
613
|
-
|
|
614
|
-
var subjectList = kb.statementsMatching(undefined, UI.ns.rdf('type'), tableClass,
|
|
615
|
-
// can be undefined OR
|
|
616
|
-
sourceDocument); // can be undefined
|
|
617
|
-
|
|
618
|
-
// Subjects for later lookup. This is a mapping of type URIs to
|
|
619
|
-
// lists of subjects (it is necessary to record the type of
|
|
620
|
-
// a subject).
|
|
621
|
-
|
|
622
|
-
var subjects = {};
|
|
623
|
-
for (var i = 0; i < subjectList.length; ++i) {
|
|
624
|
-
var type = subjectList[i].object;
|
|
625
|
-
if (type.termType !== 'NamedNode') {
|
|
626
|
-
// @@ no bnodes?
|
|
627
|
-
continue;
|
|
628
|
-
}
|
|
629
|
-
var typeObj = getTypeForObject(types, type);
|
|
630
|
-
if (!(type.uri in subjects)) {
|
|
631
|
-
subjects[type.uri] = [];
|
|
632
|
-
}
|
|
633
|
-
subjects[type.uri].push(subjectList[i].subject);
|
|
634
|
-
typeObj.addUse();
|
|
635
|
-
}
|
|
636
|
-
return [subjects, types];
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Get columns for the given subject.
|
|
640
|
-
|
|
641
|
-
function getSubjectProperties(subject, columns) {
|
|
642
|
-
// Get a list of properties of this subject.
|
|
643
|
-
|
|
644
|
-
var properties = kb.statementsMatching(subject, undefined, undefined, sourceDocument);
|
|
645
|
-
var result = {};
|
|
646
|
-
for (var j = 0; j < properties.length; ++j) {
|
|
647
|
-
var predicate = properties[j].predicate;
|
|
648
|
-
if (predicate.uri in FORBIDDEN_COLUMNS) {
|
|
649
|
-
continue;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
// Find/create a column for this predicate.
|
|
653
|
-
|
|
654
|
-
var column = getColumnForPredicate(columns, predicate);
|
|
655
|
-
column.checkValue(properties[j].object);
|
|
656
|
-
result[predicate.uri] = column;
|
|
657
|
-
}
|
|
658
|
-
return result;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// Identify the columns associated with a type.
|
|
662
|
-
|
|
663
|
-
function identifyColumnsForType(type, subjects) {
|
|
664
|
-
var allColumns = {};
|
|
665
|
-
|
|
666
|
-
// Process each subject of this type to build up the
|
|
667
|
-
// column list.
|
|
668
|
-
|
|
669
|
-
for (var i = 0; i < subjects.length; ++i) {
|
|
670
|
-
var columns = getSubjectProperties(subjects[i], allColumns);
|
|
671
|
-
for (var predicateUri in columns) {
|
|
672
|
-
var column = columns[predicateUri];
|
|
673
|
-
column.addUse();
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
// Generate the columns list
|
|
678
|
-
|
|
679
|
-
var allColumnsList = objectToArray(allColumns);
|
|
680
|
-
sortColumns(allColumnsList);
|
|
681
|
-
type.allColumns = allColumnsList;
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
// Build table information from parsing RDF statements.
|
|
685
|
-
|
|
686
|
-
function calculateTable() {
|
|
687
|
-
// Find the types that we will display in the dropdown
|
|
688
|
-
// list box, and associated objects of those types.
|
|
689
|
-
|
|
690
|
-
var subjects, types;
|
|
691
|
-
var s = discoverTypes();
|
|
692
|
-
// eslint-disable-next-line prefer-const
|
|
693
|
-
subjects = s[0];
|
|
694
|
-
// eslint-disable-next-line prefer-const
|
|
695
|
-
types = s[1]; // no [ ] on LHS
|
|
696
|
-
|
|
697
|
-
for (var typeUrl in subjects) {
|
|
698
|
-
var subjectList = subjects[typeUrl];
|
|
699
|
-
var type = types[typeUrl];
|
|
700
|
-
identifyColumnsForType(type, subjectList);
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// TODO: Special type that captures all rows.
|
|
704
|
-
// Combine columns from all types
|
|
705
|
-
|
|
706
|
-
var allType = new SubjectType(null);
|
|
707
|
-
return [allType, objectToArray(types)];
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// Sort the list of columns by the most common columns.
|
|
711
|
-
|
|
712
|
-
function sortColumns(columns) {
|
|
713
|
-
function sortFunction(a, b) {
|
|
714
|
-
return (a.useCount < b.useCount) - (a.useCount > b.useCount);
|
|
715
|
-
}
|
|
716
|
-
columns.sort(sortFunction);
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// Create the delete button for a column.
|
|
720
|
-
|
|
721
|
-
function renderColumnDeleteButton(type, column) {
|
|
722
|
-
var button = doc.createElement('a');
|
|
723
|
-
button.appendChild(doc.createTextNode('[x]'));
|
|
724
|
-
button.addEventListener('click', function () {
|
|
725
|
-
type.removeColumn(column);
|
|
726
|
-
buildFilteredTable(type);
|
|
727
|
-
}, false);
|
|
728
|
-
return button;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
// Render the table header for the HTML table.
|
|
732
|
-
|
|
733
|
-
function renderTableHeader(columns, type) {
|
|
734
|
-
var tr = doc.createElement('tr');
|
|
735
|
-
|
|
736
|
-
/* Empty header for link column */
|
|
737
|
-
var linkTd = doc.createElement('th');
|
|
738
|
-
tr.appendChild(linkTd);
|
|
739
|
-
for (var i = 0; i < columns.length; ++i) {
|
|
740
|
-
var th = doc.createElement('th');
|
|
741
|
-
var column = columns[i];
|
|
742
|
-
th.appendChild(doc.createTextNode(column.getLabel()));
|
|
743
|
-
|
|
744
|
-
// We can only add a delete button if we are using the
|
|
745
|
-
// proper interface and have a type to delete from:
|
|
746
|
-
if (type) {
|
|
747
|
-
th.appendChild(renderColumnDeleteButton(type, column));
|
|
748
|
-
}
|
|
749
|
-
tr.appendChild(th);
|
|
750
|
-
}
|
|
751
|
-
return tr;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
// Sort the rows in the rendered table by data from a specific
|
|
755
|
-
// column, using the provided sort function to compare values.
|
|
756
|
-
|
|
757
|
-
function applyColumnSort(rows, column, sortFunction, reverse) {
|
|
758
|
-
var columnKey = column.getKey();
|
|
759
|
-
|
|
760
|
-
// Sort the rows array.
|
|
761
|
-
rows.sort(function (row1, row2) {
|
|
762
|
-
var row1Value = null;
|
|
763
|
-
var row2Value = null;
|
|
764
|
-
if (columnKey in row1.values) {
|
|
765
|
-
row1Value = row1.values[columnKey][0];
|
|
766
|
-
}
|
|
767
|
-
if (columnKey in row2.values) {
|
|
768
|
-
row2Value = row2.values[columnKey][0];
|
|
769
|
-
}
|
|
770
|
-
var result = sortFunction(row1Value, row2Value);
|
|
771
|
-
if (reverse) {
|
|
772
|
-
return -result;
|
|
773
|
-
} else {
|
|
774
|
-
return result;
|
|
775
|
-
}
|
|
776
|
-
});
|
|
777
|
-
|
|
778
|
-
// Remove all rows from the table:
|
|
779
|
-
|
|
780
|
-
if (rows.length) {
|
|
781
|
-
var parentTable = rows[0]._htmlRow.parentNode;
|
|
782
|
-
for (var i = 0; i < rows.length; ++i) {
|
|
783
|
-
parentTable.removeChild(rows[i]._htmlRow);
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
// Add back the rows in the new sorted order:
|
|
787
|
-
|
|
788
|
-
for (var _i = 0; _i < rows.length; ++_i) {
|
|
789
|
-
parentTable.appendChild(rows[_i]._htmlRow);
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
// Filter the list of rows based on the selectors for the
|
|
795
|
-
// columns.
|
|
796
|
-
|
|
797
|
-
function applyColumnFiltersToRow(row, columns) {
|
|
798
|
-
var rowDisplayed = true;
|
|
799
|
-
|
|
800
|
-
// Check the filter functions for every column.
|
|
801
|
-
// The row should only be displayed if the filter functions
|
|
802
|
-
// for all of the columns return true.
|
|
803
|
-
|
|
804
|
-
for (var c = 0; c < columns.length; ++c) {
|
|
805
|
-
var column = columns[c];
|
|
806
|
-
var columnKey = column.getKey();
|
|
807
|
-
var columnValue = null;
|
|
808
|
-
if (columnKey in row.values) {
|
|
809
|
-
columnValue = row.values[columnKey][0];
|
|
810
|
-
}
|
|
811
|
-
if (!column.filterFunction(columnValue)) {
|
|
812
|
-
rowDisplayed = false;
|
|
813
|
-
break;
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
// Show or hide the HTML row according to the result
|
|
818
|
-
// from the filter function.
|
|
819
|
-
|
|
820
|
-
var htmlRow = row._htmlRow;
|
|
821
|
-
if (rowDisplayed) {
|
|
822
|
-
htmlRow.style.display = '';
|
|
823
|
-
} else {
|
|
824
|
-
htmlRow.style.display = 'none';
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
// Filter the list of rows based on the selectors for the
|
|
829
|
-
// columns.
|
|
830
|
-
|
|
831
|
-
function applyColumnFilters(rows, columns) {
|
|
832
|
-
// Apply filterFunction to each row.
|
|
833
|
-
|
|
834
|
-
for (var r = 0; r < rows.length; ++r) {
|
|
835
|
-
var row = rows[r];
|
|
836
|
-
applyColumnFiltersToRow(row, columns);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
// /////////////////////////////////// Literal column handling
|
|
841
|
-
|
|
842
|
-
// Sort by literal value
|
|
843
|
-
|
|
844
|
-
function literalSort(rows, column, reverse) {
|
|
845
|
-
function literalToString(colValue) {
|
|
846
|
-
if (colValue) {
|
|
847
|
-
if (colValue.termType === 'Literal') {
|
|
848
|
-
return colValue.value.toLowerCase();
|
|
849
|
-
} else if (colValue.termType === 'NamedNode') {
|
|
850
|
-
return utils.label(colValue).toLowerCase();
|
|
851
|
-
}
|
|
852
|
-
return colValue.value.toLowerCase();
|
|
853
|
-
} else {
|
|
854
|
-
return '';
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
function literalCompare(value1, value2) {
|
|
858
|
-
var strValue1 = literalToString(value1);
|
|
859
|
-
var strValue2 = literalToString(value2);
|
|
860
|
-
if (strValue1 < strValue2) {
|
|
861
|
-
return -1;
|
|
862
|
-
} else if (strValue1 > strValue2) {
|
|
863
|
-
return 1;
|
|
864
|
-
} else {
|
|
865
|
-
return 0;
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
applyColumnSort(rows, column, literalCompare, reverse);
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
// Generates a selector for an RDF literal column.
|
|
872
|
-
|
|
873
|
-
function renderLiteralSelector(rows, columns, column) {
|
|
874
|
-
var result = doc.createElement('div');
|
|
875
|
-
var textBox = doc.createElement('input');
|
|
876
|
-
textBox.setAttribute('type', 'text');
|
|
877
|
-
textBox.style.width = '70%';
|
|
878
|
-
result.appendChild(textBox);
|
|
879
|
-
var sort1 = doc.createElement('span');
|
|
880
|
-
sort1.appendChild(doc.createTextNode("\u25BC"));
|
|
881
|
-
sort1.addEventListener('click', function () {
|
|
882
|
-
literalSort(rows, column, false);
|
|
883
|
-
}, false);
|
|
884
|
-
result.appendChild(sort1);
|
|
885
|
-
var sort2 = doc.createElement('span');
|
|
886
|
-
sort2.appendChild(doc.createTextNode("\u25B2"));
|
|
887
|
-
sort2.addEventListener('click', function () {
|
|
888
|
-
literalSort(rows, column, true);
|
|
889
|
-
}, false);
|
|
890
|
-
result.appendChild(sort2);
|
|
891
|
-
var substring = null;
|
|
892
|
-
|
|
893
|
-
// Filter the table to show only rows that have a particular
|
|
894
|
-
// substring in the specified column.
|
|
895
|
-
|
|
896
|
-
column.filterFunction = function (colValue) {
|
|
897
|
-
if (!substring) {
|
|
898
|
-
return true;
|
|
899
|
-
} else if (!colValue) {
|
|
900
|
-
return false;
|
|
901
|
-
} else {
|
|
902
|
-
var literalValue;
|
|
903
|
-
if (colValue.termType === 'Literal') {
|
|
904
|
-
literalValue = colValue.value;
|
|
905
|
-
} else if (colValue.termType === 'NamedNode') {
|
|
906
|
-
literalValue = utils.label(colValue);
|
|
907
|
-
} else {
|
|
908
|
-
literalValue = '';
|
|
909
|
-
}
|
|
910
|
-
return literalValue.toLowerCase().indexOf(substring) >= 0;
|
|
911
|
-
}
|
|
912
|
-
};
|
|
913
|
-
textBox.addEventListener('keyup', function () {
|
|
914
|
-
if (textBox.value !== '') {
|
|
915
|
-
substring = textBox.value.toLowerCase();
|
|
916
|
-
} else {
|
|
917
|
-
substring = null;
|
|
918
|
-
}
|
|
919
|
-
applyColumnFilters(rows, columns);
|
|
920
|
-
}, false);
|
|
921
|
-
return result;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
// /////////////////////////////////// Enumeration
|
|
925
|
-
|
|
926
|
-
// Generates a dropdown selector for enumeration types include
|
|
927
|
-
//
|
|
928
|
-
// @param rows,
|
|
929
|
-
// @param columns, the mapping of predictae URIs to columns
|
|
930
|
-
// @param column,
|
|
931
|
-
// @param list, List of alternative terms
|
|
932
|
-
//
|
|
933
|
-
function renderEnumSelector(rows, columns, column, list) {
|
|
934
|
-
var doMultiple = true;
|
|
935
|
-
var result = doc.createElement('div');
|
|
936
|
-
var dropdown = doc.createElement('select');
|
|
937
|
-
var searchValue = {}; // Defualt to all enabled
|
|
938
|
-
for (var i = 0; i < list.length; ++i) {
|
|
939
|
-
var value = list[i];
|
|
940
|
-
searchValue[value.uri] = true;
|
|
941
|
-
}
|
|
942
|
-
var initialSelection = getHints(column).initialSelection;
|
|
943
|
-
if (initialSelection) searchValue = initialSelection;
|
|
944
|
-
if (doMultiple) dropdown.setAttribute('multiple', 'true');else dropdown.appendChild(optionElement('(All)', '-1'));
|
|
945
|
-
for (var _i2 = 0; _i2 < list.length; ++_i2) {
|
|
946
|
-
var _value = list[_i2];
|
|
947
|
-
var ele = optionElement(utils.label(_value), _i2);
|
|
948
|
-
if (searchValue[_value.uri]) ele.selected = true;
|
|
949
|
-
dropdown.appendChild(ele);
|
|
950
|
-
}
|
|
951
|
-
result.appendChild(dropdown);
|
|
952
|
-
|
|
953
|
-
// Select based on an enum value.
|
|
954
|
-
|
|
955
|
-
column.filterFunction = function (colValue) {
|
|
956
|
-
return !searchValue || colValue && searchValue[colValue.uri];
|
|
957
|
-
};
|
|
958
|
-
dropdown.addEventListener('click', function () {
|
|
959
|
-
if (doMultiple) {
|
|
960
|
-
searchValue = {};
|
|
961
|
-
var opt = dropdown.options;
|
|
962
|
-
for (var _i3 = 0; _i3 < opt.length; _i3++) {
|
|
963
|
-
var option = opt[_i3];
|
|
964
|
-
var index = Number(option.value);
|
|
965
|
-
if (opt[_i3].selected) searchValue[list[index].uri] = true;
|
|
966
|
-
}
|
|
967
|
-
} else {
|
|
968
|
-
var _index = Number(dropdown.value); // adjusted in Standard tweaks 2018-01
|
|
969
|
-
if (_index < 0) {
|
|
970
|
-
searchValue = null;
|
|
971
|
-
} else {
|
|
972
|
-
searchValue = {};
|
|
973
|
-
searchValue[list[_index].uri] = true;
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
applyColumnFilters(rows, columns);
|
|
977
|
-
}, true);
|
|
978
|
-
return result;
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
// //////////////////////////////////// Numeric
|
|
982
|
-
//
|
|
983
|
-
// Selector for XSD number types.
|
|
984
|
-
|
|
985
|
-
function renderNumberSelector(rows, columns, column) {
|
|
986
|
-
var result = doc.createElement('div');
|
|
987
|
-
var minSelector = doc.createElement('input');
|
|
988
|
-
minSelector.setAttribute('type', 'text');
|
|
989
|
-
minSelector.style.width = '40px';
|
|
990
|
-
result.appendChild(minSelector);
|
|
991
|
-
var maxSelector = doc.createElement('input');
|
|
992
|
-
maxSelector.setAttribute('type', 'text');
|
|
993
|
-
maxSelector.style.width = '40px';
|
|
994
|
-
result.appendChild(maxSelector);
|
|
995
|
-
|
|
996
|
-
// Select based on minimum/maximum limits.
|
|
997
|
-
|
|
998
|
-
var min = null;
|
|
999
|
-
var max = null;
|
|
1000
|
-
column.filterFunction = function (colValue) {
|
|
1001
|
-
if (colValue) {
|
|
1002
|
-
colValue = Number(colValue);
|
|
1003
|
-
}
|
|
1004
|
-
if (min && (!colValue || colValue < min)) {
|
|
1005
|
-
return false;
|
|
1006
|
-
}
|
|
1007
|
-
if (max && (!colValue || colValue > max)) {
|
|
1008
|
-
return false;
|
|
1009
|
-
}
|
|
1010
|
-
return true;
|
|
1011
|
-
};
|
|
1012
|
-
|
|
1013
|
-
// When the values in the boxes are changed, update the
|
|
1014
|
-
// displayed columns.
|
|
1015
|
-
|
|
1016
|
-
function eventListener() {
|
|
1017
|
-
if (minSelector.value === '') {
|
|
1018
|
-
min = null;
|
|
1019
|
-
} else {
|
|
1020
|
-
min = Number(minSelector.value);
|
|
1021
|
-
}
|
|
1022
|
-
if (maxSelector.value === '') {
|
|
1023
|
-
max = null;
|
|
1024
|
-
} else {
|
|
1025
|
-
max = Number(maxSelector.value);
|
|
1026
|
-
}
|
|
1027
|
-
applyColumnFilters(rows, columns);
|
|
1028
|
-
}
|
|
1029
|
-
minSelector.addEventListener('keyup', eventListener, false);
|
|
1030
|
-
maxSelector.addEventListener('keyup', eventListener, false);
|
|
1031
|
-
return result;
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
// /////////////////////////////////////////////////////////////////
|
|
1035
|
-
|
|
1036
|
-
// Fallback attempts at generating a selector if other attempts fail.
|
|
1037
|
-
|
|
1038
|
-
function fallbackRenderTableSelector(rows, columns, column) {
|
|
1039
|
-
// Have all values matched as numbers?
|
|
1040
|
-
|
|
1041
|
-
if (column.checkedAnyValues && column.possiblyNumber) {
|
|
1042
|
-
return renderNumberSelector(rows, columns, column);
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
// Have all values been literals?
|
|
1046
|
-
|
|
1047
|
-
if (column.possiblyLiteral) {
|
|
1048
|
-
return renderLiteralSelector(rows, columns, column);
|
|
1049
|
-
}
|
|
1050
|
-
return null;
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
// Render a selector for a given row.
|
|
1054
|
-
|
|
1055
|
-
function renderTableSelector(rows, columns, column) {
|
|
1056
|
-
// What type of data is in this column? Check the constraints for
|
|
1057
|
-
// this predicate.
|
|
1058
|
-
|
|
1059
|
-
// If this is a class which can be one of various sibling classes?
|
|
1060
|
-
if (column.superClass && column.alternatives.length > 0) {
|
|
1061
|
-
return renderEnumSelector(rows, columns, column, column.alternatives);
|
|
1062
|
-
}
|
|
1063
|
-
var cs = column.getConstraints();
|
|
1064
|
-
var range;
|
|
1065
|
-
for (var i = 0; i < cs.length; i++) {
|
|
1066
|
-
range = cs[i];
|
|
1067
|
-
|
|
1068
|
-
// Is this a number type?
|
|
1069
|
-
// Alternatively, is this an rdf:Literal type where all of
|
|
1070
|
-
// the values match as numbers?
|
|
1071
|
-
|
|
1072
|
-
if (column.checkedAnyValues && column.possiblyNumber || range.uri in XSD_NUMBER_TYPES) {
|
|
1073
|
-
return renderNumberSelector(rows, columns, column);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
// rdf:Literal? Assume a string at this point
|
|
1077
|
-
|
|
1078
|
-
if (range.uri === RDFS_LITERAL) {
|
|
1079
|
-
return renderLiteralSelector(rows, columns, column);
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
// Is this an enumeration type?
|
|
1083
|
-
|
|
1084
|
-
// Also ToDo: @@@ Handle membership of classes whcih are disjointUnions
|
|
1085
|
-
|
|
1086
|
-
var choices = kb.each(range, UI.ns.owl('oneOf'));
|
|
1087
|
-
if (choices.length > 0) {
|
|
1088
|
-
return renderEnumSelector(rows, columns, column, choices.elements);
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
return fallbackRenderTableSelector(rows, columns, column);
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
// Generate the search selectors for the table columns.
|
|
1095
|
-
|
|
1096
|
-
function renderTableSelectors(rows, columns) {
|
|
1097
|
-
var tr = doc.createElement('tr');
|
|
1098
|
-
tr.className = 'selectors';
|
|
1099
|
-
|
|
1100
|
-
// Empty link column
|
|
1101
|
-
|
|
1102
|
-
tr.appendChild(doc.createElement('td'));
|
|
1103
|
-
|
|
1104
|
-
// Generate selectors.
|
|
1105
|
-
|
|
1106
|
-
for (var i = 0; i < columns.length; ++i) {
|
|
1107
|
-
var td = doc.createElement('td');
|
|
1108
|
-
var selector = renderTableSelector(rows, columns, columns[i]);
|
|
1109
|
-
if (selector) {
|
|
1110
|
-
td.appendChild(selector);
|
|
1111
|
-
}
|
|
1112
|
-
/*
|
|
1113
|
-
// Useful debug: display URI of predicate in column header
|
|
1114
|
-
if (columns[i].predicate.uri) {
|
|
1115
|
-
td.appendChild(document.createTextNode(columns[i].predicate.uri))
|
|
1116
|
-
}
|
|
1117
|
-
*/
|
|
1118
|
-
tr.appendChild(td);
|
|
1119
|
-
}
|
|
1120
|
-
return tr;
|
|
1121
|
-
}
|
|
1122
|
-
function linkTo(uri, linkText, hints) {
|
|
1123
|
-
hints = hints || {};
|
|
1124
|
-
var result = doc.createElement('a');
|
|
1125
|
-
var linkFunction = hints.linkFunction;
|
|
1126
|
-
result.setAttribute('href', uri);
|
|
1127
|
-
result.appendChild(doc.createTextNode(linkText));
|
|
1128
|
-
if (!linkFunction) {
|
|
1129
|
-
result.addEventListener('click', UI.widgets.openHrefInOutlineMode, true);
|
|
1130
|
-
} else {
|
|
1131
|
-
result.addEventListener('click', function (e) {
|
|
1132
|
-
e.preventDefault();
|
|
1133
|
-
e.stopPropagation();
|
|
1134
|
-
var target = utils.getTarget(e);
|
|
1135
|
-
var uri = target.getAttribute('href');
|
|
1136
|
-
if (!uri) debug.log('No href found \n');
|
|
1137
|
-
linkFunction(uri);
|
|
1138
|
-
}, true);
|
|
1139
|
-
}
|
|
1140
|
-
return result;
|
|
1141
|
-
}
|
|
1142
|
-
function linkToObject(obj, hints) {
|
|
1143
|
-
var match = false;
|
|
1144
|
-
if (obj.uri) {
|
|
1145
|
-
match = obj.uri.match(/^mailto:(.*)/);
|
|
1146
|
-
}
|
|
1147
|
-
if (match) {
|
|
1148
|
-
return linkTo(obj.uri, match[1], hints);
|
|
1149
|
-
} else {
|
|
1150
|
-
return linkTo(obj.uri, utils.label(obj), hints);
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
// Render an image
|
|
1155
|
-
|
|
1156
|
-
function renderImage(obj) {
|
|
1157
|
-
var result = doc.createElement('img');
|
|
1158
|
-
result.setAttribute('src', obj.uri);
|
|
1159
|
-
|
|
1160
|
-
// Set the height, so it appears as a thumbnail.
|
|
1161
|
-
result.style.height = '40px';
|
|
1162
|
-
return result;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
// Render an individual RDF object to an HTML object displayed
|
|
1166
|
-
// in a table cell.
|
|
1167
|
-
|
|
1168
|
-
function getHints(column) {
|
|
1169
|
-
if (options && options.hints && column.variable && options.hints[column.variable.toNT()]) {
|
|
1170
|
-
return options.hints[column.variable.toNT()];
|
|
1171
|
-
}
|
|
1172
|
-
return {};
|
|
1173
|
-
}
|
|
1174
|
-
function renderValue(obj, column) {
|
|
1175
|
-
// hint
|
|
1176
|
-
var hints = getHints(column);
|
|
1177
|
-
var cellFormat = hints.cellFormat;
|
|
1178
|
-
if (cellFormat) {
|
|
1179
|
-
switch (cellFormat) {
|
|
1180
|
-
case 'shortDate':
|
|
1181
|
-
return doc.createTextNode(UI.widgets.shortDate(obj.value));
|
|
1182
|
-
// break
|
|
1183
|
-
default:
|
|
1184
|
-
// drop through
|
|
1185
|
-
}
|
|
1186
|
-
} else {
|
|
1187
|
-
if (obj.termType === 'Literal') {
|
|
1188
|
-
if (obj.datatype) {
|
|
1189
|
-
if (XSD_DATE_TYPES[obj.datatype.uri]) {
|
|
1190
|
-
return doc.createTextNode(UI.widgets.shortDate(obj.value));
|
|
1191
|
-
} else if (XSD_NUMBER_TYPES[obj.datatype.uri]) {
|
|
1192
|
-
var span = doc.createElement('span');
|
|
1193
|
-
span.textContent = obj.value;
|
|
1194
|
-
span.setAttribute('style', 'text-align: right');
|
|
1195
|
-
return span;
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
return doc.createTextNode(obj.value);
|
|
1199
|
-
} else if (obj.termType === 'NamedNode' && column.isImageColumn()) {
|
|
1200
|
-
return renderImage(obj);
|
|
1201
|
-
} else if (obj.termType === 'NamedNode' || obj.termType === 'BlankNode') {
|
|
1202
|
-
return linkToObject(obj, hints);
|
|
1203
|
-
} else if (obj.termType === 'Collection') {
|
|
1204
|
-
var _span = doc.createElement('span');
|
|
1205
|
-
_span.appendChild(doc.createTextNode('['));
|
|
1206
|
-
obj.elements.forEach(function (x) {
|
|
1207
|
-
_span.appendChild(renderValue(x, column));
|
|
1208
|
-
_span.appendChild(doc.createTextNode(', '));
|
|
1209
|
-
});
|
|
1210
|
-
_span.removeChild(_span.lastChild);
|
|
1211
|
-
_span.appendChild(doc.createTextNode(']'));
|
|
1212
|
-
return _span;
|
|
1213
|
-
} else {
|
|
1214
|
-
return doc.createTextNode("unknown termtype '" + obj.termType + "'!");
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
// Render a row of the HTML table, from the given row structure.
|
|
1220
|
-
// Note that unlike other functions, this renders into a provided
|
|
1221
|
-
// row (<tr>) element.
|
|
1222
|
-
|
|
1223
|
-
function renderTableRowInto(tr, row, columns, _downstream) {
|
|
1224
|
-
/* Link column, for linking to this subject. */
|
|
1225
|
-
|
|
1226
|
-
var linkTd = doc.createElement('td');
|
|
1227
|
-
if (row._subject && 'uri' in row._subject) {
|
|
1228
|
-
linkTd.appendChild(linkTo(row._subject.uri, "\u2192"));
|
|
1229
|
-
}
|
|
1230
|
-
tr.appendChild(linkTd);
|
|
1231
|
-
|
|
1232
|
-
// Create a <td> for each column (whether the row has data for that
|
|
1233
|
-
// column or not).
|
|
1234
|
-
|
|
1235
|
-
for (var i = 0; i < columns.length; ++i) {
|
|
1236
|
-
var column = columns[i];
|
|
1237
|
-
var td = doc.createElement('td');
|
|
1238
|
-
var orig = void 0;
|
|
1239
|
-
var columnKey = column.getKey();
|
|
1240
|
-
if (columnKey in row.values) {
|
|
1241
|
-
var objects = row.values[columnKey];
|
|
1242
|
-
var different = false;
|
|
1243
|
-
if (row.originalValues && row.originalValues[columnKey]) {
|
|
1244
|
-
if (objects.length !== row.originalValues[columnKey].length) {
|
|
1245
|
-
different = true;
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
for (var j = 0; j < objects.length; ++j) {
|
|
1249
|
-
var obj = objects[j];
|
|
1250
|
-
if (row.originalValues && row.originalValues[columnKey] && row.originalValues[columnKey].length > j) {
|
|
1251
|
-
orig = row.originalValues[columnKey][j];
|
|
1252
|
-
if (obj.toString() !== orig.toString()) {
|
|
1253
|
-
different = true;
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
td.appendChild(renderValue(obj, column));
|
|
1257
|
-
if (j !== objects.length - 1) {
|
|
1258
|
-
td.appendChild(doc.createTextNode(',\n'));
|
|
1259
|
-
}
|
|
1260
|
-
if (different) {
|
|
1261
|
-
td.style.background = '#efe'; // green = new changed
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
tr.appendChild(td);
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
// Save a reference to the HTML row in the row object.
|
|
1269
|
-
|
|
1270
|
-
row._htmlRow = tr;
|
|
1271
|
-
return tr;
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
// Check if a value is already stored in the list of values for
|
|
1275
|
-
// a cell (the query can sometimes find it multiple times)
|
|
1276
|
-
|
|
1277
|
-
function valueInList(value, list) {
|
|
1278
|
-
var key = null;
|
|
1279
|
-
if (value.termType === 'Literal') {
|
|
1280
|
-
key = 'value';
|
|
1281
|
-
} else if (value.termType === 'NamedNode') {
|
|
1282
|
-
key = 'uri';
|
|
1283
|
-
} else {
|
|
1284
|
-
return list.indexOf(value) >= 0;
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
// Check the list and compare keys:
|
|
1288
|
-
|
|
1289
|
-
var i;
|
|
1290
|
-
for (i = 0; i < list.length; ++i) {
|
|
1291
|
-
if (list[i].termType === value.termType && list[i][key] === value[key]) {
|
|
1292
|
-
return true;
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
// Not found?
|
|
1297
|
-
|
|
1298
|
-
return false;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
// Update a row, add new values, and regenerate the HTML element
|
|
1302
|
-
// containing the values.
|
|
1303
|
-
|
|
1304
|
-
function updateRow(row, columns, values) {
|
|
1305
|
-
var key;
|
|
1306
|
-
var needUpdate = false;
|
|
1307
|
-
for (key in values) {
|
|
1308
|
-
var value = values[key];
|
|
1309
|
-
|
|
1310
|
-
// If this key is not already in the row, create a new entry
|
|
1311
|
-
// for it:
|
|
1312
|
-
|
|
1313
|
-
if (!(key in row.values)) {
|
|
1314
|
-
row.values[key] = [];
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
// Possibly add this new value to the list, but don't
|
|
1318
|
-
// add it if we have already added it:
|
|
1319
|
-
|
|
1320
|
-
if (!valueInList(value, row.values[key])) {
|
|
1321
|
-
row.values[key].push(value);
|
|
1322
|
-
needUpdate = true;
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
// Regenerate the HTML row?
|
|
1327
|
-
|
|
1328
|
-
if (needUpdate) {
|
|
1329
|
-
clearElement(row._htmlRow);
|
|
1330
|
-
renderTableRowInto(row._htmlRow, row, columns);
|
|
1331
|
-
}
|
|
1332
|
-
applyColumnFiltersToRow(row, columns); // Hide immediately if nec
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
// Get a unique ID for the given subject. This is normally the
|
|
1336
|
-
// URI; if the subject has no URI, a unique ID is assigned.
|
|
1337
|
-
|
|
1338
|
-
function getSubjectId(subject) {
|
|
1339
|
-
if ('uri' in subject) {
|
|
1340
|
-
return subject.uri;
|
|
1341
|
-
} else if ('_subject_id' in subject) {
|
|
1342
|
-
return subject._subject_id;
|
|
1343
|
-
} else {
|
|
1344
|
-
var result = '' + subjectIdCounter;
|
|
1345
|
-
subject._subject_id = result;
|
|
1346
|
-
++subjectIdCounter;
|
|
1347
|
-
return result;
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
// Run a query and populate the table.
|
|
1352
|
-
// Populates also an array of logical rows. This will be empty when the function
|
|
1353
|
-
// first returns (as the query is performed in the background)
|
|
1354
|
-
|
|
1355
|
-
function runQuery(query, rows, columns, table) {
|
|
1356
|
-
query.running = true;
|
|
1357
|
-
var startTime = Date.now();
|
|
1358
|
-
var progressMessage = doc.createElement('tr');
|
|
1359
|
-
table.appendChild(progressMessage);
|
|
1360
|
-
progressMessage.textContent = 'Loading ...';
|
|
1361
|
-
for (var i = 0; i < rows.length; i++) {
|
|
1362
|
-
rows[i].original = true;
|
|
1363
|
-
if (!rows[i].originalValues) {
|
|
1364
|
-
// remember first set
|
|
1365
|
-
rows[i].originalValues = rows[i].values;
|
|
1366
|
-
}
|
|
1367
|
-
rows[i].values = {};
|
|
1368
|
-
// oldStyle = rows[i]._htmlRow.getAttribute('style') || ''
|
|
1369
|
-
// rows[i]._htmlRow.style.background = '#ffe'; //setAttribute('style', ' background-color: #ffe;')// yellow
|
|
1370
|
-
}
|
|
1371
|
-
var onResult = function onResult(values) {
|
|
1372
|
-
if (!query.running) {
|
|
1373
|
-
return;
|
|
1374
|
-
}
|
|
1375
|
-
progressMessage.textContent += '.'; // give a progress bar
|
|
1376
|
-
|
|
1377
|
-
var row = null;
|
|
1378
|
-
var rowKey = null;
|
|
1379
|
-
var rowKeyId;
|
|
1380
|
-
|
|
1381
|
-
// If the query has a row key, use it to look up the row.
|
|
1382
|
-
|
|
1383
|
-
if (keyVariable in values) {
|
|
1384
|
-
rowKey = values[keyVariable];
|
|
1385
|
-
rowKeyId = getSubjectId(rowKey);
|
|
1386
|
-
|
|
1387
|
-
// Do we have a row for this already?
|
|
1388
|
-
// If so, reuse it; otherwise, we must create a new row.
|
|
1389
|
-
|
|
1390
|
-
if (rowKeyId in rowsLookup) {
|
|
1391
|
-
row = rowsLookup[rowKeyId];
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
|
|
1395
|
-
// Create a new row?
|
|
1396
|
-
|
|
1397
|
-
if (!row) {
|
|
1398
|
-
var tr = doc.createElement('tr');
|
|
1399
|
-
table.appendChild(tr);
|
|
1400
|
-
row = {
|
|
1401
|
-
_htmlRow: tr,
|
|
1402
|
-
_subject: rowKey,
|
|
1403
|
-
values: {}
|
|
1404
|
-
};
|
|
1405
|
-
rows.push(row);
|
|
1406
|
-
if (rowKey) {
|
|
1407
|
-
rowsLookup[rowKeyId] = row;
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
// Add the new values to this row.
|
|
1412
|
-
delete row.original; // This is included in the new data
|
|
1413
|
-
updateRow(row, columns, values);
|
|
1414
|
-
};
|
|
1415
|
-
var onDone = function onDone() {
|
|
1416
|
-
if (progressMessage && progressMessage.parentNode && progressMessage.parentNode.removeChild) {
|
|
1417
|
-
progressMessage.parentNode.removeChild(progressMessage);
|
|
1418
|
-
progressMessage = null;
|
|
1419
|
-
}
|
|
1420
|
-
var elapsedTimeMS = Date.now() - startTime;
|
|
1421
|
-
debug.log('Query done: ' + rows.length + ' rows, ' + elapsedTimeMS + 'ms');
|
|
1422
|
-
// Delete rows which were from old values not new
|
|
1423
|
-
for (var _i4 = rows.length - 1; _i4 >= 0; _i4--) {
|
|
1424
|
-
// backwards
|
|
1425
|
-
if (rows[_i4].original) {
|
|
1426
|
-
debug.log(' deleting row ' + rows[_i4]._subject);
|
|
1427
|
-
var tr = rows[_i4]._htmlRow;
|
|
1428
|
-
tr.parentNode.removeChild(tr);
|
|
1429
|
-
delete rowsLookup[getSubjectId(rows[_i4]._subject)];
|
|
1430
|
-
rows.splice(_i4, 1);
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
if (options.sortBy) {
|
|
1434
|
-
// @@ for each column check needs sorting
|
|
1435
|
-
var column = getColumnForVariable(columns, options.sortBy);
|
|
1436
|
-
literalSort(rows, column, options.sortReverse);
|
|
1437
|
-
}
|
|
1438
|
-
if (options.onDone) options.onDone(resultDiv); // return div makes testing easier
|
|
1439
|
-
};
|
|
1440
|
-
kb.query(query, onResult, undefined, onDone);
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
// Given the formula object which is the query pattern,
|
|
1444
|
-
// deduce from where the variable occurs constraints on
|
|
1445
|
-
// what values it can take.
|
|
1446
|
-
|
|
1447
|
-
function inferColumnsFromFormula(columns, formula) {
|
|
1448
|
-
UI.log.debug('>> processing formula');
|
|
1449
|
-
for (var i = 0; i < formula.statements.length; ++i) {
|
|
1450
|
-
var statement = formula.statements[i];
|
|
1451
|
-
// UI.log.debug("processing statement " + i)
|
|
1452
|
-
|
|
1453
|
-
// Does it match this?:
|
|
1454
|
-
// <something> <predicate> ?var
|
|
1455
|
-
// If so, we can use the predicate as the predicate for the
|
|
1456
|
-
// column used for the specified variable.
|
|
1457
|
-
|
|
1458
|
-
if (statement.predicate.termType === 'NamedNode' && statement.object.termType === 'Variable') {
|
|
1459
|
-
var variable = statement.object.toString();
|
|
1460
|
-
if (variable in columns) {
|
|
1461
|
-
var column = columns[variable];
|
|
1462
|
-
column.setPredicate(statement.predicate, false, statement.subject);
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
1465
|
-
if (statement.predicate.termType === 'NamedNode' && statement.subject.termType === 'Variable') {
|
|
1466
|
-
var _variable = statement.subject.toString();
|
|
1467
|
-
if (_variable in columns) {
|
|
1468
|
-
var _column = columns[_variable];
|
|
1469
|
-
_column.setPredicate(statement.predicate, true, statement.object);
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
// Apply to OPTIONAL formulas:
|
|
1475
|
-
|
|
1476
|
-
for (var _i5 = 0; _i5 < formula.optional.length; ++_i5) {
|
|
1477
|
-
UI.log.debug('recurse to optional subformula ' + _i5);
|
|
1478
|
-
inferColumnsFromFormula(columns, formula.optional[_i5]);
|
|
1479
|
-
}
|
|
1480
|
-
UI.log.debug('<< finished processing formula');
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
// Generate a list of column structures and infer details about the
|
|
1484
|
-
// predicates based on the contents of the query
|
|
1485
|
-
|
|
1486
|
-
function inferColumns(query) {
|
|
1487
|
-
// Generate the columns list:
|
|
1488
|
-
|
|
1489
|
-
var result = [];
|
|
1490
|
-
var columns = {};
|
|
1491
|
-
for (var i = 0; i < query.vars.length; ++i) {
|
|
1492
|
-
var column = new Column();
|
|
1493
|
-
var queryVar = query.vars[i];
|
|
1494
|
-
UI.log.debug('column ' + i + ' : ' + queryVar);
|
|
1495
|
-
column.setVariable(queryVar);
|
|
1496
|
-
columns[queryVar] = column;
|
|
1497
|
-
result.push(column);
|
|
1498
|
-
}
|
|
1499
|
-
inferColumnsFromFormula(columns, query.pat);
|
|
1500
|
-
return result;
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
// Generate a table from a query.
|
|
1504
|
-
|
|
1505
|
-
function renderTableForQuery(query, type) {
|
|
1506
|
-
// infer columns from query, to allow generic queries
|
|
1507
|
-
var columns;
|
|
1508
|
-
if (!givenQuery) {
|
|
1509
|
-
columns = type.getColumns();
|
|
1510
|
-
} else {
|
|
1511
|
-
columns = inferColumns(query);
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
// Start with an empty list of rows; this will be populated
|
|
1515
|
-
// by the query.
|
|
1516
|
-
|
|
1517
|
-
var rows = [];
|
|
1518
|
-
|
|
1519
|
-
// Create table element and header.
|
|
1520
|
-
|
|
1521
|
-
var table = doc.createElement('table');
|
|
1522
|
-
table.appendChild(renderTableHeader(columns, type));
|
|
1523
|
-
table.appendChild(renderTableSelectors(rows, columns));
|
|
1524
|
-
|
|
1525
|
-
// Run query. Note that this is perform asynchronously; the
|
|
1526
|
-
// query runs in the background and this call does not block.
|
|
1527
|
-
|
|
1528
|
-
table.logicalRows = rows; // Save for refresh
|
|
1529
|
-
table.columns = columns;
|
|
1530
|
-
table.query = query;
|
|
1531
|
-
runQuery(query, rows, columns, table);
|
|
1532
|
-
return table;
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
// Find the most common type of row
|
|
1536
|
-
|
|
1537
|
-
function getMostCommonType(types) {
|
|
1538
|
-
var bestCount = -1;
|
|
1539
|
-
var best = null;
|
|
1540
|
-
var typeUri;
|
|
1541
|
-
for (typeUri in types) {
|
|
1542
|
-
var type = types[typeUri];
|
|
1543
|
-
if (type.useCount > bestCount) {
|
|
1544
|
-
best = type;
|
|
1545
|
-
bestCount = type.useCount;
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
return best;
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
// Filter list of columns to only those columns used in the
|
|
1552
|
-
// specified rows.
|
|
1553
|
-
/*
|
|
1554
|
-
function filterColumns (columns, rows) {
|
|
1555
|
-
var filteredColumns = {}
|
|
1556
|
-
// Copy columns from "columns" -> "filteredColumns", but only
|
|
1557
|
-
// those columns that are used in the list of rows specified.
|
|
1558
|
-
for (let columnUri in columns) {
|
|
1559
|
-
for (let i = 0; i < rows.length; ++i) {
|
|
1560
|
-
if (columnUri in rows[i]) {
|
|
1561
|
-
filteredColumns[columnUri] = columns[columnUri]
|
|
1562
|
-
break
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
return filteredColumns
|
|
1567
|
-
}
|
|
1568
|
-
*/
|
|
1569
|
-
}
|
|
1570
|
-
// ///////////////////////////////////////////////////////////////////
|
|
1571
|
-
|
|
1572
|
-
// ENDS
|
|
1573
|
-
//# sourceMappingURL=table.js.map
|