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 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | 15x 15x 15x 15x 12x 12x 12x 101x 60x 60x 41x 41x 8x 8x 33x 33x 33x 41x 89x 12x 12x 33x 1122x 1122x 1122x 632x 632x 490x 490x 490x 1089x 33x 21x 33x 33x 21x 33x 47682x 47682x 6125557x 47682x 250x 47432x 6872x 47432x 109355x 6871x 6871x 6871x 39667x 14474x 25193x 20x 25173x 39667x 62817x 62817x 47432x 1144x 1425x 2x 1423x 82097x 1423x 43x 43x 43x 841x 841x | /*! * WikiLambda Vue tree manipulation utilities code * * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt * @license MIT */ var Constants = require( '../Constants.js' ), typeUtils = require( './typeUtils.js' ).methods, normalize = require( './schemata.js' ).methods.normalizeZObject; module.exports = exports = { methods: { /** * Convert a ZObject represented as a JS object into a flat array of * rows, where each row represents a key-value. Every row has an ID, * a key, a value and the row ID of its parent. Depending on the input * parameters, the generated array of rows will be adapted to pend from * a given parent row, or will be the whole ZObject to represent as the * global state. * * @param {Object} zObject * @param {Object} parentRow the row object from which the resulting object will pend * @param {Object} startingRowId the first available rowID in the global state table * @return {Array} */ convertZObjectToRows: function ( zObject, parentRow, startingRowId ) { // Raise an exception if parentRow is set and nextAvailableId is not to avoid overwriting IDs Iif ( parentRow && !startingRowId ) { throw new Error( 'The parameter startingRowId must be set when inserting a ZObject under a parentRow' ); } const zObjectRows = []; let nextAvailableId = startingRowId || 0; function flattenZObject( value, key, parentRowId, isExistingParent = false ) { if ( typeof value === 'string' ) { // ROW IS TERMINAL // Push a new row with its final value as 'value' zObjectRows.push( { id: nextAvailableId, key, value, parent: parentRowId } ); nextAvailableId++; } else { // ROW IS NOT TERMINAL // Push a non-terminal row with value set to either array or object // We don't push the parent if it's already a row in the zObjectTable let rowId; const type = Array.isArray( value ) ? Constants.ROW_VALUE_ARRAY : Constants.ROW_VALUE_OBJECT; if ( isExistingParent ) { // We are inserting the already existing parent with its own id, // key and parent; the only thing that may change is the value. // The calling method will have to decide whether to insert it or replace it. rowId = parentRow.id; zObjectRows.push( { id: rowId, key, value: type, parent: parentRow.parent } ); } else { rowId = nextAvailableId; zObjectRows.push( { id: rowId, key, value: type, parent: parentRowId } ); nextAvailableId++; } // And for every child, recurse with current rowId as parentRowId for ( const objectKey in value ) { flattenZObject( value[ objectKey ], objectKey, rowId ); } } } // Initial call, if there's a parent, link with key and parent id, else undefined flattenZObject( normalize( zObject ), parentRow ? parentRow.key : undefined, parentRow ? parentRow.id : undefined, !!parentRow ); return zObjectRows; }, convertZObjectToTree: function ( zObject, startingKey, startingId, startingParentId ) { var zObjectTree = []; function tranverseJson( value, key, parentId ) { var valueType = typeUtils.getZObjectType( value ), currentId = zObjectTree.length, type, objectKey; // When the node is terminal, push a new row with its final value as 'value' if ( typeof value === 'string' ) { zObjectTree.push( { id: currentId, key: key, value: value, parent: parentId } ); return; } // Else, push a new row with its type (array or object) as 'value' type = valueType === Constants.Z_TYPED_LIST ? 'array' : 'object'; zObjectTree.push( { id: currentId, key: key, value: type, parent: parentId } ); // And for every child, perform the same operation for ( objectKey in value ) { tranverseJson( value[ objectKey ], objectKey, currentId ); } } if ( startingId !== undefined ) { zObjectTree.length = startingId; } tranverseJson( normalize( zObject ), startingKey, startingParentId ); if ( startingId !== undefined ) { zObjectTree.splice( 0, startingId ); } return zObjectTree; }, convertZObjectTreetoJson: function ( zObjectTree, parentId, rootIsArray ) { function reconstructJson( object, layer, isArrayChild ) { var json = {}, value, currentElements = object.filter( function ( item ) { return item.parent === layer; } ); if ( currentElements.length === 0 && !isArrayChild ) { return; } // if array children, we need to return an array not an object if ( isArrayChild ) { json = []; } currentElements.forEach( function ( currentElement ) { switch ( currentElement.value ) { case 'array': value = reconstructJson( object, currentElement.id, true ); json[ currentElement.key ] = value; break; case 'object': if ( isArrayChild ) { json[ currentElement.key ] = reconstructJson( object, currentElement.id ); } else if ( !currentElement.key ) { json = reconstructJson( object, currentElement.id ); } else { json[ currentElement.key ] = reconstructJson( object, currentElement.id ); } break; default: json[ currentElement.key ] = currentElement.value; break; } } ); return json; } return reconstructJson( zObjectTree, parentId, rootIsArray ); }, getNextObjectId: function ( zObject ) { if ( !zObject || zObject.length === 0 ) { return 0; } const highestObjectId = Math.max( ...zObject.map( ( item ) => item.id ) ); return highestObjectId + 1; }, findLatestKey: function ( zObject, zid ) { const keyRegex = new RegExp( '^' + zid + 'K([0-9]+)$' ); const defaultKey = 0; return Math.max( defaultKey, ...zObject.map( function ( item ) { const match = item.value && item.value.match( keyRegex ); return match ? parseInt( match[ 1 ], 10 ) : -1; } ) ); } } }; |