|  | 
| 9 | 9 |  */ | 
| 10 | 10 | 
 | 
| 11 | 11 | import {compareVersions} from 'compare-versions'; | 
| 12 |  | -import {dehydrate} from '../hydration'; | 
|  | 12 | +import {dehydrate} from 'react-devtools-shared/src/hydration'; | 
| 13 | 13 | import isArray from 'shared/isArray'; | 
| 14 | 14 | 
 | 
| 15 | 15 | import type {Source} from 'react-devtools-shared/src/shared/types'; | 
| 16 | 16 | import type {DehydratedData} from 'react-devtools-shared/src/frontend/types'; | 
| 17 | 17 | 
 | 
|  | 18 | +export {default as formatWithStyles} from './formatWithStyles'; | 
|  | 19 | +export {default as formatConsoleArguments} from './formatConsoleArguments'; | 
|  | 20 | + | 
| 18 | 21 | // TODO: update this to the first React version that has a corresponding DevTools backend | 
| 19 | 22 | const FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER = '999.9.9'; | 
| 20 | 23 | export function hasAssignedBackend(version?: string): boolean { | 
| @@ -164,125 +167,6 @@ export function serializeToString(data: any): string { | 
| 164 | 167 |   ); | 
| 165 | 168 | } | 
| 166 | 169 | 
 | 
| 167 |  | -// NOTE: KEEP IN SYNC with src/hook.js | 
| 168 |  | -// Formats an array of args with a style for console methods, using | 
| 169 |  | -// the following algorithm: | 
| 170 |  | -//     1. The first param is a string that contains %c | 
| 171 |  | -//          - Bail out and return the args without modifying the styles. | 
| 172 |  | -//            We don't want to affect styles that the developer deliberately set. | 
| 173 |  | -//     2. The first param is a string that doesn't contain %c but contains | 
| 174 |  | -//        string formatting | 
| 175 |  | -//          - [`%c${args[0]}`, style, ...args.slice(1)] | 
| 176 |  | -//          - Note: we assume that the string formatting that the developer uses | 
| 177 |  | -//            is correct. | 
| 178 |  | -//     3. The first param is a string that doesn't contain string formatting | 
| 179 |  | -//        OR is not a string | 
| 180 |  | -//          - Create a formatting string where: | 
| 181 |  | -//                 boolean, string, symbol -> %s | 
| 182 |  | -//                 number -> %f OR %i depending on if it's an int or float | 
| 183 |  | -//                 default -> %o | 
| 184 |  | -export function formatWithStyles( | 
| 185 |  | -  inputArgs: $ReadOnlyArray<any>, | 
| 186 |  | -  style?: string, | 
| 187 |  | -): $ReadOnlyArray<any> { | 
| 188 |  | -  if ( | 
| 189 |  | -    inputArgs === undefined || | 
| 190 |  | -    inputArgs === null || | 
| 191 |  | -    inputArgs.length === 0 || | 
| 192 |  | -    // Matches any of %c but not %%c | 
| 193 |  | -    (typeof inputArgs[0] === 'string' && inputArgs[0].match(/([^%]|^)(%c)/g)) || | 
| 194 |  | -    style === undefined | 
| 195 |  | -  ) { | 
| 196 |  | -    return inputArgs; | 
| 197 |  | -  } | 
| 198 |  | - | 
| 199 |  | -  // Matches any of %(o|O|d|i|s|f), but not %%(o|O|d|i|s|f) | 
| 200 |  | -  const REGEXP = /([^%]|^)((%%)*)(%([oOdisf]))/g; | 
| 201 |  | -  if (typeof inputArgs[0] === 'string' && inputArgs[0].match(REGEXP)) { | 
| 202 |  | -    return [`%c${inputArgs[0]}`, style, ...inputArgs.slice(1)]; | 
| 203 |  | -  } else { | 
| 204 |  | -    const firstArg = inputArgs.reduce((formatStr, elem, i) => { | 
| 205 |  | -      if (i > 0) { | 
| 206 |  | -        formatStr += ' '; | 
| 207 |  | -      } | 
| 208 |  | -      switch (typeof elem) { | 
| 209 |  | -        case 'string': | 
| 210 |  | -        case 'boolean': | 
| 211 |  | -        case 'symbol': | 
| 212 |  | -          return (formatStr += '%s'); | 
| 213 |  | -        case 'number': | 
| 214 |  | -          const formatting = Number.isInteger(elem) ? '%i' : '%f'; | 
| 215 |  | -          return (formatStr += formatting); | 
| 216 |  | -        default: | 
| 217 |  | -          return (formatStr += '%o'); | 
| 218 |  | -      } | 
| 219 |  | -    }, '%c'); | 
| 220 |  | -    return [firstArg, style, ...inputArgs]; | 
| 221 |  | -  } | 
| 222 |  | -} | 
| 223 |  | - | 
| 224 |  | -// NOTE: KEEP IN SYNC with src/hook.js | 
| 225 |  | -// Skips CSS and object arguments, inlines other in the first argument as a template string | 
| 226 |  | -export function formatConsoleArguments( | 
| 227 |  | -  maybeMessage: any, | 
| 228 |  | -  ...inputArgs: $ReadOnlyArray<any> | 
| 229 |  | -): $ReadOnlyArray<any> { | 
| 230 |  | -  if (inputArgs.length === 0 || typeof maybeMessage !== 'string') { | 
| 231 |  | -    return [maybeMessage, ...inputArgs]; | 
| 232 |  | -  } | 
| 233 |  | - | 
| 234 |  | -  const args = inputArgs.slice(); | 
| 235 |  | - | 
| 236 |  | -  let template = ''; | 
| 237 |  | -  let argumentsPointer = 0; | 
| 238 |  | -  for (let i = 0; i < maybeMessage.length; ++i) { | 
| 239 |  | -    const currentChar = maybeMessage[i]; | 
| 240 |  | -    if (currentChar !== '%') { | 
| 241 |  | -      template += currentChar; | 
| 242 |  | -      continue; | 
| 243 |  | -    } | 
| 244 |  | - | 
| 245 |  | -    const nextChar = maybeMessage[i + 1]; | 
| 246 |  | -    ++i; | 
| 247 |  | - | 
| 248 |  | -    // Only keep CSS and objects, inline other arguments | 
| 249 |  | -    switch (nextChar) { | 
| 250 |  | -      case 'c': | 
| 251 |  | -      case 'O': | 
| 252 |  | -      case 'o': { | 
| 253 |  | -        ++argumentsPointer; | 
| 254 |  | -        template += `%${nextChar}`; | 
| 255 |  | -
 | 
| 256 |  | -        break; | 
| 257 |  | -      } | 
| 258 |  | -      case 'd': | 
| 259 |  | -      case 'i': { | 
| 260 |  | -        const [arg] = args.splice(argumentsPointer, 1); | 
| 261 |  | -        template += parseInt(arg, 10).toString(); | 
| 262 |  | -
 | 
| 263 |  | -        break; | 
| 264 |  | -      } | 
| 265 |  | -      case 'f': { | 
| 266 |  | -        const [arg] = args.splice(argumentsPointer, 1); | 
| 267 |  | -        template += parseFloat(arg).toString(); | 
| 268 |  | -
 | 
| 269 |  | -        break; | 
| 270 |  | -      } | 
| 271 |  | -      case 's': { | 
| 272 |  | -        const [arg] = args.splice(argumentsPointer, 1); | 
| 273 |  | -        template += arg.toString(); | 
| 274 |  | -
 | 
| 275 |  | -        break; | 
| 276 |  | -      } | 
| 277 |  | -
 | 
| 278 |  | -      default: | 
| 279 |  | -        template += `%${nextChar}`; | 
| 280 |  | -    } | 
| 281 |  | -  } | 
| 282 |  | - | 
| 283 |  | -  return [template, ...args]; | 
| 284 |  | -} | 
| 285 |  | - | 
| 286 | 170 | // based on https://github.com/tmpfs/format-util/blob/0e62d430efb0a1c51448709abd3e2406c14d8401/format.js#L1 | 
| 287 | 171 | // based on https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions | 
| 288 | 172 | // Implements s, d, i and f placeholders | 
|  | 
0 commit comments