1+ /**
2+ * Utility functions for various common tasks.
3+ *
4+ * version 2.0 - 2025.06.03
5+ * upgrade Vue component registration to Vue3 and Vue.defineAsyncComponent
6+ *
7+ * This file contains a collection of utility functions that can be used for:
8+ * - String formatting
9+ * - DOM manipulation
10+ * - AJAX requests
11+ * - Cookie handling
12+ * - Vue component registration
13+ * - File upload handling
14+ * - Internationalization
15+ * - Debouncing and throttling functions
16+ * - Password strength calculation
17+ * - Form handling
18+ * - Flash message handling
19+ */
20+
121"use strict" ;
222
3- // Allows "bla {a} bla {b}".format({'a': 'hello', 'b': 'world'})
23+ /**
24+ * Allows "bla {a} bla {b}".format({'a': 'hello', 'b': 'world'})
25+ * @param {Object } args - The arguments to replace in the string.
26+ * @returns {String } - The formatted string.
27+ */
428if ( ! String . prototype . format ) {
529 String . prototype . format = function ( args ) {
630 return this . replace ( / \{ ( [ ^ } ] + ) \} / g, function ( match , k ) { return args [ k ] ; } ) ;
@@ -10,12 +34,20 @@ if (!String.prototype.format) {
1034// Similar to jQuery $ but lighter
1135window . Q = function ( sel , el ) { return ( el || document ) . querySelectorAll ( sel ) ; } ;
1236
13- // Clone any object
37+ /**
38+ * Clone any object
39+ * @param {Object } data - The object to clone.
40+ * @returns {Object } - The cloned object.
41+ */
1442Q . clone = function ( data ) { return JSON . parse ( JSON . stringify ( data ) ) ; } ;
1543
1644Q . eval = function ( text ) { return eval ( '(' + text + ')' ) ; } ;
1745
18- // Given a url retuns an object with parsed query string
46+ /**
47+ * Given a URL returns an object with parsed query string
48+ * @param {String } source - The URL to parse.
49+ * @returns {Object } - The parsed query string as an object.
50+ */
1951Q . get_query = function ( source ) {
2052 source = source || window . location . search . substring ( 1 ) ;
2153 var vars = { } , items = source . split ( '&' ) ;
@@ -26,7 +58,14 @@ Q.get_query = function (source) {
2658 return vars ;
2759} ;
2860
29- // a wrapper for fetch return a promise
61+ /**
62+ * A wrapper for fetch that returns a promise
63+ * @param {String } method - The HTTP method.
64+ * @param {String } url - The URL to fetch.
65+ * @param {Object } data - The data to send.
66+ * @param {Object } headers - The headers to include.
67+ * @returns {Promise } - The fetch promise.
68+ */
3069Q . ajax = function ( method , url , data , headers ) {
3170 var options = {
3271 method : method ,
@@ -55,18 +94,24 @@ Q.post = (url, data, headers) => Q.ajax("POST", url, data, headers);
5594Q . put = ( url , data , headers ) => Q . ajax ( "PUT" , url , data , headers ) ;
5695Q . delete = ( url , headers ) => Q . ajax ( "DELETE" , url , null , headers ) ;
5796
58- // Gets a cookie value
97+ /**
98+ * Gets a cookie value
99+ * @param {String } name - The name of the cookie.
100+ * @returns {String|null } - The cookie value or null if not found.
101+ */
59102Q . get_cookie = function ( name ) {
60103 var cookie = RegExp ( "" + name + "[^;]+" ) . exec ( document . cookie ) ;
61104 if ( ! cookie ) return null ;
62105 return decodeURIComponent ( ! ! cookie ? cookie . toString ( ) . replace ( / ^ [ ^ = ] + ./ , "" ) : "" ) ;
63106} ;
64107
65- // Load components lazily: https://vuejs.org/v2/ guide/components .html#Async-Components
108+ // Load components lazily: https://v3. vuejs.org/guide/component-dynamic-async .html#async-components
66109Q . register_vue_component = function ( name , src , onload ) {
67- Vue . component ( name , function ( resolve , reject ) {
68- Q . ajax ( 'GET' , src ) . then ( function ( res ) { resolve ( onload ( res ) ) ; } ) ;
110+ window . app . component ( name , Vue . defineAsyncComponent ( ( ) => {
111+ return Q . ajax ( 'GET' , src ) . then ( function ( res ) {
112+ return onload ( res ) ;
69113 } ) ;
114+ } ) ) ;
70115} ;
71116
72117// Passes binary data to callback on drop of file in elem_id
@@ -88,10 +133,14 @@ Q.upload_helper = function (elem_id, callback) {
88133 }
89134} ;
90135
91- // Internationalization helper
136+ /**
137+ * Internationalization helper
92138// Usage:
93139// T.translations = {'dog': {0: 'no cane', 1: 'un case', 2: '{n} cani', 10: 'tanti cani' }};
94140// T('dog').format({n: 5}) -> "5 cani"
141+ * @param {String } text - The text to translate.
142+ * @returns {Object } - The translation object with toString and format methods.
143+ */
95144var T = function ( text ) {
96145 var obj = {
97146 toString : function ( ) { return T . format ( text ) ; } ,
@@ -100,7 +149,12 @@ var T = function (text) {
100149 return obj ;
101150} ;
102151
103- // Adds a convenience format method to the client-side translator object
152+ /**
153+ * Adds a convenience format method to the client-side translator object
154+ * @param {String } text - The text to format.
155+ * @param {Object } args - The arguments for formatting.
156+ * @returns {String } - The formatted text.
157+ */
104158T . format = function ( text , args ) {
105159 args = args || { } ;
106160 translations = ( T . translations || { } ) [ text ] ;
@@ -214,7 +268,11 @@ Q.tags_input = function(elem, options) {
214268 fill ( elem , repl ) ;
215269} ;
216270
217- // Password strenght calculator
271+ /**
272+ * Password strength calculator
273+ * @param {String } text - The password text.
274+ * @returns {Number } - The password strength score.
275+ */
218276Q . score_password = function ( text ) {
219277 var score = - 10 , counters = { } ;
220278 text . split ( '' ) . map ( function ( c ) { counters [ c ] = ( counters [ c ] || 0 ) + 1 ; score += 5 / counters [ c ] ; } ) ;
@@ -310,4 +368,4 @@ Q.handle_components();
310368Q . handle_flash ( ) ;
311369Q ( 'input[type=text].type-list-string' ) . forEach ( function ( elem ) { Q . tags_input ( elem ) ; } ) ;
312370Q ( 'input[type=text].type-list-integer' ) . forEach ( function ( elem ) { Q . tags_input ( elem , { regex :/ [ - + ] ? [ \d ] + / } ) ; } ) ;
313- Q ( 'input[name=password],input[name=new_password]' ) . forEach ( Q . score_input ) ;
371+ Q ( 'input[name=password],input[name=new_password]' ) . forEach ( Q . score_input ) ;
0 commit comments