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,6 +1,13 @@
1
1
  // See COPYRIGHT.md for copyright information
2
2
 
3
3
  import {iXBRLViewer} from "./ixbrlviewer";
4
+ import {
5
+ FEATURE_GUIDE_LINK,
6
+ FEATURE_REVIEW,
7
+ FEATURE_SUPPORT_LINK,
8
+ FEATURE_SURVEY_LINK,
9
+ USER_GUIDE_URL,
10
+ } from "./util";
4
11
  describe("Feature enablement", () => {
5
12
  var viewer = null;
6
13
  beforeAll(() => {
@@ -8,58 +15,99 @@ describe("Feature enablement", () => {
8
15
  });
9
16
 
10
17
  test("Query parameter with no value results in enablement", () => {
11
- viewer.setFeatures([], 'a')
12
- expect(viewer._features).toEqual(new Set(['a']));
18
+ viewer.setFeatures({}, 'a')
19
+ expect(viewer._staticFeatures).toEqual({});
20
+ expect(viewer._dynamicFeatures).toEqual({'a': 'true'});
13
21
  expect(viewer.isFeatureEnabled('a')).toBeTruthy();
14
22
  });
15
23
 
16
24
  test("Excluded from JSON, excluded from query", () => {
17
- viewer.setFeatures([], '')
18
- expect(viewer._features).toEqual(new Set([]));
25
+ viewer.setFeatures({}, '')
26
+ expect(viewer._staticFeatures).toEqual({});
27
+ expect(viewer._dynamicFeatures).toEqual({});
19
28
  expect(viewer.isFeatureEnabled('a')).toBeFalsy();
20
29
  });
21
30
 
22
31
  test("Excluded from JSON, enabled in query", () => {
23
- viewer.setFeatures([], 'a=true')
24
- expect(viewer._features).toEqual(new Set(['a']));
32
+ viewer.setFeatures({}, 'a=true')
33
+ expect(viewer._staticFeatures).toEqual({});
34
+ expect(viewer._dynamicFeatures).toEqual({'a': 'true'});
25
35
  expect(viewer.isFeatureEnabled('a')).toBeTruthy();
26
36
  });
27
37
 
28
38
  test("Excluded from JSON, disabled in query", () => {
29
- viewer.setFeatures([], 'a=false')
30
- expect(viewer._features).toEqual(new Set([]));
39
+ viewer.setFeatures({}, 'a=false')
40
+ expect(viewer._staticFeatures).toEqual({});
41
+ expect(viewer._dynamicFeatures).toEqual({'a': 'false'});
31
42
  expect(viewer.isFeatureEnabled('a')).toBeFalsy();
32
43
  });
33
44
 
34
45
  test("Excluded from JSON, enabled and disabled in query", () => {
35
- viewer.setFeatures([], 'a=true&a=false&a')
36
- expect(viewer._features).toEqual(new Set([]));
46
+ viewer.setFeatures({}, 'a=true&a=false&a')
47
+ expect(viewer._staticFeatures).toEqual({});
48
+ expect(viewer._dynamicFeatures).toEqual({'a': 'false'});
37
49
  expect(viewer.isFeatureEnabled('a')).toBeFalsy();
38
50
  });
39
51
 
40
52
  test("Included in JSON, excluded from query", () => {
41
- viewer.setFeatures(['a'], '')
42
- expect(viewer._features).toEqual(new Set(['a']));
53
+ viewer.setFeatures({'a': true}, '')
54
+ expect(viewer._staticFeatures).toEqual({'a': true});
55
+ expect(viewer._dynamicFeatures).toEqual({});
43
56
  expect(viewer.isFeatureEnabled('a')).toBeTruthy();
44
57
  });
45
58
 
46
59
  test("Included in JSON, enabled in query", () => {
47
- viewer.setFeatures(['a'], 'a=true')
48
- expect(viewer._features).toEqual(new Set(['a']));
60
+ viewer.setFeatures({'a': true}, 'a=true')
61
+ expect(viewer._staticFeatures).toEqual({'a': true});
62
+ expect(viewer._dynamicFeatures).toEqual({'a': 'true'});
49
63
  expect(viewer.isFeatureEnabled('a')).toBeTruthy();
50
64
  });
51
65
 
52
66
  test("Included in JSON, disabled in query", () => {
53
- viewer.setFeatures(['a'], 'a=false')
54
- expect(viewer._features).toEqual(new Set([]));
67
+ viewer.setFeatures({'a': true}, 'a=false')
68
+ expect(viewer._staticFeatures).toEqual({'a': true});
69
+ expect(viewer._dynamicFeatures).toEqual({'a': 'false'});
55
70
  expect(viewer.isFeatureEnabled('a')).toBeFalsy();
56
71
  });
57
72
 
58
73
  test("Included in JSON, enabled and disabled in query", () => {
59
- viewer.setFeatures(['a'], 'a=true&a=false&a')
60
- expect(viewer._features).toEqual(new Set([]));
74
+ viewer.setFeatures({'a': true}, 'a=true&a=false&a')
75
+ expect(viewer._staticFeatures).toEqual({'a': true});
76
+ expect(viewer._dynamicFeatures).toEqual({'a': 'false'});
61
77
  expect(viewer.isFeatureEnabled('a')).toBeFalsy();
62
78
  });
79
+
80
+ test("Value set in JSON, not included in query", () => {
81
+ viewer.setFeatures({'a': '1'}, '')
82
+ expect(viewer._staticFeatures).toEqual({'a': '1'});
83
+ expect(viewer._dynamicFeatures).toEqual({});
84
+ expect(viewer.getFeatureValue('a')).toEqual('1');
85
+ expect(viewer.isFeatureEnabled('a')).toBeTruthy();
86
+ });
87
+
88
+ test("Value not set in JSON, set in query", () => {
89
+ viewer.setFeatures({}, 'a=1')
90
+ expect(viewer._staticFeatures).toEqual({});
91
+ expect(viewer._dynamicFeatures).toEqual({'a': '1'});
92
+ expect(viewer.getFeatureValue('a')).toEqual('1');
93
+ expect(viewer.isFeatureEnabled('a')).toBeTruthy();
94
+ });
95
+
96
+ test("Value set in JSON, overwritten in query", () => {
97
+ viewer.setFeatures({'a': '1'}, 'a=2')
98
+ expect(viewer._staticFeatures).toEqual({'a': '1'});
99
+ expect(viewer._dynamicFeatures).toEqual({'a': '2'});
100
+ expect(viewer.getFeatureValue('a')).toEqual('2');
101
+ expect(viewer.isFeatureEnabled('a')).toBeTruthy();
102
+ });
103
+
104
+ test("Value set in JSON, overwritten in query with blank", () => {
105
+ viewer.setFeatures({'a': '1'}, 'a')
106
+ expect(viewer._staticFeatures).toEqual({'a': '1'});
107
+ expect(viewer._dynamicFeatures).toEqual({'a': 'true'});
108
+ expect(viewer.getFeatureValue('a')).toEqual('true');
109
+ expect(viewer.isFeatureEnabled('a')).toBeTruthy();
110
+ });
63
111
  });
64
112
 
65
113
  describe("Review mode enablement", () => {
@@ -69,12 +117,78 @@ describe("Review mode enablement", () => {
69
117
  });
70
118
 
71
119
  test("Review mode enabled", () => {
72
- viewer.setFeatures(['review'], '')
120
+ viewer.setFeatures({[FEATURE_REVIEW]: true}, '')
73
121
  expect(viewer.isReviewModeEnabled()).toBeTruthy();
74
122
  });
75
123
 
76
124
  test("Review mode disabled", () => {
77
- viewer.setFeatures(['a'], '')
125
+ viewer.setFeatures({'a': true}, '')
78
126
  expect(viewer.isReviewModeEnabled()).toBeFalsy();
79
127
  });
80
128
  });
129
+
130
+ describe("Support link enablement", () => {
131
+ var viewer = null;
132
+ beforeAll(() => {
133
+ viewer = new iXBRLViewer({})
134
+ });
135
+
136
+ test("Support link enabled by JSON", () => {
137
+ viewer.setFeatures({[FEATURE_SUPPORT_LINK]: '/help'}, '')
138
+ expect(viewer.getSupportLinkUrl()).toEqual('/help');
139
+ });
140
+
141
+ test("Support link enabled by query", () => {
142
+ viewer.setFeatures({}, FEATURE_SUPPORT_LINK + '=/help')
143
+ expect(viewer.getSupportLinkUrl()).toEqual(null);
144
+ });
145
+
146
+ test("Support link disabled by query", () => {
147
+ viewer.setFeatures({[FEATURE_SUPPORT_LINK]: '/help'}, FEATURE_SUPPORT_LINK + '=false')
148
+ expect(viewer.getSupportLinkUrl()).toEqual('/help');
149
+ });
150
+ });
151
+
152
+ describe("Survey link enablement", () => {
153
+ var viewer = null;
154
+ beforeAll(() => {
155
+ viewer = new iXBRLViewer({})
156
+ });
157
+
158
+ test("Survey link enabled by JSON", () => {
159
+ viewer.setFeatures({[FEATURE_SURVEY_LINK]: '/survey'}, '')
160
+ expect(viewer.getSurveyLinkUrl()).toEqual('/survey');
161
+ });
162
+
163
+ test("Survey link enabled by query", () => {
164
+ viewer.setFeatures({}, FEATURE_SURVEY_LINK + '=/survey')
165
+ expect(viewer.getSurveyLinkUrl()).toEqual(null);
166
+ });
167
+
168
+ test("Survey link disabled by query", () => {
169
+ viewer.setFeatures({[FEATURE_SURVEY_LINK]: '/survey'}, FEATURE_SURVEY_LINK + '=false')
170
+ expect(viewer.getSurveyLinkUrl()).toEqual('/survey');
171
+ });
172
+ });
173
+
174
+ describe("Guide link enablement", () => {
175
+ var viewer = null;
176
+ beforeAll(() => {
177
+ viewer = new iXBRLViewer({})
178
+ });
179
+
180
+ test("Guide link enabled by JSON", () => {
181
+ viewer.setFeatures({[FEATURE_GUIDE_LINK]: '/guide'}, '')
182
+ expect(viewer.getGuideLinkUrl()).toEqual('/guide');
183
+ });
184
+
185
+ test("Guide link enabled by query", () => {
186
+ viewer.setFeatures({}, FEATURE_GUIDE_LINK + '=/guide')
187
+ expect(viewer.getGuideLinkUrl()).toEqual(USER_GUIDE_URL);
188
+ });
189
+
190
+ test("Guide link disabled by query", () => {
191
+ viewer.setFeatures({[FEATURE_GUIDE_LINK]: '/guide'}, FEATURE_GUIDE_LINK + '=false')
192
+ expect(viewer.getGuideLinkUrl()).toEqual('/guide');
193
+ });
194
+ });
@@ -46,6 +46,6 @@ export class IXNode {
46
46
  }
47
47
 
48
48
  htmlHidden() {
49
- return this.wrapperNodes.is(':hidden') || this.wrapperNodes.is((i,e) => isTransparent($(e).css('color')));
49
+ return this.wrapperNodes.filter(':not(.ixbrl-no-highlight)').is(':hidden') || this.wrapperNodes.is((i,e) => isTransparent($(e).css('color')));
50
50
  }
51
51
  }
@@ -1,6 +1,7 @@
1
1
  // See COPYRIGHT.md for copyright information
2
2
 
3
3
  import $ from 'jquery'
4
+ import i18next from "i18next";
4
5
 
5
6
  export class Menu {
6
7
  constructor(elt, attr) {
@@ -8,14 +9,14 @@ export class Menu {
8
9
  attr = attr || {};
9
10
  this.type = attr.type || "dropdown";
10
11
 
11
- elt.find(".menu-title").click((e) => {
12
+ elt.find(".menu-title").on("click", (e) => {
12
13
  elt.find(".content-container").toggle();
13
14
  /* Stop an opening click from also being treated as an "out-of-menu"
14
15
  * closing click */
15
16
  e.stopPropagation();
16
17
  });
17
18
 
18
- $('html').click((event) => {
19
+ $('html').on("click", (event) => {
19
20
  if ($(".content", elt).find($(event.target)).length === 0) {
20
21
  this.close();
21
22
  }
@@ -50,7 +51,7 @@ export class Menu {
50
51
  .attr({
51
52
  href: filename})
52
53
  .text(name)
53
- .click(() => menu.close());
54
+ .on("click", () => menu.close());
54
55
  this._add(item);
55
56
  }
56
57
 
@@ -65,14 +66,14 @@ export class Menu {
65
66
  $('<input type="checkbox"></input>')
66
67
  .prop("checked", onByDefault)
67
68
  .change(function () {
68
- callback($(this).prop("checked"));
69
+ callback($(this).prop("checked"), true);
69
70
  menu.close();
70
71
  })
71
72
  )
72
73
  .append($("<span></span>").addClass("checkmark"));
73
74
  this._add(item, after);
74
75
  if (onByDefault) {
75
- callback(true);
76
+ callback(true, false);
76
77
  }
77
78
  }
78
79
 
@@ -89,9 +90,8 @@ export class Menu {
89
90
  .prepend(
90
91
  $('<input type="radio"></input>')
91
92
  .attr({ "name": name, "value": v})
92
- .change(function () {
93
+ .on("change", function () {
93
94
  callback($(this).val())
94
- menu.close();
95
95
  })
96
96
  )
97
97
  .append($("<span></span>").addClass("checkmark"))
@@ -102,4 +102,22 @@ export class Menu {
102
102
  }
103
103
  }
104
104
  }
105
+
106
+ addLabel(name) {
107
+ const item = $('<div></div>')
108
+ .addClass("label")
109
+ .text(name)
110
+ this._add(item);
111
+ }
112
+
113
+ addLink(label, href) {
114
+ const item = $("<a></a>")
115
+ .attr("href", href)
116
+ .attr("target", "_blank")
117
+ .attr("title", label)
118
+ .attr("aria-label", label)
119
+ .addClass("item")
120
+ .text(label);
121
+ this._add(item);
122
+ }
105
123
  }
@@ -47,9 +47,9 @@ const hyphen = '[-\u2014]';
47
47
 
48
48
  // everything that we allow immediately before a match
49
49
  // (201c = left double quote, 2014 = em dash, 201d = right double quote)
50
- const begin_guard = '(?:^|(?<=(?:[/\u201c\u2014(]|' + one_ws + '|' + hyphen + ')))';
50
+ const begin_guard = '(?:^|(?<=(?:[/\u201c\u2014([]|' + one_ws + '|' + hyphen + ')))';
51
51
  // everything that we allow immediately after a match
52
- const end_guard = '(?:$|(?=(?:[/,.:;\u201d\u2014)]|' + one_ws + '|' + hyphen + ')))';
52
+ const end_guard = '(?:$|(?=(?:[/,.:;\u201d\u2014)\\]]|' + one_ws + '|' + hyphen + ')))';
53
53
 
54
54
  const ordinal_suffix = '(?:st|nd|rd|th)';
55
55
  const day = '[123]?\\d' + ordinal_suffix + '?';
@@ -90,6 +90,10 @@ const note = 'note' + ws + '\\d{1,3}';
90
90
  const level = 'level' + ws + '\\d{1,3}';
91
91
  const page = 'page' + ws + '\\d{1,3}';
92
92
  const tier = 'tier' + ws + '\\d{1,3}';
93
+ const act = 'act' + ws + 'of' + ws + year; // e.g. 'SECURITIES EXCHANGE ACT OF 1934'
94
+ // Note that this is a superset of "isoDate" but "dateMatch" appears before "do_not_want" so it won't exclude ISO dates.
95
+ const phone_number = '\\d+-\\d+[-\\d]*' // e.g. 275-3125. Also covers employer number (e.g. 47-2509828).
96
+ const form_name = '(?:10|8)-(?:k|q)' // e.g. '10-K'
93
97
 
94
98
  const months_ended = r_or([number_word, '\\d+']) + ws + 'months ended';
95
99
 
@@ -98,7 +102,7 @@ const month_day_year = month_num + '/' + day_with_0 + '/' + year;
98
102
  const month_year = month_num + '/\\d\\d';
99
103
 
100
104
  const do_not_want = r_or([section, topic, form, asc, item, rule, note, level, page,
101
- tier, months_ended, month_day_year, month_year]);
105
+ tier, act, phone_number, form_name, months_ended, month_day_year, month_year]);
102
106
 
103
107
  const number_separator = r_or([r_maybe(ws + hyphen + ws), ws]);
104
108
  const number_word_string = number_word + r_zero_or_more(number_separator + number_word);
@@ -112,12 +112,16 @@ describe("Number match replace", () => {
112
112
  var numbers = [
113
113
  [ 'Sept 20th, 2019', '[[Sept 20th, 2019]]' ],
114
114
  [ 'abcd 37 abcd', 'abcd [[37]] abcd' ],
115
+ [ '2010-01-01', '[[2010-01-01]]' ],
115
116
  // Test "do not want" filtering
116
117
  [ 'abcd topic 37 abcd', 'abcd topic 37 abcd' ],
117
118
  [ 'abcd topic 37 93 abcd', 'abcd topic 37 [[93]] abcd' ],
118
119
  [ 'section 123(a)', 'section 123(a)' ],
119
120
  [ 'section 123a', 'section 123a' ],
120
121
  [ 'section 123', 'section 123' ],
122
+ [ 'securities exchange act of 1934', 'securities exchange act of 1934' ],
123
+ [ '10-K', '10-K' ],
124
+ [ '274-3125', '274-3125' ],
121
125
  // Doesn't match due to end guard
122
126
  [ '401(k)', '401(k)' ],
123
127
  [ 'N RM100', 'N [[RM100]]' ],
@@ -1,6 +1,24 @@
1
1
  // See COPYRIGHT.md for copyright information
2
2
 
3
- import $ from 'jquery'
3
+ export class ReportSetOutline {
4
+ constructor(reportSet) {
5
+ this._reportSet = reportSet;
6
+ this.outlines = reportSet.reports.map(r => new DocumentOutline(r));
7
+ }
8
+
9
+ hasOutline() {
10
+ return this.outlines.some(o => Object.keys(o.sections).length > 0);
11
+ }
12
+
13
+ sortedSections() {
14
+ return this.outlines.flatMap(o => o.sortedSections());
15
+ }
16
+
17
+ groupsForFact(f) {
18
+ return this.outlines.find(o => o.report == f.report).groupsForFact(f);
19
+ }
20
+
21
+ }
4
22
 
5
23
  // DocumentOutline chooses a fact for each presentation group (ELR) that
6
24
  // represents the start of that ELR. This is done by deciding which ELRs each
@@ -8,7 +26,7 @@ import $ from 'jquery'
8
26
  // continuous run of facts in document order that participate in each ELR.
9
27
  export class DocumentOutline {
10
28
  constructor(report) {
11
- this._report = report;
29
+ this.report = report;
12
30
  const facts = report.facts().sort((a, b) => a.ixNode.docOrderindex - b.ixNode.docOrderindex);
13
31
  const runLength = {};
14
32
  const runStart = {};
@@ -57,7 +75,8 @@ export class DocumentOutline {
57
75
  factInGroup(fact, elr) {
58
76
  // Roots are abstract so no need to check for concepts with outgoing
59
77
  // relationships only.
60
- if (this._report.getParentRelationshipsInGroup(fact.conceptName(), "pres", elr).length == 0) {
78
+
79
+ if (this.report.getParentRelationshipsInGroup(fact.conceptName(), "pres", elr).length == 0) {
61
80
  return false;
62
81
  }
63
82
  const fd = fact.dimensions();
@@ -97,18 +116,18 @@ export class DocumentOutline {
97
116
  // between presentation and dimensional ELRs.
98
117
  //
99
118
  _buildDimensionMap() {
100
- const groups = this._report.relationshipGroups("pres");
119
+ const groups = this.report.relationshipGroups("pres");
101
120
  this.dimensionMap = {};
102
121
  for (const elr of groups) {
103
122
  this.dimensionMap[elr] = {};
104
- for (const root of this._report.relationshipGroupRoots("pres", elr)) {
123
+ for (const root of this.report.relationshipGroupRoots("pres", elr)) {
105
124
  this.buildDimensionMapFromSubTree("pres", elr, null, root);
106
125
  }
107
126
  }
108
127
  }
109
128
 
110
129
  buildDimensionMapFromSubTree(arcrole, elr, dimension, conceptName) {
111
- const c = this._report.getConcept(conceptName);
130
+ const c = this.report.getConcept(conceptName);
112
131
  if (c.isTypedDimension()) {
113
132
  this.dimensionMap[elr][conceptName] = { typed: true };
114
133
  return
@@ -117,13 +136,13 @@ export class DocumentOutline {
117
136
  dimension = conceptName;
118
137
  this.dimensionMap[elr][dimension] = { members: {}, allowDefault: false};
119
138
  }
120
- var children = this._report.getChildRelationships(conceptName, arcrole);
139
+ var children = this.report.getChildRelationships(conceptName, arcrole);
121
140
  if (!(elr in children)) {
122
141
  return
123
142
  }
124
143
  for (var rel of children[elr]) {
125
144
  if (dimension) {
126
- if (this._report.dimensionDefault(dimension) == rel.t) {
145
+ if (this.report.dimensionDefault(dimension) == rel.t) {
127
146
  this.dimensionMap[elr][dimension].allowDefault = true;
128
147
  }
129
148
  else {
@@ -136,10 +155,10 @@ export class DocumentOutline {
136
155
 
137
156
  // Returns a list of presentation groups that this fact participates in
138
157
  groupsForFact(fact) {
139
- var factGroups = [];
140
- for (const group of this._report.relationshipGroups("pres")) {
158
+ const factGroups = [];
159
+ for (const group of this.report.relationshipGroups("pres")) {
141
160
  if (this.factInGroup(fact, group)) {
142
- factGroups.push(group);
161
+ factGroups.push({ elr: group, fact: this.sections[group], report: this.report});
143
162
  }
144
163
  }
145
164
  return factGroups;
@@ -152,7 +171,9 @@ export class DocumentOutline {
152
171
  sortedSections() {
153
172
  const sections = Object.keys(this.sections);
154
173
  const re = /\(parenthetical\)\s*$/i;
155
- const filteredSections = sections.filter(s => !re.test(this._report.getRoleLabel(s)));
156
- return filteredSections.sort((a, b) => this._report.getRoleLabel(a).localeCompare(this._report.getRoleLabel(b)));
174
+ const filteredSections = sections.filter(s => !re.test(this.report.getRoleLabelOrURI(s)));
175
+ return filteredSections
176
+ .sort((a, b) => this.report.getRoleLabelOrURI(a).localeCompare(this.report.getRoleLabelOrURI(b)))
177
+ .map(elr => ({ report: this.report, fact: this.sections[elr], elr: elr }));
157
178
  }
158
179
  }