@fiduswriter/bibliography-manager 0.1.7 → 0.1.9

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 (176) hide show
  1. package/README.md +53 -12
  2. package/dist/database/index.d.ts +12 -11
  3. package/dist/database/index.d.ts.map +1 -1
  4. package/dist/database/index.js +22 -16
  5. package/dist/database/index.js.map +1 -1
  6. package/dist/database/server_connector.d.ts +14 -15
  7. package/dist/database/server_connector.d.ts.map +1 -1
  8. package/dist/database/server_connector.js +17 -9
  9. package/dist/database/server_connector.js.map +1 -1
  10. package/dist/export/index.d.ts +6 -4
  11. package/dist/export/index.d.ts.map +1 -1
  12. package/dist/export/index.js +7 -1
  13. package/dist/export/index.js.map +1 -1
  14. package/dist/form/cats.d.ts +5 -4
  15. package/dist/form/cats.d.ts.map +1 -1
  16. package/dist/form/cats.js +2 -0
  17. package/dist/form/cats.js.map +1 -1
  18. package/dist/form/fields/date.d.ts +4 -4
  19. package/dist/form/fields/date.d.ts.map +1 -1
  20. package/dist/form/fields/date.js +5 -1
  21. package/dist/form/fields/date.js.map +1 -1
  22. package/dist/form/fields/key.d.ts +11 -9
  23. package/dist/form/fields/key.d.ts.map +1 -1
  24. package/dist/form/fields/key.js +13 -6
  25. package/dist/form/fields/key.js.map +1 -1
  26. package/dist/form/fields/key_list.d.ts +10 -8
  27. package/dist/form/fields/key_list.d.ts.map +1 -1
  28. package/dist/form/fields/key_list.js +4 -0
  29. package/dist/form/fields/key_list.js.map +1 -1
  30. package/dist/form/fields/literal.d.ts +4 -4
  31. package/dist/form/fields/literal.d.ts.map +1 -1
  32. package/dist/form/fields/literal.js +2 -1
  33. package/dist/form/fields/literal.js.map +1 -1
  34. package/dist/form/fields/literal_list.d.ts +8 -7
  35. package/dist/form/fields/literal_list.d.ts.map +1 -1
  36. package/dist/form/fields/literal_list.js +3 -0
  37. package/dist/form/fields/literal_list.js.map +1 -1
  38. package/dist/form/fields/literal_long.d.ts +4 -4
  39. package/dist/form/fields/literal_long.d.ts.map +1 -1
  40. package/dist/form/fields/literal_long.js +1 -0
  41. package/dist/form/fields/literal_long.js.map +1 -1
  42. package/dist/form/fields/name.d.ts +10 -27
  43. package/dist/form/fields/name.d.ts.map +1 -1
  44. package/dist/form/fields/name.js +22 -18
  45. package/dist/form/fields/name.js.map +1 -1
  46. package/dist/form/fields/name_list.d.ts +9 -7
  47. package/dist/form/fields/name_list.d.ts.map +1 -1
  48. package/dist/form/fields/name_list.js +5 -2
  49. package/dist/form/fields/name_list.js.map +1 -1
  50. package/dist/form/fields/range.d.ts +10 -8
  51. package/dist/form/fields/range.d.ts.map +1 -1
  52. package/dist/form/fields/range.js +13 -9
  53. package/dist/form/fields/range.js.map +1 -1
  54. package/dist/form/fields/range_list.d.ts +9 -7
  55. package/dist/form/fields/range_list.d.ts.map +1 -1
  56. package/dist/form/fields/range_list.js +3 -0
  57. package/dist/form/fields/range_list.js.map +1 -1
  58. package/dist/form/fields/tag_list.d.ts +7 -6
  59. package/dist/form/fields/tag_list.d.ts.map +1 -1
  60. package/dist/form/fields/tag_list.js +3 -0
  61. package/dist/form/fields/tag_list.js.map +1 -1
  62. package/dist/form/fields/title.d.ts +4 -4
  63. package/dist/form/fields/title.d.ts.map +1 -1
  64. package/dist/form/fields/title.js +1 -0
  65. package/dist/form/fields/title.js.map +1 -1
  66. package/dist/form/fields/uri.d.ts +4 -4
  67. package/dist/form/fields/uri.d.ts.map +1 -1
  68. package/dist/form/fields/uri.js +5 -1
  69. package/dist/form/fields/uri.js.map +1 -1
  70. package/dist/form/fields/verbatim.d.ts +4 -4
  71. package/dist/form/fields/verbatim.d.ts.map +1 -1
  72. package/dist/form/fields/verbatim.js +5 -1
  73. package/dist/form/fields/verbatim.js.map +1 -1
  74. package/dist/form/index.d.ts +32 -30
  75. package/dist/form/index.d.ts.map +1 -1
  76. package/dist/form/index.js +33 -11
  77. package/dist/form/index.js.map +1 -1
  78. package/dist/form/strings.d.ts +11 -11
  79. package/dist/form/strings.d.ts.map +1 -1
  80. package/dist/form/strings.js +5 -5
  81. package/dist/form/strings.js.map +1 -1
  82. package/dist/form/templates.d.ts +6 -5
  83. package/dist/form/templates.d.ts.map +1 -1
  84. package/dist/form/templates.js +2 -2
  85. package/dist/form/templates.js.map +1 -1
  86. package/dist/import/bibliography_import.d.ts +20 -7
  87. package/dist/import/bibliography_import.d.ts.map +1 -1
  88. package/dist/import/bibliography_import.js +15 -7
  89. package/dist/import/bibliography_import.js.map +1 -1
  90. package/dist/import/dialog.d.ts +6 -5
  91. package/dist/import/dialog.d.ts.map +1 -1
  92. package/dist/import/dialog.js +27 -12
  93. package/dist/import/dialog.js.map +1 -1
  94. package/dist/import/index.d.ts +2 -0
  95. package/dist/import/index.d.ts.map +1 -1
  96. package/dist/import/index.js +5 -0
  97. package/dist/import/index.js.map +1 -1
  98. package/dist/import/templates.d.ts +2 -1
  99. package/dist/import/templates.d.ts.map +1 -1
  100. package/dist/import/templates.js.map +1 -1
  101. package/dist/index.d.ts +2 -0
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js.map +1 -1
  104. package/dist/overview/index.d.ts +43 -28
  105. package/dist/overview/index.d.ts.map +1 -1
  106. package/dist/overview/index.js +55 -20
  107. package/dist/overview/index.js.map +1 -1
  108. package/dist/overview/menu.d.ts +13 -12
  109. package/dist/overview/menu.d.ts.map +1 -1
  110. package/dist/overview/menu.js +13 -10
  111. package/dist/overview/menu.js.map +1 -1
  112. package/dist/overview/templates.d.ts +5 -3
  113. package/dist/overview/templates.d.ts.map +1 -1
  114. package/dist/overview/templates.js.map +1 -1
  115. package/dist/plugins/bibliography_overview/index.d.ts +1 -1
  116. package/dist/plugins/bibliography_overview/index.d.ts.map +1 -1
  117. package/dist/plugins/bibliography_overview/index.js.map +1 -1
  118. package/dist/schema/csl_bib.d.ts +1 -1
  119. package/dist/schema/literal.d.ts +1 -1
  120. package/dist/schema/literal.d.ts.map +1 -1
  121. package/dist/schema/literal.js.map +1 -1
  122. package/dist/schema/literal_long.d.ts +1 -1
  123. package/dist/schema/literal_long.d.ts.map +1 -1
  124. package/dist/schema/literal_long.js +1 -7
  125. package/dist/schema/literal_long.js.map +1 -1
  126. package/dist/schema/title.d.ts +1 -1
  127. package/dist/schema/title.d.ts.map +1 -1
  128. package/dist/schema/title.js.map +1 -1
  129. package/dist/tools.d.ts +4 -3
  130. package/dist/tools.d.ts.map +1 -1
  131. package/dist/tools.js.map +1 -1
  132. package/dist/types/biblio.d.ts +138 -0
  133. package/dist/types/biblio.d.ts.map +1 -0
  134. package/dist/types/biblio.js +2 -0
  135. package/dist/types/biblio.js.map +1 -0
  136. package/package.json +88 -74
  137. package/src/database/{index.js → index.ts} +60 -38
  138. package/src/database/server_connector.ts +92 -0
  139. package/src/export/{index.js → index.ts} +16 -4
  140. package/src/form/{cats.js → cats.ts} +11 -3
  141. package/src/form/fields/{date.js → date.ts} +10 -5
  142. package/src/form/fields/{key.js → key.ts} +37 -19
  143. package/src/form/fields/{key_list.js → key_list.ts} +18 -7
  144. package/src/form/fields/{literal.js → literal.ts} +11 -5
  145. package/src/form/fields/{literal_list.js → literal_list.ts} +19 -10
  146. package/src/form/fields/{literal_long.js → literal_long.ts} +6 -4
  147. package/src/form/fields/{name.js → name.ts} +53 -39
  148. package/src/form/fields/name_list.ts +49 -0
  149. package/src/form/fields/{range.js → range.ts} +34 -22
  150. package/src/form/fields/{range_list.js → range_list.ts} +17 -10
  151. package/src/form/fields/{tag_list.js → tag_list.ts} +9 -5
  152. package/src/form/fields/{title.js → title.ts} +6 -4
  153. package/src/form/fields/{uri.js → uri.ts} +11 -6
  154. package/src/form/fields/{verbatim.js → verbatim.ts} +10 -5
  155. package/src/form/{index.js → index.ts} +113 -60
  156. package/src/form/{strings.js → strings.ts} +24 -22
  157. package/src/form/{templates.js → templates.ts} +14 -5
  158. package/src/global.d.ts +75 -0
  159. package/src/import/{bibliography_import.js → bibliography_import.ts} +42 -16
  160. package/src/import/{dialog.js → dialog.ts} +47 -23
  161. package/src/import/index.ts +14 -0
  162. package/src/import/{templates.js → templates.ts} +1 -1
  163. package/src/overview/{index.js → index.ts} +147 -79
  164. package/src/overview/{menu.js → menu.ts} +18 -12
  165. package/src/overview/{templates.js → templates.ts} +3 -2
  166. package/src/plugins/bibliography_overview/index.ts +1 -0
  167. package/src/schema/{literal_long.js → literal_long.ts} +3 -8
  168. package/src/schema/{title.js → title.ts} +1 -1
  169. package/src/{tools.js → tools.ts} +7 -5
  170. package/src/types/biblio.ts +189 -0
  171. package/src/database/server_connector.js +0 -57
  172. package/src/form/fields/name_list.js +0 -42
  173. package/src/import/index.js +0 -2
  174. package/src/plugins/bibliography_overview/index.js +0 -1
  175. /package/src/{index.js → index.ts} +0 -0
  176. /package/src/schema/{literal.js → literal.ts} +0 -0
@@ -12,15 +12,48 @@ import {
12
12
  setDocTitle,
13
13
  whenReady
14
14
  } from "fwtoolkit"
15
+ import type {DialogButtonSpec} from "fwtoolkit/dialog"
16
+ import type {DatatableBulk} from "fwtoolkit"
17
+ import type {OverviewMenuModel} from "fwtoolkit/overview_menu"
18
+ import type {ContentMenuInit} from "fwtoolkit/content_menu"
19
+ import type {DataTable} from "simple-datatables"
15
20
  import {baseBodyTemplate, FeedbackTab, SiteMenu} from "@fiduswriter/common"
16
21
  import {plugins as defaultBibPlugins} from "../plugins/bibliography_overview/index.js"
17
22
  import {getBibTypeTitle} from "../form/strings.js"
18
23
  import {litToText, nameToText} from "../tools.js"
24
+ import type {
25
+ BibCategory,
26
+ BibliographyApp,
27
+ IdTranslation,
28
+ NameDictObject,
29
+ NodeArray
30
+ } from "../types/biblio.js"
19
31
  import {bulkMenuModel, menuModel} from "./menu.js"
20
32
  import {editCategoriesTemplate} from "./templates.js"
21
33
 
34
+ interface PluginExport {
35
+ new (overview: BibliographyOverview): {init: () => Promise<unknown> | void}
36
+ name: string
37
+ }
38
+
39
+ type BibPlugin = [string, Record<string, PluginExport>]
40
+
22
41
  export class BibliographyOverview {
23
- constructor({app, user}, bibPlugins = defaultBibPlugins) {
42
+ app: BibliographyApp
43
+ user: Record<string, unknown>
44
+ bibPlugins: BibPlugin[]
45
+ lastSort: {column: number; dir: "asc" | "desc"}
46
+ dom!: HTMLElement
47
+ overviewTable?: OverviewDataTable
48
+ table?: DataTable
49
+ dtBulk?: DatatableBulk
50
+ menu?: OverviewMenuView
51
+ plugins?: Record<string, {init: () => Promise<unknown> | void}>
52
+
53
+ constructor(
54
+ {app, user}: {app: BibliographyApp; user: Record<string, unknown>},
55
+ bibPlugins: BibPlugin[] = defaultBibPlugins as BibPlugin[]
56
+ ) {
24
57
  this.app = app
25
58
  this.user = user
26
59
  this.bibPlugins = bibPlugins
@@ -31,12 +64,15 @@ export class BibliographyOverview {
31
64
  /** Bind the init function to doc loading.
32
65
  * @function bind
33
66
  */
34
- init() {
67
+ init(): Promise<void> {
35
68
  return whenReady().then(() => {
36
69
  this.render()
37
70
  const smenu = new SiteMenu(this.app, "bibliography")
38
71
  smenu.init()
39
- this.menu = new OverviewMenuView(this, menuModel)
72
+ this.menu = new OverviewMenuView(
73
+ this,
74
+ menuModel as () => OverviewMenuModel
75
+ )
40
76
  this.menu.init()
41
77
  this.setBibCategoryList(this.app.bibDB.cats)
42
78
  this.initTable(Object.keys(this.app.bibDB.db))
@@ -48,7 +84,7 @@ export class BibliographyOverview {
48
84
  })
49
85
  }
50
86
 
51
- render() {
87
+ render(): void {
52
88
  this.dom = document.createElement("body")
53
89
  this.dom.innerHTML = baseBodyTemplate({
54
90
  contents: "",
@@ -67,7 +103,7 @@ export class BibliographyOverview {
67
103
  feedbackTab.init()
68
104
  }
69
105
 
70
- onResize() {
106
+ onResize(): void {
71
107
  if (!this.table) {
72
108
  return
73
109
  }
@@ -75,18 +111,18 @@ export class BibliographyOverview {
75
111
  }
76
112
 
77
113
  /* Initialize the overview table */
78
- initTable(ids) {
114
+ initTable(ids: string[]): void {
79
115
  if (this.overviewTable) {
80
116
  this.overviewTable.destroy()
81
- this.overviewTable = null
117
+ this.overviewTable = undefined
82
118
  }
83
- this.table = null
84
- this.dtBulk = null
119
+ this.table = undefined
120
+ this.dtBulk = undefined
85
121
 
86
- const contentsEl = this.dom.querySelector(".fw-contents")
122
+ const contentsEl = this.dom.querySelector(".fw-contents") as HTMLElement
87
123
  contentsEl.innerHTML = ""
88
124
 
89
- const hiddenCols = [0]
125
+ const hiddenCols: number[] = [0]
90
126
 
91
127
  if (window.innerWidth < 500) {
92
128
  hiddenCols.push(1)
@@ -124,8 +160,8 @@ export class BibliographyOverview {
124
160
  data: ids.map(id => this.createTableRow(id)),
125
161
  idColumn: 0,
126
162
  checkboxColumn: 1,
127
- bulkMenu: bulkMenuModel(),
128
- bulkMenuPage: this,
163
+ bulkMenu: bulkMenuModel() as unknown as ContentMenuInit,
164
+ bulkMenuPage: this as Record<string, unknown>,
129
165
  searchable: true,
130
166
  scrollY: `${Math.max(window.innerHeight - 360, 100)}px`,
131
167
  tabIndex: 1,
@@ -146,19 +182,22 @@ export class BibliographyOverview {
146
182
  `<div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : ""}></div>`,
147
183
  rowRender: (row, tr, _index) => {
148
184
  const id = row.cells[0].data
149
- const inputNode = {
185
+ const inputNode: {
186
+ nodeName: string
187
+ attributes: Record<string, string | boolean | number>
188
+ } = {
150
189
  nodeName: "input",
151
190
  attributes: {
152
191
  type: "checkbox",
153
192
  class: "entry-select fw-check",
154
- "data-id": id,
193
+ "data-id": id as number,
155
194
  id: `bib-${id}`
156
195
  }
157
196
  }
158
197
  if (row.cells[1].data) {
159
198
  inputNode.attributes.checked = true
160
199
  }
161
- tr.childNodes[0].childNodes = [
200
+ ;(tr as {childNodes: {childNodes: unknown[]}[]}).childNodes[0].childNodes = [
162
201
  inputNode,
163
202
  {
164
203
  nodeName: "label",
@@ -172,22 +211,22 @@ export class BibliographyOverview {
172
211
  if (this.getSelected().length > 0) {
173
212
  return
174
213
  }
175
- const rowIndex = this.table.data.data.indexOf(row)
176
- const editButton = this.table.dom.querySelector(
214
+ const rowIndex = this.table!.data.data.indexOf(row as never)
215
+ const editButton = this.table!.dom.querySelector(
177
216
  `tr[data-index="${rowIndex}"] span.edit-bib`
178
217
  )
179
218
  if (editButton) {
180
- editButton.click()
219
+ ;(editButton as HTMLElement).click()
181
220
  }
182
221
  },
183
222
  onDelete: row => {
184
- const bibId = row.cells[0].data
223
+ const bibId = row.cells[0].data as number
185
224
  this.deleteBibEntryDialog([bibId])
186
225
  }
187
226
  })
188
227
  this.overviewTable.init()
189
- this.table = this.overviewTable.table
190
- this.table.id = "bibliography"
228
+ this.table = this.overviewTable.table as DataTable
229
+ ;(this.table as unknown as {id: string}).id = "bibliography"
191
230
  this.dtBulk = this.overviewTable.dtBulk
192
231
 
193
232
  this.table.on("datatable.sort", (column, dir) => {
@@ -201,75 +240,79 @@ export class BibliographyOverview {
201
240
  * @function setBibCategoryList
202
241
  * @param newBibCategories The new categories which will be added to the existing ones.
203
242
  */
204
- setBibCategoryList(bibCategories) {
205
- const catSelector = this.menu.model.content.find(
243
+ setBibCategoryList(bibCategories: BibCategory[]): void {
244
+ const catSelector = this.menu!.model.content.find(
206
245
  menuItem => menuItem.id === "cat_selector"
207
246
  )
208
- catSelector.content = catSelector.content.filter(
209
- cat => cat.type !== "category"
210
- )
247
+ if (!catSelector) {
248
+ return
249
+ }
250
+ const dropdown = catSelector as {
251
+ content: {type?: string; title?: string; action?: unknown}[]
252
+ }
253
+ dropdown.content = dropdown.content.filter(cat => cat.type !== "category")
211
254
 
212
- catSelector.content = catSelector.content.concat(
255
+ dropdown.content = dropdown.content.concat(
213
256
  bibCategories.map(cat => ({
214
257
  title: cat.category_title,
215
258
  type: "category",
216
- action: _overview => {
259
+ action: (_overview: BibliographyOverview) => {
217
260
  const trs = this.dom.querySelectorAll(
218
261
  "#bibliography > tbody > tr"
219
262
  )
220
263
  trs.forEach(tr => {
264
+ const titleEl = tr.querySelector(".fw-data-table-title")
221
265
  if (
222
- tr
223
- .querySelector(".fw-data-table-title")
224
- .classList.contains(`cat_${cat.id}`)
266
+ titleEl &&
267
+ titleEl.classList.contains(`cat_${cat.id}`)
225
268
  ) {
226
- tr.style.display = ""
269
+ ;(tr as HTMLElement).style.display = ""
227
270
  } else {
228
- tr.style.display = "none"
271
+ ;(tr as HTMLElement).style.display = "none"
229
272
  }
230
273
  })
231
274
  }
232
275
  }))
233
276
  )
234
- this.menu.update()
277
+ this.menu!.update()
235
278
  }
236
279
 
237
280
  /** This takes a list of new bib entries and adds them to BibDB and the bibliography table
238
281
  * @function updateTable
239
282
  */
240
- updateTable(ids) {
283
+ updateTable(ids: number[]): void {
241
284
  // Remove items that already exist
242
285
  this.removeTableRows(ids)
243
- this.table.insert({data: ids.map(id => this.createTableRow(id))})
286
+ this.table!.insert({data: ids.map(id => this.createTableRow(id))})
244
287
  // Redo last sort
245
- this.table.columns.sort(this.lastSort.column, this.lastSort.dir)
288
+ this.table!.columns.sort(this.lastSort.column, this.lastSort.dir)
246
289
  }
247
290
 
248
- createTableRow(id) {
249
- const bibInfo = this.app.bibDB.db[id]
291
+ createTableRow(id: string | number): (string | number | boolean)[] {
292
+ const bibInfo = this.app.bibDB.db[id as number]
250
293
  const bibauthors = bibInfo.fields.author || bibInfo.fields.editor
251
294
  const cats = bibInfo.cats.map(cat => `cat_${cat}`)
252
295
  return [
253
- id,
296
+ id as number,
254
297
  false, // checkbox
255
298
  `<span class="fw-data-table-title ${cats.join(" ")}">
256
299
  <i class="fa fa-book"></i>
257
300
  <span class="edit-bib fw-link-text fw-searchable" data-id="${id}">
258
- ${bibInfo.fields.title?.length ? escapeText(litToText(bibInfo.fields.title)) : gettext("Untitled")}
301
+ ${(bibInfo.fields.title as NodeArray | undefined)?.length ? escapeText(litToText(bibInfo.fields.title as NodeArray)) : gettext("Untitled")}
259
302
  </span>
260
303
  ${bibInfo.entry_key ? `<small class="bib-entry-key">${escapeText(bibInfo.entry_key)}</small>` : ""}
261
304
  </span>`, // title
262
305
  getBibTypeTitle(bibInfo.bib_type), // sourcetype
263
- bibauthors ? nameToText(bibauthors) : "", // author
264
- `<span class="fw-date">${bibInfo.fields.date ? bibInfo.fields.date.replace("/", " ") : ""}</span>`, // published,
306
+ bibauthors ? nameToText(bibauthors as NameDictObject[]) : "", // author
307
+ `<span class="fw-date">${bibInfo.fields.date ? (bibInfo.fields.date as string).replace("/", " ") : ""}</span>`, // published,
265
308
  `<span class="delete-bib fw-link-text" data-id="${id}"><i class="fa fa-trash-alt"> </i></span>` // delete icon
266
309
  ]
267
310
  }
268
311
 
269
- removeTableRows(ids) {
270
- const existingRows = this.table.data.data
312
+ removeTableRows(ids: number[]): void {
313
+ const existingRows = this.table!.data.data
271
314
  .map((row, index) => {
272
- const id = row.cells[0].data
315
+ const id = row.cells[0].data as number
273
316
  if (ids.includes(id)) {
274
317
  return index
275
318
  } else {
@@ -279,14 +322,14 @@ export class BibliographyOverview {
279
322
  .filter(rowIndex => rowIndex !== false)
280
323
 
281
324
  if (existingRows.length) {
282
- this.table.rows.remove(existingRows)
325
+ this.table!.rows.remove(existingRows as number[])
283
326
  }
284
327
  }
285
328
 
286
329
  /** Opens a dialog for editing categories.
287
330
  * @function editCategoriesDialog
288
331
  */
289
- editCategoriesDialog() {
332
+ editCategoriesDialog(): void {
290
333
  if (this.app.isOffline()) {
291
334
  addAlert(
292
335
  "info",
@@ -296,20 +339,23 @@ export class BibliographyOverview {
296
339
  )
297
340
  return
298
341
  }
299
- const buttons = [
342
+ const buttons: DialogButtonSpec[] = [
300
343
  {
301
344
  text: gettext("Submit"),
302
345
  classes: "fw-dark",
303
346
  click: () => {
304
- const cats = {ids: [], titles: []}
347
+ const cats: {ids: number[]; titles: string[]} = {
348
+ ids: [],
349
+ titles: []
350
+ }
305
351
  this.dom
306
352
  .querySelectorAll("#edit-categories .category-form")
307
353
  .forEach(el => {
308
- const title = el.value.trim()
354
+ const title = (el as HTMLInputElement).value.trim()
309
355
  if (title.length) {
310
356
  cats.ids.push(
311
357
  Number.parseInt(
312
- el.getAttribute("data-id") || 0
358
+ el.getAttribute("data-id") || "0"
313
359
  )
314
360
  )
315
361
  cats.titles.push(title)
@@ -350,8 +396,8 @@ export class BibliographyOverview {
350
396
  * @function deleteBibEntryDialog
351
397
  * @param ids Ids of items that are to be deleted.
352
398
  */
353
- deleteBibEntryDialog(ids) {
354
- const buttons = [
399
+ deleteBibEntryDialog(ids: number[]): void {
400
+ const buttons: DialogButtonSpec[] = [
355
401
  {
356
402
  text: gettext("Delete"),
357
403
  classes: "fw-dark",
@@ -376,13 +422,13 @@ export class BibliographyOverview {
376
422
  }
377
423
 
378
424
  // get IDs of selected bib entries
379
- getSelected() {
425
+ getSelected(): number[] {
380
426
  return Array.from(
381
427
  this.dom.querySelectorAll(".entry-select:checked:not(:disabled)")
382
- ).map(el => Number.parseInt(el.getAttribute("data-id")))
428
+ ).map(el => Number.parseInt(el.getAttribute("data-id") || ""))
383
429
  }
384
430
 
385
- activatePlugins() {
431
+ activatePlugins(): Promise<unknown> | void {
386
432
  if (this.plugins) {
387
433
  // Plugins have been activated already
388
434
  return
@@ -398,11 +444,11 @@ export class BibliographyOverview {
398
444
  return Promise.all(
399
445
  Object.values(plugin).map(pluginExport => {
400
446
  if (typeof pluginExport === "function") {
401
- this.plugins[pluginExport.name] = new pluginExport(
447
+ this.plugins![pluginExport.name] = new pluginExport(
402
448
  this
403
449
  )
404
450
  return (
405
- this.plugins[pluginExport.name].init() ||
451
+ this.plugins![pluginExport.name].init() ||
406
452
  Promise.resolve()
407
453
  )
408
454
  }
@@ -416,7 +462,7 @@ export class BibliographyOverview {
416
462
  /** Initialize the bibliography table and bind interactive parts.
417
463
  * @function bibEvents
418
464
  */
419
- bindEvents() {
465
+ bindEvents(): void {
420
466
  this.dom.addEventListener("click", event =>
421
467
  this.handleActivation(event)
422
468
  )
@@ -426,58 +472,77 @@ export class BibliographyOverview {
426
472
 
427
473
  // Allow pasting of bibtex data.
428
474
  this.dom.addEventListener("paste", event => {
429
- if (event.target.nodeName === "INPUT") {
475
+ if ((event.target as Element).nodeName === "INPUT") {
430
476
  // We are inside of an input element, cancel.
431
477
  return false
432
478
  }
479
+ if (!event.clipboardData) {
480
+ return false
481
+ }
433
482
  const text = event.clipboardData.getData("text")
434
483
  return this.getBibtex(text)
435
484
  })
436
485
 
437
486
  // The two drag events are needed to allow dropping
438
487
  this.dom.addEventListener("dragover", event => {
439
- if (event.dataTransfer.types.includes("text/plain")) {
488
+ if (
489
+ event.dataTransfer &&
490
+ event.dataTransfer.types.includes("text/plain")
491
+ ) {
440
492
  event.preventDefault()
441
493
  }
442
494
  })
443
495
 
444
496
  this.dom.addEventListener("dragenter", event => {
445
- if (event.dataTransfer.types.includes("text/plain")) {
497
+ if (
498
+ event.dataTransfer &&
499
+ event.dataTransfer.types.includes("text/plain")
500
+ ) {
446
501
  event.preventDefault()
447
502
  }
448
503
  })
449
504
 
450
505
  // Allow dropping of bibtex data
451
506
  this.dom.addEventListener("drop", event => {
452
- if (event.target.nodeName === "INPUT") {
507
+ if ((event.target as Element).nodeName === "INPUT") {
453
508
  // We are inside of an input element, cancel.
454
509
  return false
455
510
  }
511
+ if (!event.dataTransfer) {
512
+ return false
513
+ }
456
514
  const text = fixUTF8(event.dataTransfer.getData("text"))
457
515
  return this.getBibtex(text)
458
516
  })
459
517
  }
460
518
 
461
- handleActivation(event) {
519
+ handleActivation(event: Event): void {
462
520
  if (!isActivationEvent(event)) {
463
521
  return
464
522
  }
465
- const el = {}
523
+ const el: {target?: Element | null} = {}
466
524
  switch (true) {
467
525
  case findTarget(event, ".delete-bib", el): {
468
- const bibId = Number.parseInt(el.target.dataset.id)
526
+ const bibId = Number.parseInt(
527
+ (el.target as HTMLElement).dataset.id || ""
528
+ )
469
529
  this.deleteBibEntryDialog([bibId])
470
530
  break
471
531
  }
472
532
  case findTarget(event, ".edit-bib", el): {
473
- const bibId = Number.parseInt(el.target.dataset.id)
533
+ const bibId = Number.parseInt(
534
+ (el.target as HTMLElement).dataset.id || ""
535
+ )
474
536
  import("../form/index.js").then(({BibEntryForm}) => {
475
537
  const form = new BibEntryForm(
476
538
  this.app.bibDB,
477
539
  this.app,
478
540
  bibId
479
541
  )
480
- form.init().then(idTranslations => {
542
+ form.init().then((idTranslations: IdTranslation[] | void) => {
543
+ if (!idTranslations) {
544
+ return
545
+ }
481
546
  const ids = idTranslations.map(idTrans => idTrans[1])
482
547
  return this.updateTable(ids)
483
548
  })
@@ -485,7 +550,10 @@ export class BibliographyOverview {
485
550
  break
486
551
  }
487
552
  case findTarget(event, ".fw-add-input", el): {
488
- const itemEl = el.target.closest(".fw-list-input")
553
+ const itemEl = (el.target as HTMLElement).closest(".fw-list-input")
554
+ if (!itemEl) {
555
+ break
556
+ }
489
557
  if (!itemEl.nextElementSibling) {
490
558
  itemEl.insertAdjacentHTML(
491
559
  "afterend",
@@ -497,7 +565,7 @@ export class BibliographyOverview {
497
565
  </tr>`
498
566
  )
499
567
  } else {
500
- itemEl.parentElement.removeChild(itemEl)
568
+ itemEl.parentElement!.removeChild(itemEl)
501
569
  }
502
570
  break
503
571
  }
@@ -507,7 +575,7 @@ export class BibliographyOverview {
507
575
  }
508
576
 
509
577
  // find bibtex in pasted or dropped data.
510
- getBibtex(text) {
578
+ getBibtex(text: string): boolean {
511
579
  import("../import/index.js").then(({BibliographyImporter}) => {
512
580
  const importer = new BibliographyImporter(
513
581
  text,
@@ -520,30 +588,30 @@ export class BibliographyOverview {
520
588
  return true
521
589
  }
522
590
 
523
- saveCategories(cats) {
591
+ saveCategories(cats: {ids: number[]; titles: string[]}): void {
524
592
  this.app.bibDB
525
593
  .saveCategories(cats)
526
594
  .then(bibCats => this.setBibCategoryList(bibCats))
527
595
  }
528
596
 
529
- deleteBibEntries(ids) {
597
+ deleteBibEntries(ids: number[]): void {
530
598
  this.app.bibDB
531
599
  .deleteBibEntries(ids)
532
600
  .then(ids => this.removeTableRows(ids))
533
601
  }
534
602
 
535
- close() {
603
+ close(): void {
536
604
  if (this.table) {
537
605
  this.table.destroy()
538
- this.table = null
606
+ this.table = undefined
539
607
  }
540
608
  if (this.dtBulk) {
541
609
  this.dtBulk.destroy()
542
- this.dtBulk = null
610
+ this.dtBulk = undefined
543
611
  }
544
612
  if (this.menu) {
545
613
  this.menu.destroy()
546
- this.menu = null
614
+ this.menu = undefined
547
615
  }
548
616
  }
549
617
  }
@@ -1,26 +1,28 @@
1
1
  import {BibLatexFileExporter} from "../export/index.js"
2
2
  import {BibliographyFileImportDialog} from "../import/index.js"
3
+ import type {IdTranslation} from "../types/biblio.js"
4
+ import type {BibliographyOverview} from "./index.js"
3
5
 
4
6
  export const bulkMenuModel = () => ({
5
7
  content: [
6
8
  {
7
9
  title: gettext("Delete selected"),
8
10
  tooltip: gettext("Delete selected bibliography entries."),
9
- action: overview => {
11
+ action: (overview: BibliographyOverview) => {
10
12
  const ids = overview
11
13
  .getSelected()
12
- .map(id => Number.parseInt(id))
14
+ .map(id => Number.parseInt(String(id)))
13
15
  if (ids.length) {
14
16
  overview.deleteBibEntryDialog(ids)
15
17
  }
16
18
  },
17
- disabled: overview =>
19
+ disabled: (overview: BibliographyOverview) =>
18
20
  !overview.getSelected().length || overview.app.isOffline()
19
21
  },
20
22
  {
21
23
  title: gettext("Export selected"),
22
24
  tooltip: gettext("Export selected bibliography entries."),
23
- action: overview => {
25
+ action: (overview: BibliographyOverview) => {
24
26
  const ids = overview.getSelected()
25
27
  if (ids.length) {
26
28
  const exporter = new BibLatexFileExporter(
@@ -30,7 +32,7 @@ export const bulkMenuModel = () => ({
30
32
  exporter.init()
31
33
  }
32
34
  },
33
- disabled: overview =>
35
+ disabled: (overview: BibliographyOverview) =>
34
36
  !overview.getSelected().length || overview.app.isOffline()
35
37
  }
36
38
  ]
@@ -45,11 +47,11 @@ export const menuModel = () => ({
45
47
  content: [
46
48
  {
47
49
  title: gettext("All categories"),
48
- action: _overview => {
50
+ action: (_overview: BibliographyOverview) => {
49
51
  const trs = document.querySelectorAll(
50
52
  "#bibliography > tbody > tr"
51
53
  )
52
- trs.forEach(tr => (tr.style.display = ""))
54
+ trs.forEach(tr => ((tr as HTMLElement).style.display = ""))
53
55
  }
54
56
  }
55
57
  ],
@@ -59,20 +61,23 @@ export const menuModel = () => ({
59
61
  type: "text",
60
62
  title: gettext("Edit categories"),
61
63
  keys: "Alt-e",
62
- action: overview => overview.editCategoriesDialog(),
64
+ action: (overview: BibliographyOverview) => overview.editCategoriesDialog(),
63
65
  order: 2
64
66
  },
65
67
  {
66
68
  type: "text",
67
69
  title: gettext("Register new source"),
68
70
  keys: "Alt-n",
69
- action: overview => {
71
+ action: (overview: BibliographyOverview) => {
70
72
  import("../form/index.js").then(({BibEntryForm}) => {
71
73
  const form = new BibEntryForm(
72
74
  overview.app.bibDB,
73
75
  overview.app
74
76
  )
75
- form.init().then(idTranslations => {
77
+ form.init().then((idTranslations: IdTranslation[] | void) => {
78
+ if (!idTranslations) {
79
+ return
80
+ }
76
81
  const ids = idTranslations.map(idTrans => idTrans[1])
77
82
  return overview.updateTable(ids)
78
83
  })
@@ -84,7 +89,7 @@ export const menuModel = () => ({
84
89
  type: "text",
85
90
  title: gettext("Import bibliography"),
86
91
  keys: "Alt-u",
87
- action: overview => {
92
+ action: (overview: BibliographyOverview) => {
88
93
  const fileImporter = new BibliographyFileImportDialog(
89
94
  overview.app.bibDB,
90
95
  ids => overview.updateTable(ids),
@@ -99,7 +104,8 @@ export const menuModel = () => ({
99
104
  icon: "search",
100
105
  title: gettext("Search bibliography"),
101
106
  keys: "Alt-s",
102
- input: (overview, text) => overview.table.search(text),
107
+ input: (overview: BibliographyOverview, text: string) =>
108
+ overview.table!.search(text),
103
109
  order: 5
104
110
  }
105
111
  ]
@@ -1,7 +1,8 @@
1
1
  import {escapeText} from "fwtoolkit"
2
+ import type {BibCategory} from "../types/biblio.js"
2
3
 
3
4
  /** A template for each category in the category list edit of the bibliography categories list. */
4
- const categoryFormsTemplate = ({categories}) =>
5
+ const categoryFormsTemplate = ({categories}: {categories: BibCategory[]}) =>
5
6
  `${categories
6
7
  .map(
7
8
  cat =>
@@ -22,7 +23,7 @@ const categoryFormsTemplate = ({categories}) =>
22
23
  </tr>`
23
24
 
24
25
  /** A template for the editing of bibliography categories list. */
25
- export const editCategoriesTemplate = ({categories}) =>
26
+ export const editCategoriesTemplate = ({categories}: {categories: BibCategory[]}) =>
26
27
  `<table id="editCategoryList" class="fw-dialog-table">
27
28
  <tbody>
28
29
  ${categoryFormsTemplate({categories})}
@@ -0,0 +1 @@
1
+ export const plugins: unknown[] = []
@@ -7,6 +7,7 @@ import {
7
7
  text,
8
8
  variable
9
9
  } from "./common.js"
10
+ import type {Node} from "prosemirror-model"
10
11
  import {Schema} from "prosemirror-model"
11
12
  import {marks} from "prosemirror-schema-basic"
12
13
 
@@ -16,14 +17,8 @@ const longliteral = {
16
17
  code: true,
17
18
  defining: true,
18
19
  parseDOM: [{tag: "pre.long-literal"}],
19
- toDOM(_node) {
20
- return [
21
- "pre",
22
- {
23
- class: "long-literal"
24
- },
25
- 0
26
- ]
20
+ toDOM(_node: Node) {
21
+ return ["pre", {class: "long-literal"}, 0] as const
27
22
  }
28
23
  }
29
24