Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 17x 17x 17x 17x 17x 17x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 76x 164x 84x 84x 80x 76x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 230x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 8x 8x 8x 26x 26x 26x 14x 14x 14x 8x 133x 133x 133x 133x 133x 133x 133x 133x 133x 26x 26x 26x 22x 22x 133x 133x 133x 133x 133x 133x 133x 133x 133x 21x 21x 21x 21x 21x 21x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 133x 59x 59x 2x 2x 57x 59x 20x 20x 20x 42x 42x 20x 20x 37x 37x 59x 133x 133x 133x | /**
* WikiLambda Vue editor: miscellaneous utilities
*
* @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
* @license MIT
*/
'use strict';
const miscUtils = {
/**
* Get the text of the edit summary message for when changes are made to a Function
*
* @param {string} message The key of the message to fetch
* @param {string[]} ZIDs The ZIDs of the affected linked Implementations or Testers
* @return {string} The rendered message
*/
createConnectedItemsChangesSummaryMessage: function ( message, ZIDs ) {
// Messages that can be used here:
// * wikilambda-updated-implementations-approved-summary
// * wikilambda-updated-implementations-deactivated-summary
// * wikilambda-updated-testers-approved-summary
// * wikilambda-updated-testers-deactivated-summary
return mw.message( message ).params( [ mw.language.listToText( ZIDs ) ] ).text();
},
/**
* Safely retrieves the value of a nested property within an object.
*
* This function will not throw an error if any part of the path is `null` or `undefined`.
*
* @param {Object} obj - The object from which to retrieve the property.
* @param {string} path - The path to the desired property, specified as a string with dot notation.
* @return {string|undefined} - The value of the nested property, or `undefined`
* if any part of the path is `null` or `undefined`.
*
* @example
*
* const error = {
* error: {
* message: 'Something went wrong!'
* }
* };
*
* const message = getNestedProperty(error, 'error.message');
* console.log(message); // Output: 'Something went wrong!'
*
* const code = getNestedProperty(error, 'error.code');
* console.log(code); // Output: undefined
*
* const nonExistent = getNestedProperty(null, 'error.message');
* console.log(nonExistent); // Output: undefined
*/
getNestedProperty: function ( obj, path ) {
return path.split( '.' ).reduce( ( acc, part ) => {
if ( acc && acc[ part ] !== undefined && acc[ part ] !== null ) {
return acc[ part ];
}
return undefined;
}, obj );
},
/**
* Check if two arrays are equal.
*
* @param {Array} arr1 - The first array to compare.
* @param {Array} arr2 - The second array to compare.
* @return {boolean} - True if the arrays are equal, false otherwise.
*/
arraysAreEqual: function ( arr1, arr2 ) {
return arr1.length === arr2.length && arr1.every( ( value, index ) => value === arr2[ index ] );
},
/**
*
* Custom throttle implementation.
* Ensures a function is called at most once in the specified delay period.
*
* @param {Function} func - The function to throttle.
* @param {number} delay - The delay in milliseconds.
* @return {Function} - The throttled function.
*/
throttle: function ( func, delay ) {
let lastCall = 0;
return function ( ...args ) {
const now = Date.now();
if ( now - lastCall >= delay ) {
lastCall = now;
func.apply( this, args );
}
};
},
/**
* Helper function: parse or null
*
* @param {any} value
* @return {Object|Array|null}
*/
tryJsonParse: function ( value ) {
try {
return JSON.parse( value );
} catch ( error ) {
return null;
}
},
/**
* Computes SHA-256 hash of a string and returns it as a hex string.
*
* @param {string} input - The string to hash
* @return {Promise<string>} Promise resolving to the hex hash string
*/
sha256: async function ( input ) {
const enc = new TextEncoder();
const data = enc.encode( input );
return crypto.subtle.digest( 'SHA-256', data ).then( ( hashBuf ) => {
const hashArr = Array.from( new Uint8Array( hashBuf ) );
return hashArr.map( ( b ) => b.toString( 16 ).padStart( 2, '0' ) ).join( '' );
} );
},
/**
* Lightweight JSON standardizer. Walks a nested tree and:
* * if array, iterate through its children and recurse
* * if dictionary, order keys alphabetically and recurse
* * other types, exit and don't recurse
*
* @param {Object|Array|string} value
* @return {Object|Array|string}
*/
stabilize: function ( value ) {
// Iterate and recurse if array
if ( Array.isArray( value ) ) {
return value.map( miscUtils.stabilize );
}
// For an object, order keys and recurse
if ( value !== null && typeof value === 'object' ) {
return Object.keys( value )
.sort()
.reduce( ( acc, key ) => {
acc[ key ] = miscUtils.stabilize( value[ key ] );
return acc;
}, {} );
}
// Exit if string, number, boolean, null, undefined...
return value;
}
};
module.exports = miscUtils;
|