slim-select 2.9.0 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,7 +15,7 @@ Advanced select dropdown
15
15
 
16
16
  ## [Documentation and Examples](https://slimselectjs.com)
17
17
 
18
- See [website](https://slimselectjs.com) for the full list of settings, methods and event callbacks
18
+ See [website](https://slimselectjs.com) for the full list of [settings](https://slimselectjs.com/settings), [methods](https://slimselectjs.com/methods) and [event callbacks](https://slimselectjs.com/events)
19
19
 
20
20
  ![](https://raw.githubusercontent.com/brianvoe/slim-select/master/slimselect.gif)
21
21
 
@@ -152,6 +152,7 @@ new SlimSelect({
152
152
  timeoutDelay: 200,
153
153
  maxValuesShown: 20,
154
154
  maxValuesMessage: '{number} selected',
155
+ addableText: 'Press "Enter" to add {value}',
155
156
  },
156
157
  })
157
158
  ```
@@ -167,7 +168,7 @@ new SlimSelect({
167
168
  events: {
168
169
  search: (searchValue: string, currentData: DataArray) => Promise<DataArrayPartial> | DataArrayPartial
169
170
  searchFilter: (option: Option, search: string) => boolean
170
- addable: (value: string) => Promise<OptionOptional | string> | OptionOptional | string
171
+ addable: (value: string) => Promise<OptionOptional | string> | OptionOptional | string | Error
171
172
  beforeChange: (newVal: Option[], oldVal: Option[]) => boolean | void
172
173
  afterChange: (newVal: Option[]) => void
173
174
  beforeOpen: () => void
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "slim-select",
3
3
  "description": "Slim advanced select dropdown",
4
- "version": "2.9.0",
4
+ "version": "2.9.1",
5
5
  "author": "Brian Voelker <brian@webiswhatido.com> (http://webiswhatido.com)",
6
6
  "homepage": "https://slimselectjs.com",
7
7
  "license": "MIT",
@@ -53,21 +53,21 @@
53
53
  "devDependencies": {
54
54
  "@jest/globals": "^29.7.0",
55
55
  "@rollup/plugin-babel": "^6.0.4",
56
- "@rollup/plugin-commonjs": "^26.0.1",
57
- "@rollup/plugin-node-resolve": "^15.2.3",
58
- "@rollup/plugin-replace": "^5.0.7",
56
+ "@rollup/plugin-commonjs": "^28.0.0",
57
+ "@rollup/plugin-node-resolve": "^15.3.0",
58
+ "@rollup/plugin-replace": "^6.0.1",
59
59
  "@rollup/plugin-terser": "^0.4.4",
60
- "@rollup/plugin-typescript": "^11.1.6",
60
+ "@rollup/plugin-typescript": "^12.1.0",
61
61
  "@testing-library/jest-dom": "^6.5.0",
62
62
  "@testing-library/user-event": "^14.5.2",
63
63
  "@types/downloadjs": "^1.4.6",
64
- "@types/jest": "^29.5.12",
65
- "@typescript-eslint/eslint-plugin": "^8.5.0",
66
- "@typescript-eslint/parser": "^8.5.0",
67
- "@vitejs/plugin-vue": "^5.1.3",
64
+ "@types/jest": "^29.5.13",
65
+ "@typescript-eslint/eslint-plugin": "^8.8.1",
66
+ "@typescript-eslint/parser": "^8.8.1",
67
+ "@vitejs/plugin-vue": "^5.1.4",
68
68
  "clipboard": "^2.0.11",
69
69
  "downloadjs": "^1.4.7",
70
- "eslint": "^9.10.0",
70
+ "eslint": "^9.12.0",
71
71
  "eslint-config-prettier": "^9.1.0",
72
72
  "eslint-plugin-prettier": "^5.2.1",
73
73
  "identity-obj-proxy": "^3.0.0",
@@ -77,18 +77,18 @@
77
77
  "prettier": "^3.3.3",
78
78
  "prismjs": "^1.29.0",
79
79
  "rimraf": "^6.0.1",
80
- "rollup": "^4.21.2",
80
+ "rollup": "^4.24.0",
81
81
  "rollup-plugin-peer-deps-external": "^2.2.4",
82
82
  "rollup-plugin-typescript2": "^0.36.0",
83
83
  "rollup-plugin-vue": "^6.0.0",
84
- "sass": "^1.78.0",
84
+ "sass": "^1.79.5",
85
85
  "ts-jest": "^29.2.5",
86
86
  "tslib": "^2.7.0",
87
- "typescript": "^5.6.2",
88
- "vite": "^5.4.4",
89
- "vite-plugin-dts": "^4.2.1",
90
- "vue": "^3.5.4",
91
- "vue-router": "^4.4.4",
87
+ "typescript": "^5.6.3",
88
+ "vite": "^5.4.8",
89
+ "vite-plugin-dts": "^4.2.4",
90
+ "vue": "^3.5.12",
91
+ "vue-router": "^4.4.5",
92
92
  "vue-tsc": "^2.1.6",
93
93
  "vuex": "^4.0.2"
94
94
  }
@@ -72,7 +72,9 @@ export default class Render {
72
72
  this.updateAriaAttributes()
73
73
 
74
74
  // Add content to the content location settings
75
- this.settings.contentLocation.appendChild(this.content.main)
75
+ if (this.settings.contentLocation) {
76
+ this.settings.contentLocation.appendChild(this.content.main)
77
+ }
76
78
  }
77
79
 
78
80
  // Remove disabled classes
@@ -374,7 +374,7 @@ export default class Select {
374
374
  const optionEl = document.createElement('option')
375
375
  optionEl.id = info.id
376
376
  optionEl.value = info.value
377
- optionEl.innerHTML = info.text
377
+ optionEl.textContent = info.text
378
378
  if (info.html !== '') {
379
379
  optionEl.setAttribute('data-html', info.html)
380
380
  }
@@ -195,6 +195,21 @@ describe('Settings module', () => {
195
195
  expect(optionElement.dataset.html).toBe(option.html)
196
196
  })
197
197
 
198
+ test('malicious text is inserted with innerText', () => {
199
+ // decoded text: <img src=x onerror=alert(1)></img>
200
+ const str = '&#x3c;&#x69;&#x6d;&#x67;&#x20;&#x73;&#x72;&#x63;&#x3d;&#x78;&#x20;&#x6f;&#x6e;&#x65;&#x72;&#x72;&#x6f;&#x72;&#x3d;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x3e;&#x3c;&#x2f;&#x69;&#x6d;&#x67;&#x3e;'
201
+ // const str = 'opt'
202
+ const decode = (string: string|null) => {
203
+ if(string === null) return ''
204
+ const doc = new DOMParser().parseFromString(string, "text/html")
205
+ return doc.documentElement.textContent;
206
+ }
207
+ const option = new Option({ text: str })
208
+ const optionElement = select.createOption(option)
209
+ // expect(decode(optionElement.textContent)).toBe('opt')
210
+ expect(optionElement.textContent).toBe(str)
211
+ })
212
+
198
213
  test('disabled sets disabled property correctly', () => {
199
214
  const option = new Option({ text: 'opt', disabled: true })
200
215
  const optionElement = select.createOption(option)
@@ -24,7 +24,7 @@ export default class Settings {
24
24
  public searchingText: string
25
25
  public searchHighlight: boolean
26
26
  public closeOnSelect: boolean
27
- public contentLocation: HTMLElement
27
+ public contentLocation: HTMLElement | null
28
28
  public contentPosition: 'relative' | 'absolute'
29
29
  public openPosition: 'auto' | 'up' | 'down'
30
30
  public placeholderText: string
package/vite.config.mts CHANGED
@@ -3,6 +3,13 @@ import { defineConfig } from 'vite'
3
3
 
4
4
  // https://vitejs.dev/config/
5
5
  export default defineConfig({
6
+ css: {
7
+ preprocessorOptions: {
8
+ scss: {
9
+ api: 'modern-compiler' // or "modern"
10
+ }
11
+ }
12
+ },
6
13
  build: {
7
14
  outDir: 'docs',
8
15
  emptyOutDir: true,
@@ -10,9 +17,9 @@ export default defineConfig({
10
17
  output: {
11
18
  entryFileNames: `assets/[name].js`,
12
19
  chunkFileNames: `assets/[name].js`,
13
- assetFileNames: `assets/[name].[ext]`,
14
- },
15
- },
20
+ assetFileNames: `assets/[name].[ext]`
21
+ }
22
+ }
16
23
  },
17
- plugins: [vue()],
24
+ plugins: [vue()]
18
25
  })