ixbrl-viewer 1.4.1__py3-none-any.whl → 1.4.86__py3-none-any.whl

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.
Files changed (190) hide show
  1. iXBRLViewerPlugin/__init__.py +231 -127
  2. iXBRLViewerPlugin/_version.py +33 -3
  3. iXBRLViewerPlugin/constants.py +96 -2
  4. iXBRLViewerPlugin/featureConfig.py +8 -1
  5. iXBRLViewerPlugin/iXBRLViewer.py +356 -214
  6. iXBRLViewerPlugin/plugin.py +12 -0
  7. iXBRLViewerPlugin/ui.py +81 -50
  8. iXBRLViewerPlugin/viewer/dist/ixbrlviewer.js +1 -1
  9. iXBRLViewerPlugin/viewer/dist/ixbrlviewer.js.LICENSE.txt +12 -5
  10. iXBRLViewerPlugin/viewer/i18next-parser.config.js +1 -1
  11. iXBRLViewerPlugin/viewer/src/data/utr.json +1244 -0
  12. iXBRLViewerPlugin/viewer/src/html/fact-details.html +69 -38
  13. iXBRLViewerPlugin/viewer/src/html/footer-logo.html +4 -0
  14. iXBRLViewerPlugin/viewer/src/html/footnote-details.html +2 -2
  15. iXBRLViewerPlugin/viewer/src/html/inspector.html +352 -197
  16. iXBRLViewerPlugin/viewer/src/i18n/cy/balancetypes.json +1 -0
  17. iXBRLViewerPlugin/viewer/src/i18n/cy/currencies.json +13 -0
  18. iXBRLViewerPlugin/viewer/src/i18n/cy/datatypes.json +9 -0
  19. iXBRLViewerPlugin/viewer/src/i18n/cy/labelroles.json +24 -0
  20. iXBRLViewerPlugin/viewer/src/i18n/cy/referenceparts.json +10 -0
  21. iXBRLViewerPlugin/viewer/src/i18n/cy/scale.json +16 -0
  22. iXBRLViewerPlugin/viewer/src/i18n/cy/tooltips.json +17 -0
  23. iXBRLViewerPlugin/viewer/src/i18n/cy/translation.json +179 -0
  24. iXBRLViewerPlugin/viewer/src/i18n/da/balancetypes.json +4 -0
  25. iXBRLViewerPlugin/viewer/src/i18n/da/currencies.json +13 -0
  26. iXBRLViewerPlugin/viewer/src/i18n/da/datatypes.json +9 -0
  27. iXBRLViewerPlugin/viewer/src/i18n/da/labelroles.json +24 -0
  28. iXBRLViewerPlugin/viewer/src/i18n/da/referenceparts.json +10 -0
  29. iXBRLViewerPlugin/viewer/src/i18n/da/scale.json +15 -0
  30. iXBRLViewerPlugin/viewer/src/i18n/da/tooltips.json +17 -0
  31. iXBRLViewerPlugin/viewer/src/i18n/da/translation.json +179 -0
  32. iXBRLViewerPlugin/viewer/src/i18n/de/balancetypes.json +4 -0
  33. iXBRLViewerPlugin/viewer/src/i18n/de/currencies.json +13 -0
  34. iXBRLViewerPlugin/viewer/src/i18n/de/datatypes.json +9 -0
  35. iXBRLViewerPlugin/viewer/src/i18n/de/labelroles.json +24 -0
  36. iXBRLViewerPlugin/viewer/src/i18n/de/referenceparts.json +10 -0
  37. iXBRLViewerPlugin/viewer/src/i18n/de/scale.json +15 -0
  38. iXBRLViewerPlugin/viewer/src/i18n/de/tooltips.json +17 -0
  39. iXBRLViewerPlugin/viewer/src/i18n/de/translation.json +179 -0
  40. iXBRLViewerPlugin/viewer/src/i18n/en/balancetypes.json +4 -0
  41. iXBRLViewerPlugin/viewer/src/i18n/en/datatypes.json +10 -0
  42. iXBRLViewerPlugin/viewer/src/i18n/en/labelroles.json +4 -0
  43. iXBRLViewerPlugin/viewer/src/i18n/en/scale.json +16 -0
  44. iXBRLViewerPlugin/viewer/src/i18n/en/tooltips.json +17 -0
  45. iXBRLViewerPlugin/viewer/src/i18n/en/translation.json +73 -23
  46. iXBRLViewerPlugin/viewer/src/i18n/es/balancetypes.json +4 -0
  47. iXBRLViewerPlugin/viewer/src/i18n/es/datatypes.json +10 -0
  48. iXBRLViewerPlugin/viewer/src/i18n/es/labelroles.json +24 -0
  49. iXBRLViewerPlugin/viewer/src/i18n/es/scale.json +16 -0
  50. iXBRLViewerPlugin/viewer/src/i18n/es/tooltips.json +17 -0
  51. iXBRLViewerPlugin/viewer/src/i18n/es/translation.json +87 -37
  52. iXBRLViewerPlugin/viewer/src/i18n/fr/balancetypes.json +4 -0
  53. iXBRLViewerPlugin/viewer/src/i18n/fr/currencies.json +13 -0
  54. iXBRLViewerPlugin/viewer/src/i18n/fr/datatypes.json +9 -0
  55. iXBRLViewerPlugin/viewer/src/i18n/fr/labelroles.json +24 -0
  56. iXBRLViewerPlugin/viewer/src/i18n/fr/referenceparts.json +10 -0
  57. iXBRLViewerPlugin/viewer/src/i18n/fr/scale.json +15 -0
  58. iXBRLViewerPlugin/viewer/src/i18n/fr/tooltips.json +17 -0
  59. iXBRLViewerPlugin/viewer/src/i18n/fr/translation.json +179 -0
  60. iXBRLViewerPlugin/viewer/src/i18n/nl/balancetypes.json +4 -0
  61. iXBRLViewerPlugin/viewer/src/i18n/nl/currencies.json +13 -0
  62. iXBRLViewerPlugin/viewer/src/i18n/nl/datatypes.json +9 -0
  63. iXBRLViewerPlugin/viewer/src/i18n/nl/labelroles.json +24 -0
  64. iXBRLViewerPlugin/viewer/src/i18n/nl/referenceparts.json +10 -0
  65. iXBRLViewerPlugin/viewer/src/i18n/nl/scale.json +15 -0
  66. iXBRLViewerPlugin/viewer/src/i18n/nl/tooltips.json +17 -0
  67. iXBRLViewerPlugin/viewer/src/i18n/nl/translation.json +179 -0
  68. iXBRLViewerPlugin/viewer/src/i18n/uk/balancetypes.json +4 -0
  69. iXBRLViewerPlugin/viewer/src/i18n/uk/currencies.json +13 -0
  70. iXBRLViewerPlugin/viewer/src/i18n/uk/datatypes.json +9 -0
  71. iXBRLViewerPlugin/viewer/src/i18n/uk/labelroles.json +24 -0
  72. iXBRLViewerPlugin/viewer/src/i18n/uk/referenceparts.json +10 -0
  73. iXBRLViewerPlugin/viewer/src/i18n/uk/scale.json +15 -0
  74. iXBRLViewerPlugin/viewer/src/i18n/uk/tooltips.json +17 -0
  75. iXBRLViewerPlugin/viewer/src/i18n/uk/translation.json +179 -0
  76. iXBRLViewerPlugin/viewer/src/icons/calculator.svg +13 -0
  77. iXBRLViewerPlugin/viewer/src/icons/circle-cross.svg +11 -0
  78. iXBRLViewerPlugin/viewer/src/icons/circle-tick.svg +11 -0
  79. iXBRLViewerPlugin/viewer/src/icons/dark-mode.svg +4 -0
  80. iXBRLViewerPlugin/viewer/src/icons/dimension.svg +1 -5
  81. iXBRLViewerPlugin/viewer/src/icons/member.svg +2 -5
  82. iXBRLViewerPlugin/viewer/src/icons/multi-tag.svg +10 -0
  83. iXBRLViewerPlugin/viewer/src/img/arelle-dark.svg +179 -0
  84. iXBRLViewerPlugin/viewer/src/img/inline-viewer-dark.svg +59 -0
  85. iXBRLViewerPlugin/viewer/src/js/accordian.js +5 -4
  86. iXBRLViewerPlugin/viewer/src/js/aspect.js +29 -10
  87. iXBRLViewerPlugin/viewer/src/js/aspect.test.js +40 -31
  88. iXBRLViewerPlugin/viewer/src/js/balance.js +14 -0
  89. iXBRLViewerPlugin/viewer/src/js/calculation.js +213 -0
  90. iXBRLViewerPlugin/viewer/src/js/calculation.test.js +306 -0
  91. iXBRLViewerPlugin/viewer/src/js/calculationInspector.js +187 -0
  92. iXBRLViewerPlugin/viewer/src/js/chart.js +26 -24
  93. iXBRLViewerPlugin/viewer/src/js/chart.test.js +10 -9
  94. iXBRLViewerPlugin/viewer/src/js/concept.js +37 -4
  95. iXBRLViewerPlugin/viewer/src/js/concept.test.js +30 -6
  96. iXBRLViewerPlugin/viewer/src/js/datatype.js +20 -0
  97. iXBRLViewerPlugin/viewer/src/js/datatype.test.js +62 -0
  98. iXBRLViewerPlugin/viewer/src/js/dialog.js +6 -4
  99. iXBRLViewerPlugin/viewer/src/js/docOrderIndex.js +7 -7
  100. iXBRLViewerPlugin/viewer/src/js/fact.js +156 -59
  101. iXBRLViewerPlugin/viewer/src/js/fact.test.js +160 -29
  102. iXBRLViewerPlugin/viewer/src/js/factset.js +64 -15
  103. iXBRLViewerPlugin/viewer/src/js/factset.test.js +102 -31
  104. iXBRLViewerPlugin/viewer/src/js/footnote.js +8 -2
  105. iXBRLViewerPlugin/viewer/src/js/index.js +11 -3
  106. iXBRLViewerPlugin/viewer/src/js/inspector.js +747 -221
  107. iXBRLViewerPlugin/viewer/src/js/inspector.test.js +143 -25
  108. iXBRLViewerPlugin/viewer/src/js/interval.js +70 -0
  109. iXBRLViewerPlugin/viewer/src/js/interval.test.js +153 -0
  110. iXBRLViewerPlugin/viewer/src/js/ixbrlviewer.js +391 -262
  111. iXBRLViewerPlugin/viewer/src/js/ixbrlviewer.test.js +134 -20
  112. iXBRLViewerPlugin/viewer/src/js/ixnode.js +1 -1
  113. iXBRLViewerPlugin/viewer/src/js/menu.js +25 -7
  114. iXBRLViewerPlugin/viewer/src/js/number-matcher.js +7 -3
  115. iXBRLViewerPlugin/viewer/src/js/number-matcher.test.js +4 -0
  116. iXBRLViewerPlugin/viewer/src/js/outline.js +34 -13
  117. iXBRLViewerPlugin/viewer/src/js/outline.test.js +97 -91
  118. iXBRLViewerPlugin/viewer/src/js/period.js +0 -1
  119. iXBRLViewerPlugin/viewer/src/js/report.js +260 -351
  120. iXBRLViewerPlugin/viewer/src/js/report.test.js +95 -27
  121. iXBRLViewerPlugin/viewer/src/js/reportset.js +264 -0
  122. iXBRLViewerPlugin/viewer/src/js/reportset.test.js +357 -0
  123. iXBRLViewerPlugin/viewer/src/js/search.js +72 -38
  124. iXBRLViewerPlugin/viewer/src/js/search.test.js +184 -84
  125. iXBRLViewerPlugin/viewer/src/js/summary.js +34 -8
  126. iXBRLViewerPlugin/viewer/src/js/summary.test.js +69 -25
  127. iXBRLViewerPlugin/viewer/src/js/tableExport.js +9 -9
  128. iXBRLViewerPlugin/viewer/src/js/taxonomynamer.js +34 -0
  129. iXBRLViewerPlugin/viewer/src/js/taxonomynamer.test.js +32 -0
  130. iXBRLViewerPlugin/viewer/src/js/test-utils.js +46 -0
  131. iXBRLViewerPlugin/viewer/src/js/theme.js +50 -0
  132. iXBRLViewerPlugin/viewer/src/js/unit.js +90 -32
  133. iXBRLViewerPlugin/viewer/src/js/unit.test.js +62 -25
  134. iXBRLViewerPlugin/viewer/src/js/util.js +94 -0
  135. iXBRLViewerPlugin/viewer/src/js/util.test.js +33 -1
  136. iXBRLViewerPlugin/viewer/src/js/utr.js +27 -0
  137. iXBRLViewerPlugin/viewer/src/js/viewer.js +205 -181
  138. iXBRLViewerPlugin/viewer/src/js/viewerOptions.js +0 -2
  139. iXBRLViewerPlugin/viewer/src/less/accordian.less +10 -6
  140. iXBRLViewerPlugin/viewer/src/less/block-list.less +16 -5
  141. iXBRLViewerPlugin/viewer/src/less/calculation-inspector.less +83 -0
  142. iXBRLViewerPlugin/viewer/src/less/chart.less +8 -5
  143. iXBRLViewerPlugin/viewer/src/less/colours-dark-mode.less +40 -0
  144. iXBRLViewerPlugin/viewer/src/less/colours.less +32 -20
  145. iXBRLViewerPlugin/viewer/src/less/common.less +3 -3
  146. iXBRLViewerPlugin/viewer/src/less/components.less +6 -4
  147. iXBRLViewerPlugin/viewer/src/less/core.less +2 -0
  148. iXBRLViewerPlugin/viewer/src/less/dialog.less +21 -14
  149. iXBRLViewerPlugin/viewer/src/less/form-controls.less +33 -11
  150. iXBRLViewerPlugin/viewer/src/less/inspector.less +1045 -726
  151. iXBRLViewerPlugin/viewer/src/less/loader.less +2 -2
  152. iXBRLViewerPlugin/viewer/src/less/menu.less +33 -15
  153. iXBRLViewerPlugin/viewer/src/less/summary.less +16 -6
  154. iXBRLViewerPlugin/viewer/src/less/tabs.less +9 -9
  155. iXBRLViewerPlugin/viewer/src/less/text-block-viewer.less +2 -0
  156. iXBRLViewerPlugin/viewer/src/less/text-mixins.less +2 -1
  157. iXBRLViewerPlugin/viewer/src/less/validation-report.less +2 -3
  158. iXBRLViewerPlugin/viewer/src/less/viewer.less +105 -74
  159. iXBRLViewerPlugin/viewer/webpack.common.js +19 -9
  160. iXBRLViewerPlugin/xhtmlserialize.py +59 -45
  161. {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/METADATA +181 -50
  162. ixbrl_viewer-1.4.86.dist-info/RECORD +217 -0
  163. {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/WHEEL +1 -1
  164. ixbrl_viewer-1.4.1.dist-info/LICENSE → ixbrl_viewer-1.4.86.dist-info/licenses/LICENSE.md +8 -14
  165. {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/top_level.txt +0 -1
  166. iXBRLViewerPlugin/viewer/src/js/calculations.js +0 -111
  167. iXBRLViewerPlugin/viewer/src/js/interact.min.js +0 -6
  168. ixbrl_viewer-1.4.1.dist-info/RECORD +0 -155
  169. tests/__init__.py +0 -0
  170. tests/puppeteer/framework/core_elements.js +0 -117
  171. tests/puppeteer/framework/page_objects/doc_frame.js +0 -105
  172. tests/puppeteer/framework/page_objects/fact_details_panel.js +0 -80
  173. tests/puppeteer/framework/page_objects/search_panel.js +0 -76
  174. tests/puppeteer/framework/page_objects/toolbar.js +0 -18
  175. tests/puppeteer/framework/utils.js +0 -3
  176. tests/puppeteer/framework/viewer_page.js +0 -103
  177. tests/puppeteer/puppeteer_test_run_via_intellij.jpg +0 -0
  178. tests/puppeteer/test_filings/filing_documents_smoke_test.zip +0 -0
  179. tests/puppeteer/test_filings/highlights.zip +0 -0
  180. tests/puppeteer/tests/fact_properties.test.js +0 -78
  181. tests/puppeteer/tests/highlight.test.js +0 -186
  182. tests/puppeteer/tests/search.test.js +0 -86
  183. tests/puppeteer/tools/generate.sh +0 -15
  184. tests/unit_tests/__init__.py +0 -0
  185. tests/unit_tests/iXBRLViewerPlugin/__init__.py +0 -0
  186. tests/unit_tests/iXBRLViewerPlugin/mock_arelle.py +0 -39
  187. tests/unit_tests/iXBRLViewerPlugin/test_iXBRLViewer.py +0 -641
  188. tests/unit_tests/iXBRLViewerPlugin/test_xhtmlserialize.py +0 -310
  189. {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/entry_points.txt +0 -0
  190. {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info/licenses}/NOTICE +0 -0
@@ -1,11 +1,10 @@
1
1
  // See COPYRIGHT.md for copyright information
2
2
 
3
3
  import $ from 'jquery'
4
- import { numberMatchSearch, fullDateMatch } from './number-matcher.js'
4
+ import { numberMatchSearch } from './number-matcher.js'
5
5
  import { TableExport } from './tableExport.js'
6
- import { escapeRegex } from './util.js'
7
6
  import { IXNode } from './ixnode.js';
8
- import { setDefault, runGenerator } from './util.js';
7
+ import { getIXHiddenLinkStyle, runGenerator, viewerUniqueId, HIGHLIGHT_COLORS } from './util.js';
9
8
  import { DocOrderIndex } from './docOrderIndex.js';
10
9
  import { MessageBox } from './messagebox.js';
11
10
 
@@ -22,9 +21,9 @@ function localName(e) {
22
21
 
23
22
 
24
23
  export class Viewer {
25
- constructor(iv, iframes, report) {
24
+ constructor(iv, iframes, reportSet) {
26
25
  this._iv = iv;
27
- this._report = report;
26
+ this._reportSet = reportSet;
28
27
  this._iframes = iframes;
29
28
  this._contents = iframes.contents();
30
29
  this.onSelect = $.Callbacks();
@@ -65,9 +64,12 @@ export class Viewer {
65
64
 
66
65
  viewer._iframes.each(function (docIndex) {
67
66
  $(this).data("selected", docIndex == viewer._currentDocumentIndex);
68
- viewer._preProcessiXBRL($(this).contents().find("body").get(0), docIndex);
67
+ const reportIndex = $(this).data("report-index");
68
+ viewer._preProcessiXBRL($(this).contents().find("body").get(0), reportIndex, docIndex, false);
69
69
  });
70
70
 
71
+ viewer._setContinuationMaps();
72
+
71
73
  /* Call plugin promise for each document in turn */
72
74
  (async function () {
73
75
  for (const [docIndex, iframe] of viewer._iframes.toArray().entries()) {
@@ -91,7 +93,7 @@ export class Viewer {
91
93
  })()
92
94
  .then(() => viewer._iv.setProgress("Preparing document") )
93
95
  .then(() => {
94
- this._report.setIXNodeMap(this._ixNodeMap);
96
+ this._reportSet.setIXNodeMap(this._ixNodeMap);
95
97
  this._applyStyles();
96
98
  this._bindHandlers();
97
99
  this.scale = 1;
@@ -105,14 +107,14 @@ export class Viewer {
105
107
  }
106
108
 
107
109
  _addDocumentSetTabs() {
108
- if (this._report.isDocumentSet()) {
110
+ if (this._reportSet.isMultiDocumentViewer()) {
109
111
  $('#ixv .ixds-tabs').show();
110
- for (const [i, doc] of this._report.documentSetFiles().entries()) {
111
- $('<div class="tab">')
112
- .text(doc)
113
- .prop('title', doc)
112
+ for (const [i, doc] of this._reportSet.reportFiles().entries()) {
113
+ $('<button class="tab"></button>')
114
+ .text(doc.file)
115
+ .prop('title', doc.file)
114
116
  .data('ix-doc-id', i)
115
- .click(() => this.selectDocument(i))
117
+ .on("click", () => this.selectDocument(i))
116
118
  .appendTo($('#ixv #viewer-pane .ixds-tabs .tab-area'));
117
119
  }
118
120
  $('#ixv #viewer-pane .ixds-tabs .tab-area .tab').eq(0).addClass("active");
@@ -123,16 +125,21 @@ export class Viewer {
123
125
  // display: block, a div is used, otherwise a span. Returns the wrapper node
124
126
  // as a jQuery node
125
127
  _wrapNode(n) {
126
- var wrapper = "<span>";
127
- const nn = n.getElementsByTagName("*");
128
- for (var i = 0; i < nn.length; i++) {
129
- if (getComputedStyle(nn[i]).getPropertyValue('display') === "block") {
130
- wrapper = '<div>';
131
- break;
128
+ let wrapper = "<span>";
129
+ if (getComputedStyle(n).getPropertyValue("display") === "block") {
130
+ wrapper = '<div>';
131
+ }
132
+ else {
133
+ const nn = n.getElementsByTagName("*");
134
+ for (var i = 0; i < nn.length; i++) {
135
+ if (getComputedStyle(nn[i]).getPropertyValue('display') === "block") {
136
+ wrapper = '<div>';
137
+ break;
138
+ }
132
139
  }
133
140
  }
134
141
  $(n).wrap(wrapper);
135
- return $(n).parent();
142
+ return n.parentNode;
136
143
  }
137
144
 
138
145
 
@@ -230,9 +237,9 @@ export class Viewer {
230
237
  const url = $(n).attr("href");
231
238
  if (url !== undefined) {
232
239
  const [file, fragment] = url.split('#', 2);
233
- const docIndex = this._report.documentSetFiles().indexOf(file);
240
+ const docIndex = this._reportSet.reportFiles().indexOf(file);
234
241
  if (!url.includes('/') && docIndex != -1) {
235
- $(n).click((e) => {
242
+ $(n).on("click", (e) => {
236
243
  this._showDocumentAndElement(docIndex, fragment);
237
244
  e.preventDefault();
238
245
  });
@@ -246,44 +253,52 @@ export class Viewer {
246
253
  }
247
254
  }
248
255
 
249
- _findOrCreateWrapperNode(domNode) {
256
+ _findOrCreateWrapperNode(domNode, inHidden) {
250
257
  const v = this;
258
+
259
+ if (inHidden) {
260
+ return $(domNode).addClass("ixbrl-element-hidden");
261
+ }
262
+
251
263
  /* Is the element the only significant content within a <td> or <th> ? If
252
- * so, use that as the wrapper element. */
253
- var nodes = $(domNode).closest("td,th").eq(0);
264
+ * so, use that as the wrapper element.
265
+ * Check for 'display: table-cell' to avoid using hidden cells */
266
+ const tableNode = domNode.closest("td,th");
267
+ const nodes = [];
254
268
  const innerText = $(domNode).text();
255
- if (nodes.length == 1 && innerText.length > 0) {
269
+ if (tableNode !== null && getComputedStyle(tableNode).display === 'table-cell' && innerText.length > 0) {
256
270
  // Use indexOf rather than a single regex because innerText may
257
271
  // be too long for the regex engine
258
- const outerText = $(nodes).text();
272
+ const outerText = $(tableNode).text();
259
273
  const start = outerText.indexOf(innerText);
260
274
  const wrapper = outerText.substring(0, start) + outerText.substring(start + innerText.length);
261
- if (/[0-9A-Za-z]/.test(wrapper)) {
262
- nodes = $();
275
+ if (!/[0-9A-Za-z]/.test(wrapper)) {
276
+ nodes.push(tableNode)
263
277
  }
264
278
  }
265
- /* Otherwise, insert a <span> as wrapper */
279
+ /* Otherwise, insert a <span> or <div> as wrapper */
266
280
  if (nodes.length == 0) {
267
- nodes = this._wrapNode(domNode);
268
- // Create a node set of current node and all absolutely positioned
269
- // descendants.
270
- nodes = nodes.find("*").addBack().filter(function (n, e) {
271
- return (this == nodes[0] || (getComputedStyle(this).getPropertyValue('position') === "absolute"));
272
- });
281
+ nodes.push(this._wrapNode(domNode));
273
282
  }
274
- nodes.each(function (i) {
283
+ // Create a list of the wrapper node, and all absolutely positioned descendants.
284
+ for (const e of nodes[0].querySelectorAll("*")) {
285
+ if (getComputedStyle(e).getPropertyValue('position') === "absolute") {
286
+ nodes.push(e);
287
+ }
288
+ }
289
+ for (const [i, n] of nodes.entries()) {
275
290
  // getBoundingClientRect blocks on layout, so only do it if we've actually got absolute nodes
276
291
  if (nodes.length > 1) {
277
- this.classList.add("ixbrl-contains-absolute");
292
+ n.classList.add("ixbrl-contains-absolute");
278
293
  }
279
294
  if (i == 0) {
280
- this.classList.add("ixbrl-element");
295
+ n.classList.add("ixbrl-element");
281
296
  }
282
297
  else {
283
- this.classList.add("ixbrl-sub-element");
298
+ n.classList.add("ixbrl-sub-element");
284
299
  }
285
- });
286
- return nodes;
300
+ }
301
+ return $(nodes);
287
302
  }
288
303
 
289
304
 
@@ -299,18 +314,21 @@ export class Viewer {
299
314
  const nextContinuationMap = {};
300
315
  // map of items in default target document to all their continuations
301
316
  const itemContinuationMap = {};
302
- this._iframes.contents().find("body *").each(function () {
303
- const name = localName(this.nodeName).toUpperCase();
304
- if (['NONNUMERIC', 'NONFRACTION', 'FOOTNOTE', 'CONTINUATION'].includes(name)) {
305
- const nodeId = this.getAttribute('id');
306
- const continuedAtId = this.getAttribute("continuedAt");
307
- if (continuedAtId !== null) {
308
- nextContinuationMap[nodeId] = continuedAtId;
309
- }
310
- if (name != 'CONTINUATION' && !this.hasAttribute('target')) {
311
- itemContinuationMap[nodeId] = [];
317
+ this._iframes.each((n, iframe) => {
318
+ const reportIndex = $(iframe).data("report-index");
319
+ $(iframe).contents().find("body *").each((m, node) => {
320
+ const name = localName(node.nodeName).toUpperCase();
321
+ if (['NONNUMERIC', 'NONFRACTION', 'FOOTNOTE', 'CONTINUATION'].includes(name) && node.hasAttribute('id')) {
322
+ const nodeId = viewerUniqueId(reportIndex, node.getAttribute('id'));
323
+ const continuedAtId = viewerUniqueId(reportIndex, node.getAttribute("continuedAt"));
324
+ if (continuedAtId !== null) {
325
+ nextContinuationMap[nodeId] = continuedAtId;
326
+ }
327
+ if (name != 'CONTINUATION') {
328
+ itemContinuationMap[nodeId] = [];
329
+ }
312
330
  }
313
- }
331
+ });
314
332
  });
315
333
 
316
334
  // Map of continuation IDs to list of (default target doc) items that
@@ -330,6 +348,24 @@ export class Viewer {
330
348
  this.itemContinuationMap = itemContinuationMap;
331
349
  }
332
350
 
351
+ _setContinuationMaps() {
352
+ for (const [itemId, itemContinuations] of Object.entries(this.itemContinuationMap)) {
353
+ this._ixNodeMap[itemId].continuations = itemContinuations.map(id => this._ixNodeMap[id]);
354
+ }
355
+ }
356
+
357
+ _getOrCreateIXNode(vuid, nodes, docIndex, isHidden) {
358
+ // We may have already created an IXNode for this ID from a -sec-ix-hidden
359
+ // element
360
+ let ixn = this._ixNodeMap[vuid];
361
+ if (!ixn) {
362
+ ixn = new IXNode(vuid, nodes, docIndex);
363
+ this._ixNodeMap[vuid] = ixn;
364
+ ixn.isHidden = isHidden;
365
+ }
366
+ return ixn;
367
+ }
368
+
333
369
  //
334
370
  // Traverse the DOM hierarchy to find IX elements, and build maps and add
335
371
  // wrapper nodes and classes.
@@ -359,7 +395,7 @@ export class Viewer {
359
395
  // Viewer._docOrderItemIndex is a DocOrderIndex object that maintains a list of
360
396
  // fact and footnotes in document order.
361
397
  //
362
- _preProcessiXBRL(n, docIndex, inHidden) {
398
+ _preProcessiXBRL(n, reportIndex, docIndex, inHidden) {
363
399
  const name = localName(n.nodeName).toUpperCase();
364
400
  const isFootnote = name === 'FOOTNOTE';
365
401
  const isContinuation = name === 'CONTINUATION';
@@ -367,59 +403,48 @@ export class Viewer {
367
403
  const isNonFraction = name === 'NONFRACTION';
368
404
  const isFact = isNonNumeric || isNonFraction;
369
405
  if (n.nodeType === 1) {
370
- // Ignore iXBRL elements that are not in the default target document, as
371
- // the viewer builder does not handle these, and the builder does not
372
- // ensure that they have ID attributes.
373
- const id = n.getAttribute("id");
374
- if (((isFact || isFootnote) && !n.hasAttribute("target"))
375
- || (isContinuation && this.continuationOfMap[id] !== undefined)) {
376
- var nodes;
377
- if (inHidden) {
378
- nodes = $(n);
379
- } else {
380
- nodes = this._findOrCreateWrapperNode(n);
381
- }
382
-
383
- // For a continuation, store the IX ID(s) of the item(s), not the continuation
384
- const headId = isContinuation ? this.continuationOfMap[id] : id;
385
- this._addIdToNode(nodes.first(), headId);
386
-
387
- // We may have already created an IXNode for this ID from a -sec-ix-hidden
388
- // element
389
- var ixn = this._ixNodeMap[id];
390
- if (!ixn) {
391
- ixn = new IXNode(id, nodes, docIndex);
392
- this._ixNodeMap[id] = ixn;
393
- }
394
- if (inHidden) {
395
- ixn.isHidden = true;
396
- nodes.addClass("ixbrl-element-hidden");
397
- }
398
- if (isContinuation) {
399
- $(nodes).addClass("ixbrl-continuation");
400
- }
401
- else {
402
- this._docOrderItemIndex.addItem(id, docIndex);
403
- }
404
- if (isNonFraction) {
405
- $(nodes).addClass("ixbrl-element-nonfraction");
406
- if (n.hasAttribute('scale')) {
407
- const scale = Number(n.getAttribute('scale'));
408
- // Set scale if the value is a valid number and is not a redundant 0/"ones" scale.
409
- if (!Number.isNaN(scale) && scale !== 0) {
410
- ixn.scale = scale;
406
+ const vuid = viewerUniqueId(reportIndex, n.getAttribute("id"));
407
+ if (isFact || isFootnote) {
408
+ // If @id is not present, it must be for a target document that wasn't processed.
409
+ if (n.hasAttribute("id")) {
410
+ let nodes = this._findOrCreateWrapperNode(n, inHidden);
411
+
412
+ this._addIdToNode(nodes.first(), vuid);
413
+ let ixn = this._getOrCreateIXNode(vuid, nodes, docIndex, inHidden);
414
+ this._docOrderItemIndex.addItem(vuid, docIndex);
415
+
416
+ if (isNonFraction) {
417
+ nodes.addClass("ixbrl-element-nonfraction");
418
+ if (n.hasAttribute('scale')) {
419
+ const scale = Number(n.getAttribute('scale'));
420
+ // Set scale if the value is a valid number and is not a redundant 0/"ones" scale.
421
+ if (!Number.isNaN(scale) && scale !== 0) {
422
+ ixn.scale = scale;
423
+ }
411
424
  }
412
425
  }
413
- }
414
- if (isNonNumeric) {
415
- $(nodes).addClass("ixbrl-element-nonnumeric");
416
- if (n.hasAttribute('escape') && n.getAttribute('escape').match(/^(true|1)$/)) {
417
- ixn.escaped = true;
426
+ if (isNonNumeric) {
427
+ nodes.addClass("ixbrl-element-nonnumeric");
428
+ if (n.hasAttribute('escape') && n.getAttribute('escape').match(/^(true|1)$/)) {
429
+ ixn.escaped = true;
430
+ }
431
+ }
432
+ if (isFootnote) {
433
+ nodes.addClass("ixbrl-element-footnote");
434
+ ixn.footnote = true;
418
435
  }
419
436
  }
420
- if (isFootnote) {
421
- $(nodes).addClass("ixbrl-element-footnote");
422
- ixn.footnote = true;
437
+ }
438
+ else if (isContinuation) {
439
+ if (n.hasAttribute("id") && this.continuationOfMap[vuid] !== undefined) {
440
+ let nodes = this._findOrCreateWrapperNode(n, inHidden);
441
+
442
+ // For a continuation, store the IX ID(s) of the item(s), not the continuation
443
+ this._addIdToNode(nodes.first(), this.continuationOfMap[vuid]);
444
+
445
+ this._getOrCreateIXNode(vuid, nodes, docIndex, inHidden);
446
+
447
+ nodes.addClass("ixbrl-continuation");
423
448
  }
424
449
  }
425
450
  else if(name == 'HIDDEN') {
@@ -427,21 +452,21 @@ export class Viewer {
427
452
  }
428
453
  else {
429
454
  // Handle SEC/ESEF links-to-hidden
430
- const id = this._getIXHiddenLinkStyle(n);
431
- if (id !== null) {
432
- nodes = $(n);
433
- nodes.addClass("ixbrl-element").data('ivids', [id]);
434
- this._docOrderItemIndex.addItem(id, docIndex);
455
+ const vuid = viewerUniqueId(reportIndex, getIXHiddenLinkStyle(n));
456
+ if (vuid !== null) {
457
+ let nodes = this._findOrCreateWrapperNode(n, inHidden);
458
+ nodes.addClass("ixbrl-element").data('ivids', [vuid]);
459
+ this._docOrderItemIndex.addItem(vuid, docIndex);
435
460
  /* We may have already seen the corresponding ix element in the hidden
436
461
  * section */
437
- const ixn = this._ixNodeMap[id];
462
+ const ixn = this._ixNodeMap[vuid];
438
463
  if (ixn) {
439
464
  /* ... if so, update the node and docIndex so we can navigate to it */
440
465
  ixn.wrapperNodes = nodes;
441
466
  ixn.docIndex = docIndex;
442
467
  }
443
468
  else {
444
- this._ixNodeMap[id] = new IXNode(id, nodes, docIndex);
469
+ this._ixNodeMap[vuid] = new IXNode(vuid, nodes, docIndex);
445
470
  }
446
471
  }
447
472
  if (name == 'A') {
@@ -449,30 +474,19 @@ export class Viewer {
449
474
  }
450
475
  }
451
476
  }
452
- this._preProcessChildNodes(n, docIndex, inHidden);
477
+ this._preProcessChildNodes(n, reportIndex, docIndex, inHidden);
453
478
  }
454
479
 
455
- _getIXHiddenLinkStyle(domNode) {
456
- if (domNode.hasAttribute('style')) {
457
- const re = /(?:^|\s|;)-(?:sec|esef)-ix-hidden:\s*([^\s;]+)/;
458
- const m = domNode.getAttribute('style').match(re);
459
- if (m) {
460
- return m[1];
461
- }
462
- }
463
- return null;
464
- }
465
-
466
- _preProcessChildNodes(domNode, docIndex, inHidden) {
480
+ _preProcessChildNodes(domNode, reportIndex, docIndex, inHidden) {
467
481
  for (const childNode of domNode.childNodes) {
468
- this._preProcessiXBRL(childNode, docIndex, inHidden);
482
+ this._preProcessiXBRL(childNode, reportIndex, docIndex, inHidden);
469
483
  }
470
484
  }
471
485
 
472
486
  _applyStyles() {
473
487
  const stlyeElts = $("<style>")
474
488
  .prop("type", "text/css")
475
- .text(require('css-loader!less-loader!../less/viewer.less').toString())
489
+ .text(require('../less/viewer.less').toString())
476
490
  .appendTo(this._iframes.contents().find("head"));
477
491
  this._iv.callPluginMethod("updateViewerStyleElements", stlyeElts);
478
492
  }
@@ -489,43 +503,43 @@ export class Viewer {
489
503
  // moving to the next/prev element
490
504
  //
491
505
  _selectAdjacentTag(offset, currentItem) {
492
- var nextId;
506
+ var nextVuid;
493
507
  if (currentItem !== null) {
494
- nextId = this._docOrderItemIndex.getAdjacentItem(currentItem.id, offset);
495
- this.showDocumentForItemId(nextId);
508
+ nextVuid = this._docOrderItemIndex.getAdjacentItem(currentItem.vuid, offset);
509
+ this.showDocumentForItemId(nextVuid);
496
510
  }
497
511
  // If no fact selected go to the first or last in the current document
498
512
  else if (offset > 0) {
499
- nextId = this._docOrderItemIndex.getFirstInDocument(this._currentDocumentIndex);
513
+ nextVuid = this._docOrderItemIndex.getFirstInDocument(this._currentDocumentIndex);
500
514
  }
501
515
  else {
502
- nextId = this._docOrderItemIndex.getLastInDocument(this._currentDocumentIndex);
516
+ nextVuid = this._docOrderItemIndex.getLastInDocument(this._currentDocumentIndex);
503
517
  }
504
518
 
505
- const nextElement = this.elementsForItemId(nextId);
519
+ const nextElement = this.elementsForItemId(nextVuid);
506
520
  this.showElement(nextElement);
507
521
  // If this is a table cell with multiple nested tags pass all tags so that
508
522
  // all are shown in the inspector.
509
- this.selectElement(nextId, this._ixIdsForElement(nextElement));
523
+ this.selectElement(nextVuid, this._ixIdsForElement(nextElement));
510
524
  }
511
525
 
512
526
  _bindHandlers() {
513
527
  const viewer = this;
514
528
  $('.ixbrl-element', this._contents)
515
- .click(function (e) {
529
+ .on("click", function (e) {
516
530
  e.stopPropagation();
517
531
  viewer.selectElementByClick($(this));
518
532
  })
519
- .mouseenter(function (e) { viewer._mouseEnter($(this)) })
520
- .mouseleave(function (e) { viewer._mouseLeave($(this)) });
533
+ .on("mouseenter", function (e) { viewer._mouseEnter($(this)) })
534
+ .on("mouseleave", function (e) { viewer._mouseLeave($(this)) });
521
535
  $("body", this._contents)
522
- .click(() => viewer.selectElement(null));
536
+ .on("click", () => viewer.selectElement(null));
523
537
 
524
- $('#iframe-container .zoom-in').click(() => this.zoomIn());
525
- $('#iframe-container .zoom-out').click(() => this.zoomOut());
526
- $('#iframe-container .print').click(() => this.currentDocument().get(0).contentWindow.print());
538
+ $('#iframe-container .zoom-in').on("click", () => this.zoomIn());
539
+ $('#iframe-container .zoom-out').on("click", () => this.zoomOut());
540
+ $('#iframe-container .print').on("click", () => this.currentDocument().get(0).contentWindow.print());
527
541
 
528
- TableExport.addHandles(this._contents, this._report);
542
+ TableExport.addHandles(this._contents, this._reportSet);
529
543
  }
530
544
 
531
545
  selectNextTag(currentFact) {
@@ -593,14 +607,14 @@ export class Viewer {
593
607
  /* If the specified element is not fully visible, scroll it into the center of
594
608
  * the viewport */
595
609
  showElement(e) {
596
- const ee = e.get(0);
610
+ const ee = e.filter(':not(.ixbrl-no-highlight)').get(0);
597
611
  if (!this.isFullyVisible(ee)) {
598
612
  ee.scrollIntoView({ block: "center", inline: "center" });
599
613
  }
600
614
  }
601
615
 
602
616
  clearHighlighting() {
603
- $("body", this._iframes.contents()).find(".ixbrl-element, .ixbrl-sub-element").removeClass("ixbrl-selected").removeClass("ixbrl-related").removeClass("ixbrl-linked-highlight");
617
+ $("body", this._iframes.contents()).find(".ixbrl-element").removeClass("ixbrl-selected").removeClass("ixbrl-related").removeClass("ixbrl-linked-highlight");
604
618
  }
605
619
 
606
620
  _ixIdsForElement(e) {
@@ -616,9 +630,9 @@ export class Viewer {
616
630
  * byClick indicates that the element was clicked directly, and in this
617
631
  * case we never scroll to make it more visible.
618
632
  */
619
- selectElement(itemId, itemIdList, byClick) {
620
- if (itemId !== null) {
621
- this.onSelect.fire(itemId, itemIdList, byClick);
633
+ selectElement(vuid, itemIdList, byClick) {
634
+ if (vuid !== null) {
635
+ this.onSelect.fire(vuid, itemIdList, byClick);
622
636
  }
623
637
  else {
624
638
  this.onSelect.fire(null);
@@ -635,9 +649,9 @@ export class Viewer {
635
649
  // have nested elements, we select the innermost, as this gives the most
636
650
  // intuitive behaviour when clicking "next".
637
651
  selectElementByClick(e) {
638
- var itemIDList = [];
652
+ let itemIDList = [];
639
653
  const viewer = this;
640
- var sameContentAncestorId;
654
+ let sameContentAncestorVuid;
641
655
  // If the user clicked on a sub-element (and which is not also a proper
642
656
  // ixbrl-element) treat as if we clicked the first non-sub-element
643
657
  // ancestor in the DOM hierarchy - which would typically be
@@ -654,13 +668,13 @@ export class Viewer {
654
668
  // of the first one (sameContentAncestorId) that has exactly the same
655
669
  // content as "e"
656
670
  e.parents(".ixbrl-element").addBack().each(function () {
657
- const ids = viewer._ixIdsForElement($(this));
658
- itemIDList = itemIDList.concat(ids);
659
- if ($(this).text() == e.text() && sameContentAncestorId === undefined) {
660
- sameContentAncestorId = ids[0];
671
+ const vuids = viewer._ixIdsForElement($(this));
672
+ itemIDList = itemIDList.concat(vuids);
673
+ if ($(this).text() == e.text() && sameContentAncestorVuid === undefined) {
674
+ sameContentAncestorVuid = vuids[0];
661
675
  }
662
676
  });
663
- this.selectElement(sameContentAncestorId, itemIDList, true);
677
+ this.selectElement(sameContentAncestorVuid, itemIDList, true);
664
678
  }
665
679
 
666
680
  _mouseEnter(e) {
@@ -674,12 +688,12 @@ export class Viewer {
674
688
  }
675
689
 
676
690
  highlightRelatedFact(f) {
677
- this.changeItemClass(f.id, "ixbrl-related");
691
+ this.changeItemClass(f.vuid, "ixbrl-related");
678
692
  }
679
693
 
680
694
  highlightRelatedFacts(facts) {
681
695
  for (const f of facts) {
682
- this.changeItemClass(f.id, "ixbrl-related");
696
+ this.changeItemClass(f.vuid, "ixbrl-related");
683
697
  }
684
698
  }
685
699
 
@@ -690,19 +704,24 @@ export class Viewer {
690
704
  // Return a jQuery node list for wrapper elements corresponding to
691
705
  // the factId. May contain more than one node if the IX node contains
692
706
  // absolutely positioned elements.
693
- elementsForItemId(factId) {
694
- return this._ixNodeMap[factId].wrapperNodes;
707
+ elementsForItemId(vuid) {
708
+ if (!(vuid in this._ixNodeMap)){
709
+ throw new Error(`Attempting to retrieve IXNode with missing key: ${vuid}`);
710
+ }
711
+ return this._ixNodeMap[vuid].wrapperNodes;
695
712
  }
696
713
 
697
- elementsForItemIds(ids) {
698
- return $(ids.map(id => this._ixNodeMap[id].wrapperNodes.get()).flat());
714
+ // Returns a jQuery node list containing the primary wrapper node for each
715
+ // vuid provided
716
+ primaryElementsForItemIds(vuids) {
717
+ return $(vuids.map(vuid => this.elementsForItemId(vuid).first().get(0)));
699
718
  }
700
719
 
701
720
  /*
702
721
  * Add or remove a class to an item (fact or footnote) and any continuation elements
703
722
  */
704
- changeItemClass(itemId, highlightClass, removeClass) {
705
- const elements = this.elementsForItemIds([itemId].concat(this.itemContinuationMap[itemId]))
723
+ changeItemClass(vuid, highlightClass, removeClass) {
724
+ const elements = this.primaryElementsForItemIds([vuid].concat(this.itemContinuationMap[vuid]))
706
725
  if (removeClass) {
707
726
  elements.removeClass(highlightClass);
708
727
  }
@@ -714,15 +733,15 @@ export class Viewer {
714
733
  /*
715
734
  * Change the currently highlighted item
716
735
  */
717
- highlightItem(factId) {
736
+ highlightItem(vuid) {
718
737
  this.clearHighlighting();
719
- this.changeItemClass(factId, "ixbrl-selected");
738
+ this.changeItemClass(vuid, "ixbrl-selected");
720
739
  }
721
740
 
722
- showItemById(id) {
723
- if (id !== null) {
724
- let elts = this.elementsForItemId(id);
725
- this.showDocumentForItemId(id);
741
+ showItemById(vuid) {
742
+ if (vuid !== null) {
743
+ let elts = this.elementsForItemId(vuid);
744
+ this.showDocumentForItemId(vuid);
726
745
  /* Hidden elements will return an empty node list */
727
746
  if (elts.length > 0) {
728
747
  this.showElement(elts);
@@ -733,9 +752,9 @@ export class Viewer {
733
752
  highlightAllTags(on, namespaceGroups) {
734
753
  const groups = {};
735
754
  $.each(namespaceGroups, function (i, ns) {
736
- groups[ns] = i;
755
+ groups[ns] = i % HIGHLIGHT_COLORS;
737
756
  });
738
- const report = this._report;
757
+ const reportSet = this._reportSet;
739
758
  const viewer = this;
740
759
  if (on) {
741
760
  $(".ixbrl-element", this._contents)
@@ -746,18 +765,20 @@ export class Viewer {
746
765
  // highlight color for an element that is double tagged in a
747
766
  // table cell.
748
767
  const ixn = $(this).data('ivids').map(id => viewer._ixNodeMap[id]).filter(ixn => !ixn.footnote)[0];
749
- if (ixn != undefined) {
750
- const elements = viewer.elementsForItemIds(ixn.chainIXIds());
751
- const i = groups[report.getItemById(ixn.id).conceptQName().prefix];
752
- if (i !== undefined) {
753
- elements.addClass("ixbrl-highlight-" + i);
768
+ if (ixn !== undefined ) {
769
+ const item = reportSet.getItemById(ixn.id);
770
+ if (item !== undefined) {
771
+ const elements = viewer.primaryElementsForItemIds(ixn.chainIXIds());
772
+ const i = groups[item.conceptQName().prefix];
773
+ if (i !== undefined) {
774
+ elements.addClass("ixbrl-highlight-" + i);
775
+ }
754
776
  }
755
777
  }
756
778
  });
757
- $(".ixbrl-sub-element", this._contents).addClass("ixbrl-highlight");
758
779
  }
759
780
  else {
760
- $(".ixbrl-element, .ixbrl-sub-element", this._contents).removeClass(
781
+ $(".ixbrl-element", this._contents).removeClass(
761
782
  (i, className) => (className.match (/(^|\s)ixbrl-highlight\S*/g) || []).join(' ')
762
783
  );
763
784
  }
@@ -784,7 +805,7 @@ export class Viewer {
784
805
 
785
806
  factsInSameTable(fact) {
786
807
  var facts = [];
787
- const e = this.elementsForItemId(fact.id);
808
+ const e = this.elementsForItemId(fact.vuid);
788
809
  e.closest("table").find(".ixbrl-element").each(function () {
789
810
  facts = facts.concat($(this).data('ivids'));
790
811
  });
@@ -792,19 +813,22 @@ export class Viewer {
792
813
  }
793
814
 
794
815
  linkedHighlightFact(f) {
795
- this.changeItemClass(f.id, "ixbrl-linked-highlight");
816
+ this.changeItemClass(f.vuid, "ixbrl-linked-highlight");
796
817
  }
797
818
 
798
819
  clearLinkedHighlightFact(f) {
799
- this.changeItemClass(f.id, "ixbrl-linked-highlight", true);
820
+ this.changeItemClass(f.vuid, "ixbrl-linked-highlight", true);
800
821
  }
801
822
 
802
823
  _setTitle(docIndex) {
803
- $('#top-bar .document-title').text($('head title', this._iframes.eq(docIndex).contents()).text());
824
+ const title = $('head title', this._iframes.eq(docIndex).contents()).text();
825
+ $('#top-bar .document-title')
826
+ .text(title)
827
+ .attr("aria-label", "Inline Viewer: " + title);
804
828
  }
805
829
 
806
- showDocumentForItemId(itemId) {
807
- this.selectDocument(this._ixNodeMap[itemId].docIndex);
830
+ showDocumentForItemId(vuid) {
831
+ this.selectDocument(this._ixNodeMap[vuid].docIndex);
808
832
  }
809
833
 
810
834
  currentDocument() {