@@ -2,8 +2,6 @@ let flock;
22//let fontFamily = "Asap";
33let fontFamily = "Atkinson Hyperlegible Next" ;
44
5- import sanitizeHtml from "sanitize-html" ;
6-
75export function setFlockReference ( ref ) {
86 flock = ref ;
97}
@@ -157,35 +155,30 @@ export const flockUI = {
157155 textColor,
158156 backgroundColor,
159157 id = null ,
160- mode = "AWAIT" , // "START" or "AWAIT"
158+ mode = "AWAIT" ,
161159 } = { } ) {
162160 if ( ! flock . scene || ! flock . GUI ) {
163161 throw new Error ( "flock.scene or flock.GUI is not initialized." ) ;
164162 }
165-
166163 flock . scene . UITexture ??=
167164 flock . GUI . AdvancedDynamicTexture . CreateFullscreenUI ( "UI" ) ;
168165
169- const inputId =
170- id || `input_${ Date . now ( ) } _${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } ` ;
171- const submitId = `submit_${ inputId } ` ;
172-
173- // Sanitization Helper
174- const sanitize = ( val ) => {
175- if ( typeof val !== "string" ) return "" ;
176- const withoutHtml = sanitizeHtml ( val , {
177- allowedTags : [ ] ,
178- allowedAttributes : { } ,
179- } ) ;
180- return withoutHtml
181- . replace (
182- / [ ^ \w \s \? \. \, \! \@ \# \$ \% \^ \& \* \( \) \- \+ \= \[ \] \{ \} \: \; \x22 \x27 \/ ] / gi,
183- "" ,
184- ) // Basic char filter
185- . trim ( ) ;
166+ const sanitize = ( val , { maxLen = 500 } = { } ) => {
167+ if ( val == null ) return "" ;
168+ let s = String ( val ) ;
169+ s = s . normalize ( 'NFKC' ) ;
170+ const doc = new DOMParser ( ) . parseFromString ( s , "text/html" ) ;
171+ s = doc . body . textContent || "" ;
172+ s = s . replace ( / [ \u0000 - \u0008 \u000B \u000C \u000E - \u001F \u007F - \u009F ] / g, "" ) ;
173+ s = s . replace ( / \s + / g, " " ) . trim ( ) ;
174+ if ( s . length > maxLen ) s = s . slice ( 0 , maxLen ) ;
175+ return s ;
186176 } ;
187177
188- // Cleanup existing controls with same ID
178+ const inputId = id ? sanitize ( id , { maxLen : 100 } ) :
179+ `input_${ Date . now ( ) } _${ crypto . randomUUID ( ) } ` ;
180+ const submitId = `submit_${ inputId } ` ;
181+
189182 const existingInput = flock . scene . UITexture . getControlByName ( inputId ) ;
190183 const existingSubmit = flock . scene . UITexture . getControlByName ( submitId ) ;
191184 if ( existingInput ) existingInput . dispose ( ) ;
@@ -196,17 +189,14 @@ export const flockUI = {
196189 MEDIUM : { width : "300px" , height : "50px" } ,
197190 LARGE : { width : "400px" , height : "60px" } ,
198191 } ;
199-
200- const resolvedSize =
201- sizeMap [ ( size || "" ) . toUpperCase ( ) ] || sizeMap [ "MEDIUM" ] ;
192+ const resolvedSize = sizeMap [ ( size || "" ) . toUpperCase ( ) ] || sizeMap [ "MEDIUM" ] ;
202193 const inputWidth = resolvedSize . width ;
203194 const inputHeight = resolvedSize . height ;
204195 const buttonWidth = "50px" ;
205196 const spacing = 10 ;
206197
207- // Create input box
208198 const input = new flock . GUI . InputText ( inputId ) ;
209- input . placeholderText = text ;
199+ input . placeholderText = sanitize ( text ) ;
210200 input . width = inputWidth ;
211201 input . height = inputHeight ;
212202 input . color = textColor || "black" ;
@@ -215,27 +205,22 @@ export const flockUI = {
215205 input . fontSize = fontSize || 24 ;
216206 input . text = "" ;
217207
218- // Original Positioning Logic
219208 input . left = `${ x } px` ;
220209 input . top = `${ y } px` ;
221- input . horizontalAlignment =
222- x < 0
223- ? flock . GUI . Control . HORIZONTAL_ALIGNMENT_RIGHT
224- : flock . GUI . Control . HORIZONTAL_ALIGNMENT_LEFT ;
225- input . verticalAlignment =
226- y < 0
227- ? flock . GUI . Control . VERTICAL_ALIGNMENT_BOTTOM
228- : flock . GUI . Control . VERTICAL_ALIGNMENT_TOP ;
210+ input . horizontalAlignment = x < 0
211+ ? flock . GUI . Control . HORIZONTAL_ALIGNMENT_RIGHT
212+ : flock . GUI . Control . HORIZONTAL_ALIGNMENT_LEFT ;
213+ input . verticalAlignment = y < 0
214+ ? flock . GUI . Control . VERTICAL_ALIGNMENT_BOTTOM
215+ : flock . GUI . Control . VERTICAL_ALIGNMENT_TOP ;
229216
230- // Create submit button
231217 const button = flock . GUI . Button . CreateSimpleButton ( submitId , "✓" ) ;
232218 button . width = buttonWidth ;
233219 button . height = inputHeight ;
234220 button . color = backgroundColor || "gray" ;
235221 button . background = textColor || "white" ;
236222 button . fontSize = fontSize || 24 ;
237223
238- // Handle button offset based on alignment
239224 const offset = parseInt ( inputWidth ) + spacing ;
240225 button . left = x < 0 ? `${ x - offset } px` : `${ x + offset } px` ;
241226 button . top = `${ y } px` ;
@@ -249,17 +234,14 @@ export const flockUI = {
249234 return inputId ;
250235 }
251236
252- // Await mode
253237 return new Promise ( ( resolve ) => {
254238 const submit = ( ) => {
255239 const cleanValue = sanitize ( input . text ) ;
256240 input . dispose ( ) ;
257241 button . dispose ( ) ;
258242 resolve ( cleanValue ) ;
259243 } ;
260-
261244 button . onPointerUpObservable . add ( submit ) ;
262-
263245 input . onKeyboardEventProcessedObservable . add ( ( event ) => {
264246 if ( event . type === "keydown" && event . key === "Enter" ) {
265247 submit ( ) ;
0 commit comments