mirror of https://github.com/onivim/oni.git
Feature/change token format (#1705)
* add check to return string for classname construction if only passed single word also add more token types for reasonml * add more default tokens * add css types and increase token colors * add vscode style token colors for onedark add functionality to parse the token colors format * switch oni token style to match vscode * remove convoluted ternary in flattenTheme * tweak get key from token color to match updated token style * import deepmerge avoid type issues via require.default * fix bad merge in common.ts * comment out console.log * fix lint errors * merge default and theme tokens * add types for deepmerge and ts-ignore the incorrect package * fix package json reversions * remove deepmerge create custom strategy for merging tokens * fix lint errors * update tests and fix object.entries (not available in test) * fix scope fetching in syntax reconciler and make variables more readable * fix atomic calls length check in synchronizeTokenColors * Stop inclusion of banned tokens in the syntax highlight reconciler * rank token scopes by priority and depth * separate out tokenRanking into a tokenSelector class -> single responsibility principle * refactor getMatchingToken to use recursive method * add break clause to function * fix lint errors * change test to use foeground instead of foregroundColor * fix incorrect set fontStyle in vim highlights for italics prettify comments into jsDoc blocks * fix comment for TokenScorer * add initial test for token theme provider be explicit about passing in the token colors and default to the service * fix passing in of the token colors as props explicitly this makes the component (TokenThemeProvider) more testable * refactor construct className following testing add passing jest-styled-components test * refactor constructClassname further to be more fault tolerant update jest and use test.each for classname testing * fix failing test re. checking fontsyle for bold and italic * further tweak to create Classname to further simplify its workings make get Css Rule should actually return a css rule and not occasionally a boolean * fix type annotations for getCssRule and ensure str always returned * add tokenScorer tests and improve copy for themeprovider tests
This commit is contained in:
parent
663b877202
commit
5238600911
|
@ -22,9 +22,12 @@ export const scopesToString = (scope: string[]) => {
|
|||
if (scope) {
|
||||
return scope
|
||||
.map(s => {
|
||||
const lastStop = s.lastIndexOf(".")
|
||||
const remainder = s.substring(0, lastStop)
|
||||
return remainder.replace(/\./g, "-")
|
||||
if (s.includes(".")) {
|
||||
const lastStop = s.lastIndexOf(".")
|
||||
const remainder = s.substring(0, lastStop)
|
||||
return remainder.replace(/\./g, "-")
|
||||
}
|
||||
return s
|
||||
})
|
||||
.filter(value => !!value)
|
||||
.join(" ")
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
ISyntaxHighlightState,
|
||||
ISyntaxHighlightTokenInfo,
|
||||
} from "./SyntaxHighlightingStore"
|
||||
import { TokenScorer } from "./TokenScorer"
|
||||
|
||||
import * as Selectors from "./SyntaxHighlightSelectors"
|
||||
|
||||
|
@ -26,6 +27,7 @@ import * as Selectors from "./SyntaxHighlightSelectors"
|
|||
// window and viewport
|
||||
export class SyntaxHighlightReconciler {
|
||||
private _previousState: { [line: number]: ISyntaxHighlightLineInfo } = {}
|
||||
private _tokenScorer = new TokenScorer()
|
||||
|
||||
constructor(private _editor: NeovimEditor, private _tokenColors: TokenColors) {}
|
||||
|
||||
|
@ -64,26 +66,26 @@ export class SyntaxHighlightReconciler {
|
|||
return this._previousState[line] !== latestLine
|
||||
})
|
||||
|
||||
const tokens = filteredLines.map(li => {
|
||||
const lineNumber = parseInt(li, 10)
|
||||
const tokens = filteredLines.map(currentLine => {
|
||||
const lineNumber = parseInt(currentLine, 10)
|
||||
const line = Selectors.getLineFromBuffer(currentHighlightState, lineNumber)
|
||||
|
||||
const highlights = this._mapTokensToHighlights(line.tokens)
|
||||
return {
|
||||
line: parseInt(li, 10),
|
||||
line: parseInt(currentLine, 10),
|
||||
highlights,
|
||||
}
|
||||
})
|
||||
|
||||
filteredLines.forEach(li => {
|
||||
const lineNumber = parseInt(li, 10)
|
||||
this._previousState[li] = Selectors.getLineFromBuffer(
|
||||
filteredLines.forEach(line => {
|
||||
const lineNumber = parseInt(line, 10)
|
||||
this._previousState[line] = Selectors.getLineFromBuffer(
|
||||
currentHighlightState,
|
||||
lineNumber,
|
||||
)
|
||||
})
|
||||
|
||||
if (tokens.length > 0) {
|
||||
if (tokens.length) {
|
||||
Log.verbose(
|
||||
"[SyntaxHighlightReconciler] Applying changes to " + tokens.length + " lines.",
|
||||
)
|
||||
|
@ -91,9 +93,7 @@ export class SyntaxHighlightReconciler {
|
|||
this._tokenColors.tokenColors,
|
||||
(highlightUpdater: any) => {
|
||||
tokens.forEach(token => {
|
||||
const line = token.line
|
||||
const highlights = token.highlights
|
||||
|
||||
const { line, highlights } = token
|
||||
if (Log.isDebugLoggingEnabled()) {
|
||||
Log.debug(
|
||||
"[SyntaxHighlightingReconciler] Updating tokens for line: " +
|
||||
|
@ -122,16 +122,7 @@ export class SyntaxHighlightReconciler {
|
|||
|
||||
private _getHighlightGroupFromScope(scopes: string[]): TokenColor {
|
||||
const configurationColors = this._tokenColors.tokenColors
|
||||
|
||||
for (const scope of scopes) {
|
||||
const matchingRule = configurationColors.find((c: any) => scope.indexOf(c.scope) === 0)
|
||||
|
||||
if (matchingRule) {
|
||||
// TODO: Convert to highlight group id
|
||||
return matchingRule
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
const highestRanked = this._tokenScorer.rankTokenScopes(scopes, configurationColors)
|
||||
return highestRanked
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
import { TokenColor } from "./../TokenColors"
|
||||
|
||||
interface TokenRanking {
|
||||
depth: number
|
||||
highestRankedToken: TokenColor
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the correct token to render for a particular item
|
||||
* in a line based on textmate highlighting rules
|
||||
* @name TokenScorer
|
||||
* @class
|
||||
*/
|
||||
export class TokenScorer {
|
||||
/**
|
||||
* meta tokens are not intended for syntax highlighting but for other types of plugins
|
||||
* source is a token that All items are given effectively giving it no value from the
|
||||
* point of view of syntax highlighting as it distinguishes nothing
|
||||
*
|
||||
* see: https://www.sublimetext.com/docs/3/scope_naming.html
|
||||
*/
|
||||
private _BANNED_TOKENS = ["meta", "source"]
|
||||
private readonly _SCOPE_PRIORITIES = {
|
||||
support: 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* rankTokenScopes
|
||||
* If more than one scope selector matches the current scope then they are ranked
|
||||
* according to how “good” a match they each are. The winner is the scope selector
|
||||
* which (in order of precedence):
|
||||
* 1. Match the element deepest down in the scope e.g.
|
||||
* string wins over source.php when the scope is source.php string.quoted.
|
||||
* 2. Match most of the deepest element e.g. string.quoted wins over string.
|
||||
* 3. Rules 1 and 2 applied again to the scope selector when removing the deepest element
|
||||
* (in the case of a tie), e.g. text source string wins over source string.
|
||||
*
|
||||
* Reference: https://macromates.com/manual/en/scope_selectors
|
||||
*
|
||||
* @name rankTokenScopes
|
||||
* @function
|
||||
* @param {string[]} scopes
|
||||
* @param {TokenColor[]} themeColors
|
||||
* @returns {TokenColor}
|
||||
*/
|
||||
public rankTokenScopes(scopes: string[], themeColors: TokenColor[]): TokenColor {
|
||||
const initialRanking: TokenRanking = { highestRankedToken: null, depth: null }
|
||||
const { highestRankedToken } = scopes.reduce((highestSoFar, scope) => {
|
||||
if (this._isBannedScope(scope)) {
|
||||
return highestSoFar
|
||||
}
|
||||
|
||||
const matchingToken = this._getMatchingToken(scope, themeColors)
|
||||
|
||||
if (!matchingToken) {
|
||||
return highestSoFar
|
||||
}
|
||||
|
||||
const depth = scope.split(".").length
|
||||
if (depth === highestSoFar.depth) {
|
||||
const highestPrecedence = this._determinePrecedence(
|
||||
matchingToken,
|
||||
highestSoFar.highestRankedToken,
|
||||
)
|
||||
return { highestRankedToken: highestPrecedence, depth }
|
||||
}
|
||||
if (depth > highestSoFar.depth) {
|
||||
return { highestRankedToken: matchingToken, depth }
|
||||
}
|
||||
return highestSoFar
|
||||
}, initialRanking)
|
||||
return highestRankedToken || null
|
||||
}
|
||||
|
||||
private _isBannedScope = (scope: string) => {
|
||||
return this._BANNED_TOKENS.some(token => scope.includes(token))
|
||||
}
|
||||
|
||||
private _getPriority = (token: TokenColor) => {
|
||||
const priorities = Object.keys(this._SCOPE_PRIORITIES)
|
||||
return priorities.reduce(
|
||||
(acc, priority) =>
|
||||
token.scope.includes(priority) && this._SCOPE_PRIORITIES[priority] < acc.priority
|
||||
? { priority: this._SCOPE_PRIORITIES[priority], token }
|
||||
: acc,
|
||||
{ priority: 0, token },
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign each token a priority based on `SCOPE_PRIORITIES` and then
|
||||
* sort by priority take the first aka the highest priority one
|
||||
*
|
||||
* @name _determinePrecedence
|
||||
* @function
|
||||
* @param {TokenColor[]} ...tokens
|
||||
* @returns {TokenColor}
|
||||
*/
|
||||
private _determinePrecedence(...tokens: TokenColor[]): TokenColor {
|
||||
const [{ token }] = tokens
|
||||
.map(this._getPriority)
|
||||
.sort((prev, next) => next.priority - prev.priority)
|
||||
return token
|
||||
}
|
||||
|
||||
/**
|
||||
* if the lowest scope level doesn't match then we go up one level
|
||||
* i.e. constant.numeric.special -> constant.numeric
|
||||
* and search the theme colors for a match
|
||||
*
|
||||
* @name _getMatchingToken
|
||||
* @function
|
||||
* @param {string} scope
|
||||
* @param {TokenColor[]} theme
|
||||
* @returns {TokenColor}
|
||||
*/
|
||||
private _getMatchingToken(scope: string, theme: TokenColor[]): TokenColor {
|
||||
const parts = scope.split(".")
|
||||
if (parts.length < 2) {
|
||||
return null
|
||||
}
|
||||
const matchingToken = theme.find(color => color.scope === scope)
|
||||
if (matchingToken) {
|
||||
return matchingToken
|
||||
}
|
||||
const currentScope = parts.slice(0, parts.length - 1).join(".")
|
||||
return this._getMatchingToken(currentScope, theme)
|
||||
}
|
||||
}
|
|
@ -1,44 +1,8 @@
|
|||
import * as React from "react"
|
||||
import { css, ThemeProvider, withTheme } from "styled-components"
|
||||
|
||||
import { getInstance as TokenColorsInstance, TokenColor } from "./../../Services/TokenColors"
|
||||
import { IThemeColors } from "./../../UI/components/common"
|
||||
|
||||
/**
|
||||
* Provides a check that a token exists and has valid values
|
||||
* if not it returns nothing or in the case of the foregroundColor it returns a default
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
const cssToken = (theme: INewTheme, token: string) => (property: string) => {
|
||||
try {
|
||||
const details = theme["editor.tokenColors.hoverTokens"][token]
|
||||
return details[property]
|
||||
} catch (e) {
|
||||
if (property === "foregroundColor") {
|
||||
return theme["toolTip.foreground"]
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Construct Class name is a function which takes a token
|
||||
* and returns another function which takes the theme as an argument
|
||||
* with which it creates a css class based on the token name and returns this as
|
||||
* a string
|
||||
* @returns {fn(theme) => string}
|
||||
*/
|
||||
const constructClassName = (token: string) => (theme: INewTheme) => {
|
||||
const notPunctuation = !token.includes("punctuation")
|
||||
const tokenAsClass = token.replace(/[.]/g, "-")
|
||||
const tokenStyle = cssToken(theme, token)
|
||||
const cssClass = `
|
||||
.${tokenAsClass} {
|
||||
color: ${tokenStyle("foregroundColor") || ""};
|
||||
${tokenStyle("bold") && notPunctuation ? "font-weight: bold" : ""};
|
||||
${tokenStyle("italic") ? "font-style: italic" : ""};
|
||||
}
|
||||
`
|
||||
return cssClass
|
||||
}
|
||||
import { TokenColor, TokenColorStyle } from "./../../Services/TokenColors"
|
||||
import { Css, IThemeColors } from "./../../UI/components/common"
|
||||
|
||||
/**
|
||||
* A object representing a key of default oni tokens and an array of tokens
|
||||
|
@ -46,6 +10,7 @@ const constructClassName = (token: string) => (theme: INewTheme) => {
|
|||
*/
|
||||
const defaultsToMap = {
|
||||
"variable.parameter": [
|
||||
"support",
|
||||
"support.variable",
|
||||
"support.variable.property.dom",
|
||||
"support.variable.dom",
|
||||
|
@ -56,24 +21,36 @@ const defaultsToMap = {
|
|||
"support.variable.property",
|
||||
"variable.language",
|
||||
"variable.language.this",
|
||||
"variable.function",
|
||||
"variable.parameter",
|
||||
"variable.object",
|
||||
"variable",
|
||||
"meta.object.type",
|
||||
"meta.object",
|
||||
"variable.other.readwrite",
|
||||
"variable.other.readwrite.alias",
|
||||
"constant.numeric",
|
||||
"constant.language",
|
||||
"constant.numeric.integer",
|
||||
"constant.character.escape",
|
||||
],
|
||||
"support.function": [
|
||||
"invalid",
|
||||
"function",
|
||||
"support.function",
|
||||
"entity.name",
|
||||
"entity.name.section",
|
||||
"entity.name.type",
|
||||
"entity.name.tag",
|
||||
"entity.name.type.alias",
|
||||
"entity.name.type.class",
|
||||
"entity.name.function",
|
||||
"entity.name.type.enum",
|
||||
"entity.name.type.interface",
|
||||
"entity.name.type.module",
|
||||
"entity.other.attribute.name",
|
||||
"entity.other.inherited-class",
|
||||
"entity.other.attribute.name",
|
||||
"punctuation.accessor",
|
||||
"punctuation.separator.continuation",
|
||||
"punctuation.separator.comma",
|
||||
|
@ -81,9 +58,11 @@ const defaultsToMap = {
|
|||
"punctuation.terminator",
|
||||
],
|
||||
"variable.other.constant": [
|
||||
"constant",
|
||||
"constant.language",
|
||||
"variable.other",
|
||||
"entity.other",
|
||||
"keyword",
|
||||
"keyword.package",
|
||||
"keyword.var",
|
||||
"keyword.const",
|
||||
|
@ -95,6 +74,7 @@ const defaultsToMap = {
|
|||
"keyword.operator.expression.void",
|
||||
"keyword.control.import",
|
||||
"storage.type",
|
||||
"storage.modifier",
|
||||
"storage.type.type",
|
||||
"storage.type.class",
|
||||
"storage.type.enum",
|
||||
|
@ -119,28 +99,16 @@ const defaultsToMap = {
|
|||
"string.quoted.double",
|
||||
"string.quoted.single",
|
||||
"string.quoted.triple",
|
||||
"string",
|
||||
"string.other",
|
||||
],
|
||||
}
|
||||
|
||||
const symbols = Object.values(defaultsToMap)
|
||||
.reduce((acc, a) => [...acc, ...a], [])
|
||||
.map(constructClassName)
|
||||
|
||||
type TokenFunc = (theme: INewTheme) => string
|
||||
const flattenedSymbols = (theme: INewTheme, fns: TokenFunc[]) => fns.map(fn => fn(theme)).join("\n")
|
||||
|
||||
const styles = css`
|
||||
${p => flattenedSymbols(p.theme, symbols)};
|
||||
`
|
||||
|
||||
export interface INewTheme extends IThemeColors {
|
||||
"editor.tokenColors.hoverTokens": {
|
||||
[token: string]: {
|
||||
foregroundColor: string
|
||||
backgroundColor: string
|
||||
italic: string
|
||||
bold: string
|
||||
}
|
||||
[token: string]: TokenColorStyle
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,15 +116,21 @@ interface IDefaultMap {
|
|||
[defaultTokens: string]: string[]
|
||||
}
|
||||
|
||||
interface RenderProps {
|
||||
theme: INewTheme
|
||||
styles: Css
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
render: (s: { theme: INewTheme; styles: any }) => React.ReactElement<any>
|
||||
render: (s: RenderProps) => React.ReactElement<RenderProps> | React.ReactNode
|
||||
theme: INewTheme
|
||||
defaultMap?: IDefaultMap
|
||||
tokenColors?: TokenColor[]
|
||||
}
|
||||
|
||||
interface IState {
|
||||
theme: INewTheme
|
||||
styles: string
|
||||
styles: Css
|
||||
}
|
||||
|
||||
interface IGenerateTokenArgs {
|
||||
|
@ -164,6 +138,8 @@ interface IGenerateTokenArgs {
|
|||
defaultTokens: TokenColor[]
|
||||
}
|
||||
|
||||
type Style = "bold" | "italic" | "foreground" | "background"
|
||||
|
||||
/**
|
||||
* **TokenThemeProvider** is a Render Prop
|
||||
* It is designed to be used to give UI components access to a
|
||||
|
@ -178,45 +154,54 @@ interface IGenerateTokenArgs {
|
|||
class TokenThemeProvider extends React.Component<IProps, IState> {
|
||||
public state: IState = {
|
||||
styles: null,
|
||||
theme: null,
|
||||
theme: this.props.theme,
|
||||
}
|
||||
|
||||
private tokenColors = TokenColorsInstance().tokenColors
|
||||
private enhancedTokens: TokenColor[]
|
||||
public flattenedDefaults = Object.values(defaultsToMap).reduce((acc, a) => [...acc, ...a], [])
|
||||
|
||||
public componentDidMount() {
|
||||
const editorTokens = this.createThemeFromTokens()
|
||||
this.setState({ theme: { ...this.props.theme, ...editorTokens } })
|
||||
const themeTokenNames = this.convertTokenNamesToClasses(this.props.tokenColors)
|
||||
const tokensToHightlight = [...themeTokenNames, ...this.flattenedDefaults]
|
||||
const styles = this.constructStyles(tokensToHightlight)
|
||||
const editorTokens = this.createThemeFromTokens(this.props.tokenColors)
|
||||
|
||||
const theme = { ...this.props.theme, ...editorTokens }
|
||||
this.setState({ theme, styles })
|
||||
}
|
||||
|
||||
public createThemeFromTokens() {
|
||||
if (!this.enhancedTokens) {
|
||||
this.enhancedTokens = this.generateTokens({ defaultTokens: this.tokenColors })
|
||||
}
|
||||
const tokenColorsMap = this.enhancedTokens.reduce((theme, token) => {
|
||||
return {
|
||||
...theme,
|
||||
[token.scope]: {
|
||||
...token.settings,
|
||||
},
|
||||
}
|
||||
}, {})
|
||||
public createThemeFromTokens(tokens: TokenColor[]) {
|
||||
const combinedThemeAndDefaultTokens = this.generateTokens({
|
||||
defaultTokens: this.props.tokenColors,
|
||||
})
|
||||
const tokenColorsMap = combinedThemeAndDefaultTokens.reduce(
|
||||
(theme, token) => {
|
||||
return {
|
||||
...theme,
|
||||
[token.scope]: {
|
||||
...token.settings,
|
||||
},
|
||||
}
|
||||
},
|
||||
{} as { [key: string]: TokenColorStyle },
|
||||
)
|
||||
|
||||
return { "editor.tokenColors.hoverTokens": tokenColorsMap }
|
||||
}
|
||||
|
||||
public generateTokens({ defaultMap = defaultsToMap, defaultTokens }: IGenerateTokenArgs) {
|
||||
const newTokens = Object.keys(defaultMap).reduce((acc, key) => {
|
||||
const defaultToken = this.tokenColors.find(token => token.scope === key)
|
||||
const newTokens = Object.keys(defaultMap).reduce((acc, defaultTokenName) => {
|
||||
const defaultToken = this.props.tokenColors.find(
|
||||
token => token.scope === defaultTokenName,
|
||||
)
|
||||
if (defaultToken) {
|
||||
const tokens = defaultMap[key].map(name =>
|
||||
const tokens = defaultMap[defaultTokenName].map(name =>
|
||||
this.generateSingleToken(name, defaultToken),
|
||||
)
|
||||
return [...acc, ...tokens]
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
return [...newTokens, ...this.tokenColors]
|
||||
return [...newTokens, ...this.props.tokenColors]
|
||||
}
|
||||
|
||||
public generateSingleToken(name: string, { settings }: TokenColor) {
|
||||
|
@ -226,8 +211,88 @@ class TokenThemeProvider extends React.Component<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a check that a token exists and has valid values
|
||||
* if not it returns nothing or in the case of the foregroundColor it returns a default
|
||||
* @returns {string}
|
||||
*/
|
||||
public getCssRule = (
|
||||
hoverTokens: INewTheme["editor.tokenColors.hoverTokens"],
|
||||
token: string,
|
||||
style: Style,
|
||||
) => {
|
||||
const details = hoverTokens[token]
|
||||
|
||||
if (!details) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const italicOrBold = details.fontStyle && details.fontStyle.includes(style)
|
||||
|
||||
switch (style) {
|
||||
case "italic":
|
||||
return italicOrBold ? "font-style: italic" : ""
|
||||
case "bold":
|
||||
return italicOrBold ? "font-weight: bold" : ""
|
||||
case "foreground":
|
||||
default:
|
||||
return details[style] ? `color: ${details[style]}` : ""
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Construct Class is a function which takes a token
|
||||
* and returns another function which takes the theme as an argument
|
||||
* with which it creates a css class based on the token name and returns this as a string
|
||||
* @returns {fn(theme) => string}
|
||||
*/
|
||||
public constructClassName = (token: string) => (theme: INewTheme) => {
|
||||
const tokenAsClass = token.replace(/[.]/g, "-")
|
||||
|
||||
const hoverTokens = theme["editor.tokenColors.hoverTokens"]
|
||||
|
||||
if (!hoverTokens || !(token in hoverTokens)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const foreground = this.getCssRule(hoverTokens, token, "foreground")
|
||||
const italics = this.getCssRule(hoverTokens, token, "italic")
|
||||
const bold = this.getCssRule(hoverTokens, token, "bold")
|
||||
const hasContent = foreground || italics || bold
|
||||
|
||||
if (!hasContent) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const cssClass = `
|
||||
.${tokenAsClass} {
|
||||
${bold};
|
||||
${italics};
|
||||
${foreground};
|
||||
}
|
||||
`
|
||||
return cssClass
|
||||
}
|
||||
|
||||
public convertTokenNamesToClasses = (tokenArray: TokenColor[]) => {
|
||||
const arrayOfArrays = tokenArray.map(token => token.scope)
|
||||
const names = [].concat(...arrayOfArrays)
|
||||
return names
|
||||
}
|
||||
|
||||
public constructStyles = (tokensToMap: string[] = this.flattenedDefaults) => {
|
||||
const symbols = tokensToMap.map(this.constructClassName)
|
||||
|
||||
const flattenSymbols = (theme: INewTheme, fns: TokenFunc[]) =>
|
||||
fns.map(fn => fn(theme)).join("\n")
|
||||
|
||||
const styles = css`
|
||||
${p => flattenSymbols(p.theme, symbols)};
|
||||
`
|
||||
return styles
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { theme } = this.state
|
||||
const { theme, styles } = this.state
|
||||
return (
|
||||
theme && (
|
||||
<ThemeProvider theme={theme}>{this.props.render({ theme, styles })}</ThemeProvider>
|
||||
|
|
|
@ -12,7 +12,7 @@ import { PluginManager } from "./../../Plugins/PluginManager"
|
|||
import { Configuration, configuration, GenericConfigurationValues } from "./../Configuration"
|
||||
|
||||
import * as PersistentSettings from "./../Configuration/PersistentSettings"
|
||||
import { TokenColor } from "./../TokenColors"
|
||||
import { ThemeToken, TokenColor } from "./../TokenColors"
|
||||
import { IThemeLoader, PluginThemeLoader } from "./ThemeLoader"
|
||||
|
||||
export interface IThemeColors {
|
||||
|
@ -87,7 +87,7 @@ export interface IThemeColors {
|
|||
"fileExplorer.cursor.background": string
|
||||
"fileExplorer.cursor.foreground": string
|
||||
|
||||
"editor.tokenColors": TokenColor[]
|
||||
"editor.tokenColors": ThemeToken[]
|
||||
|
||||
// LATER:
|
||||
// - Notifications?
|
||||
|
|
|
@ -11,14 +11,20 @@ import { Event, IDisposable, IEvent } from "oni-types"
|
|||
export interface TokenColor {
|
||||
scope: string
|
||||
settings: TokenColorStyle
|
||||
// private field for determining where a token came from
|
||||
_source?: string
|
||||
}
|
||||
|
||||
export interface ThemeToken {
|
||||
scope: string | string[]
|
||||
settings: TokenColorStyle
|
||||
}
|
||||
|
||||
export interface TokenColorStyle {
|
||||
foregroundColor: string
|
||||
backgroundColor: string
|
||||
foreground: string
|
||||
background: string
|
||||
|
||||
bold: boolean
|
||||
italic: boolean
|
||||
fontStyle: "bold" | "italic" | "bold italic"
|
||||
}
|
||||
|
||||
import { Configuration, IConfigurationValues } from "./Configuration"
|
||||
|
@ -65,19 +71,97 @@ export class TokenColors implements IDisposable {
|
|||
this._subscriptions = []
|
||||
}
|
||||
|
||||
private _flattenThemeTokens = (themeTokens: ThemeToken[] = []) => {
|
||||
const multidimensionalTokens = themeTokens.map(token => {
|
||||
if (Array.isArray(token.scope)) {
|
||||
return token.scope.map(s => ({
|
||||
scope: s,
|
||||
settings: token.settings,
|
||||
}))
|
||||
}
|
||||
return token
|
||||
})
|
||||
return [].concat(...multidimensionalTokens).filter(t => !!t.scope)
|
||||
}
|
||||
|
||||
private _updateTokenColors(): void {
|
||||
const tokenColorsFromTheme = this._themeManager.activeTheme
|
||||
? this._themeManager.activeTheme.tokenColors
|
||||
: []
|
||||
const {
|
||||
activeTheme: {
|
||||
colors: { "editor.tokenColors": tokenColorsFromTheme = [] },
|
||||
},
|
||||
} = this._themeManager
|
||||
|
||||
const themeTokens = this._flattenThemeTokens(tokenColorsFromTheme)
|
||||
const userColors = this._configuration.getValue("editor.tokenColors")
|
||||
this._tokenColors = [
|
||||
...(userColors || []),
|
||||
...(tokenColorsFromTheme || []),
|
||||
...this._defaultTokenColors,
|
||||
]
|
||||
|
||||
this._tokenColors = this._mergeTokenColors({
|
||||
user: userColors,
|
||||
theme: themeTokens,
|
||||
defaults: this._defaultTokenColors,
|
||||
})
|
||||
|
||||
this._onTokenColorsChangedEvent.dispatch()
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge different token source whilst unifying settings
|
||||
* each source is passed by name so that later the priority
|
||||
* for merging can be used e.g. if user source has a
|
||||
* a higher priority then conflicting settings can prefer the
|
||||
* user source
|
||||
*/
|
||||
private _mergeTokenColors(tokens: {
|
||||
user: TokenColor[]
|
||||
defaults: TokenColor[]
|
||||
theme: TokenColor[]
|
||||
}) {
|
||||
return Object.keys(tokens).reduce(
|
||||
(output, key) => {
|
||||
const tokenColors: TokenColor[] = tokens[key]
|
||||
return tokenColors.reduce((mergedTokens, currentToken) => {
|
||||
const duplicateToken = mergedTokens.find(t => currentToken.scope === t.scope)
|
||||
if (duplicateToken) {
|
||||
return mergedTokens.map(existingToken => {
|
||||
if (existingToken.scope === duplicateToken.scope) {
|
||||
return this._mergeSettings(existingToken, {
|
||||
...currentToken,
|
||||
_source: key,
|
||||
})
|
||||
}
|
||||
return existingToken
|
||||
})
|
||||
}
|
||||
return [...mergedTokens, { ...currentToken, _source: key }]
|
||||
}, output)
|
||||
},
|
||||
[] as TokenColor[],
|
||||
)
|
||||
}
|
||||
|
||||
private _mergeSettings(prev: TokenColor, next: TokenColor) {
|
||||
const priority = {
|
||||
user: 2,
|
||||
theme: 1,
|
||||
defaults: 0,
|
||||
}
|
||||
|
||||
if (priority[next._source] > priority[prev._source]) {
|
||||
return {
|
||||
...next,
|
||||
settings: {
|
||||
...prev.settings,
|
||||
...next.settings,
|
||||
},
|
||||
}
|
||||
}
|
||||
return {
|
||||
...prev,
|
||||
settings: {
|
||||
...next.settings,
|
||||
...prev.settings,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let _tokenColors: TokenColors
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as os from "os"
|
||||
|
||||
import * as React from "react"
|
||||
import styled, { boxShadowInset, css, fontSizeSmall, withProps } from "./common"
|
||||
import styled, { boxShadowInset, css, Css, fontSizeSmall, withProps } from "./common"
|
||||
|
||||
export const QuickInfoWrapper = styled.div`
|
||||
user-select: none;
|
||||
|
@ -78,7 +78,7 @@ const childStyles = css`
|
|||
`
|
||||
|
||||
interface DocProps {
|
||||
tokenStyles?: any
|
||||
tokenStyles?: Css
|
||||
}
|
||||
export const Documentation = withProps<DocProps>(styled.div)`
|
||||
${fontSizeSmall};
|
||||
|
@ -107,8 +107,9 @@ export const Documentation = withProps<DocProps>(styled.div)`
|
|||
|
||||
interface TitleProps {
|
||||
padding?: string
|
||||
tokenStyles?: any
|
||||
tokenStyles?: Css
|
||||
}
|
||||
|
||||
export const Title = withProps<TitleProps>(styled.div)`
|
||||
padding: ${p => p.padding || "0.7rem"};
|
||||
overflow: hidden;
|
||||
|
@ -143,7 +144,7 @@ export const QuickInfoContainer = withProps<{ hasDocs: boolean }>(styled.div)`
|
|||
`
|
||||
|
||||
export interface ITextProps {
|
||||
tokenStyles?: any
|
||||
tokenStyles?: Css
|
||||
padding?: string
|
||||
text?: string
|
||||
html?: {
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as React from "react"
|
|||
import { QuickInfoContainer, QuickInfoDocumentation, QuickInfoTitle } from "./QuickInfo"
|
||||
|
||||
import TokenThemeProvider from "./../../Services/SyntaxHighlighting/TokenThemeProvider"
|
||||
import { getInstance as TokenColorsInstance } from "./../../Services/TokenColors"
|
||||
|
||||
interface IQuickInfoProps {
|
||||
titleAndContents: ITitleAndContents
|
||||
|
@ -20,6 +21,7 @@ interface ITitleAndContents {
|
|||
|
||||
class QuickInfoHoverContainer extends React.Component<IQuickInfoProps> {
|
||||
public render() {
|
||||
const { tokenColors } = TokenColorsInstance()
|
||||
const { titleAndContents, isVisible } = this.props
|
||||
const hasTitle = !!(titleAndContents && titleAndContents.title.__html)
|
||||
const hasDocs =
|
||||
|
@ -33,12 +35,13 @@ class QuickInfoHoverContainer extends React.Component<IQuickInfoProps> {
|
|||
return (
|
||||
isVisible && (
|
||||
<TokenThemeProvider
|
||||
render={({ theme, styles }) => (
|
||||
tokenColors={tokenColors}
|
||||
render={({ styles }) => (
|
||||
<QuickInfoContainer hasDocs={hasDocs}>
|
||||
<QuickInfoTitle
|
||||
padding={hasDocs ? "0.5rem" : null}
|
||||
html={titleAndContents.title}
|
||||
tokenStyles={styles}
|
||||
padding={hasDocs && "0.5rem"}
|
||||
html={titleAndContents.title}
|
||||
/>
|
||||
{titleAndContents.description && (
|
||||
<QuickInfoDocumentation
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import * as Color from "color"
|
||||
import * as styledComponents from "styled-components"
|
||||
import { ThemedStyledComponentsModule, ThemeProps } from "styled-components" // tslint:disable-line no-duplicate-imports
|
||||
import {
|
||||
FlattenInterpolation,
|
||||
InterpolationValue,
|
||||
ThemedStyledComponentsModule,
|
||||
ThemeProps,
|
||||
} from "styled-components" // tslint:disable-line no-duplicate-imports
|
||||
import { IThemeColors } from "../../Services/Themes/ThemeManager"
|
||||
|
||||
export const bufferScrollBarSize = "7px"
|
||||
|
@ -16,9 +21,7 @@ const {
|
|||
IThemeColors
|
||||
>
|
||||
|
||||
export type Css =
|
||||
| styledComponents.InterpolationValue[]
|
||||
| Array<styledComponents.FlattenInterpolation<ThemeProps<IThemeColors>>>
|
||||
export type Css = InterpolationValue[] | Array<FlattenInterpolation<ThemeProps<IThemeColors>>>
|
||||
|
||||
type FlexDirection = "flex-start" | "flex-end" | "center" | "space-between"
|
||||
|
||||
|
|
|
@ -13,12 +13,14 @@ import { TokenColor } from "./../Services/TokenColors"
|
|||
|
||||
import { NeovimInstance } from "./NeovimInstance"
|
||||
|
||||
const getGuiStringFromTokenColor = (color: TokenColor): string => {
|
||||
if (color.settings.bold && color.settings.italic) {
|
||||
const getGuiStringFromTokenColor = ({ settings: { fontStyle } }: TokenColor): string => {
|
||||
if (!fontStyle) {
|
||||
return "gui=none"
|
||||
} else if (fontStyle.includes("bold italic")) {
|
||||
return "gui=bold,italic"
|
||||
} else if (color.settings.bold) {
|
||||
} else if (fontStyle === "bold") {
|
||||
return "gui=bold"
|
||||
} else if (color.settings.italic) {
|
||||
} else if (fontStyle === "italic") {
|
||||
return "gui=italic"
|
||||
} else {
|
||||
return "gui=none"
|
||||
|
@ -50,11 +52,9 @@ export class NeovimTokenColorSynchronizer {
|
|||
|
||||
const filteredHighlights = highlightsToAdd.filter(hl => !!hl)
|
||||
|
||||
const atomicCalls = filteredHighlights.map(hlCommand => {
|
||||
return ["nvim_command", [hlCommand]]
|
||||
})
|
||||
const atomicCalls = filteredHighlights.map(hlCommand => ["nvim_command", [hlCommand]])
|
||||
|
||||
if (atomicCalls.length === 0) {
|
||||
if (!atomicCalls.length) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -79,10 +79,10 @@ export class NeovimTokenColorSynchronizer {
|
|||
|
||||
private _convertTokenStyleToHighlightInfo(tokenColor: TokenColor): string {
|
||||
const name = this._getOrCreateHighlightGroup(tokenColor)
|
||||
const foregroundColor = Color(tokenColor.settings.foregroundColor).hex()
|
||||
const backgroundColor = Color(tokenColor.settings.backgroundColor).hex()
|
||||
const foregroundColor = Color(tokenColor.settings.foreground).hex()
|
||||
const backgroundColor = Color(tokenColor.settings.background).hex()
|
||||
const gui = getGuiStringFromTokenColor(tokenColor)
|
||||
return `:hi ${name} guifg=${foregroundColor} guibg=${backgroundColor} ${gui}`
|
||||
return `:hi! ${name} guifg=${foregroundColor} guibg=${backgroundColor} ${gui}`
|
||||
}
|
||||
|
||||
private _getOrCreateHighlightGroup(tokenColor: TokenColor): string {
|
||||
|
@ -106,8 +106,13 @@ export class NeovimTokenColorSynchronizer {
|
|||
}
|
||||
|
||||
private _getKeyFromTokenColor(tokenColor: TokenColor): string {
|
||||
return `${tokenColor.scope}_${tokenColor.settings.backgroundColor}_${
|
||||
tokenColor.settings.foregroundColor
|
||||
}_${tokenColor.settings.bold}_${tokenColor.settings.italic}`
|
||||
const {
|
||||
settings: { background, foreground, fontStyle },
|
||||
} = tokenColor
|
||||
const bg = `background-${background}`
|
||||
const fg = `foreground-${foreground}`
|
||||
const bold = `bold-${fontStyle && fontStyle.includes("bold")}`
|
||||
const italic = `italic-${fontStyle && fontStyle.includes("italic")}`
|
||||
return `${tokenColor.scope}_${bg}_${fg}_${bold}_${italic}`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,25 @@ export interface IVimHighlight {
|
|||
italic: boolean
|
||||
}
|
||||
|
||||
const setFontStyle = (highlight: IVimHighlight) => {
|
||||
switch (true) {
|
||||
case highlight.bold && !highlight.italic:
|
||||
return "bold"
|
||||
case !highlight.bold && highlight.italic:
|
||||
return "italic"
|
||||
case highlight.bold && highlight.italic:
|
||||
return "bold italic"
|
||||
case !highlight.bold && !highlight.italic:
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export const vimHighlightToTokenColorStyle = (highlight: IVimHighlight): TokenColorStyle => {
|
||||
return {
|
||||
foregroundColor: Color(highlight.foreground).hex(),
|
||||
backgroundColor: Color(highlight.background).hex(),
|
||||
bold: highlight.bold,
|
||||
italic: highlight.italic,
|
||||
foreground: Color(highlight.foreground).hex(),
|
||||
background: Color(highlight.background).hex(),
|
||||
fontStyle: setFontStyle(highlight),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@ describe("Markdown Conversion Functions", () => {
|
|||
assert.ok(className === "token-scope")
|
||||
})
|
||||
|
||||
it("Scopes to string fn should correctly convert single words to a className", () => {
|
||||
const className = markdown.scopesToString(["source"])
|
||||
assert.ok(className === "source")
|
||||
})
|
||||
|
||||
it("Scopes to string Should return null if passed an falsy", () => {
|
||||
const nullArg = markdown.scopesToString(null)
|
||||
assert.ok(!nullArg)
|
||||
|
|
|
@ -27,10 +27,9 @@ describe("SyntaxHighlightReconciler", () => {
|
|||
{
|
||||
scope: "scope.test",
|
||||
settings: {
|
||||
backgroundColor: COLOR_BLACK,
|
||||
foregroundColor: COLOR_WHITE,
|
||||
bold: true,
|
||||
italic: true,
|
||||
background: COLOR_BLACK,
|
||||
foreground: COLOR_WHITE,
|
||||
fontStyle: "bold italic",
|
||||
},
|
||||
},
|
||||
])
|
||||
|
@ -93,10 +92,9 @@ describe("SyntaxHighlightReconciler", () => {
|
|||
tokenColor: {
|
||||
scope: "scope.test",
|
||||
settings: {
|
||||
backgroundColor: COLOR_BLACK,
|
||||
foregroundColor: COLOR_WHITE,
|
||||
italic: true,
|
||||
bold: true,
|
||||
background: COLOR_BLACK,
|
||||
foreground: COLOR_WHITE,
|
||||
fontStyle: "bold italic",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -155,10 +153,9 @@ describe("SyntaxHighlightReconciler", () => {
|
|||
tokenColor: {
|
||||
scope: "scope.test",
|
||||
settings: {
|
||||
backgroundColor: COLOR_BLACK,
|
||||
foregroundColor: COLOR_WHITE,
|
||||
italic: true,
|
||||
bold: true,
|
||||
background: COLOR_BLACK,
|
||||
foreground: COLOR_WHITE,
|
||||
fontStyle: "bold italic",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -16,7 +16,9 @@ describe("TokenColors", () => {
|
|||
let themeManager: ThemeManager
|
||||
|
||||
beforeEach(() => {
|
||||
mockConfiguration = new MockConfiguration()
|
||||
mockConfiguration = new MockConfiguration({
|
||||
"editor.tokenColors": [{ scope: "comment", fontStyle: "bold" }],
|
||||
})
|
||||
themeLoader = new MockThemeLoader()
|
||||
themeManager = new ThemeManager(themeLoader)
|
||||
themeLoader.addTheme("testTheme", DefaultTheme)
|
||||
|
|
|
@ -12,10 +12,9 @@ import { MockNeovimInstance } from "./../Mocks/neovim"
|
|||
const createTokenColor = (scope: string): TokenColor => ({
|
||||
scope,
|
||||
settings: {
|
||||
foregroundColor: "#FFFFFF",
|
||||
backgroundColor: "#FF0000",
|
||||
bold: false,
|
||||
italic: false,
|
||||
foreground: "#FFFFFF",
|
||||
background: "#FF0000",
|
||||
fontStyle: null,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -45,6 +45,387 @@
|
|||
"highlight.mode.operator.foreground": "#282c34",
|
||||
|
||||
"highlight.mode.visual.background": "#56b6c2",
|
||||
"highlight.mode.visual.foreground": "#282c34"
|
||||
"highlight.mode.visual.foreground": "#282c34",
|
||||
"editor.tokenColors": [
|
||||
{
|
||||
"settings": {
|
||||
"background": "#282c34",
|
||||
"foreground": "#abb2bf",
|
||||
"findHighlight": "#FFE792",
|
||||
"findHighlightForeground": "#000000",
|
||||
"selectionBorder": "#222218",
|
||||
"activeGuide": "#9D550FB0",
|
||||
"bracketsForeground": "#F8F8F2A5",
|
||||
"bracketsOptions": "underline",
|
||||
"bracketContentsForeground": "#F8F8F2A5",
|
||||
"bracketContentsOptions": "underline",
|
||||
"tagsOptions": "stippled_underline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "comment",
|
||||
"settings": {
|
||||
"foreground": "#5c6370",
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Comment",
|
||||
"scope": "html.doctype",
|
||||
"settings": {
|
||||
"foreground": "#5c6370",
|
||||
"fontStyle": "italic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "String",
|
||||
"scope": "string",
|
||||
"settings": {
|
||||
"foreground": "#98c379"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Embeded String Begin and End",
|
||||
"scope": ["string.embedded.begin", "string.embedded.end"],
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Embeded String",
|
||||
"scope": "string.embedded",
|
||||
"settings": {
|
||||
"foreground": "#56b6c2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Number",
|
||||
"scope": "constant.numeric",
|
||||
"settings": {
|
||||
"foreground": "#d19a66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Built-in constant",
|
||||
"scope": "constant.language",
|
||||
"settings": {
|
||||
"foreground": "#d19a66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "User-defined constant",
|
||||
"scope": ["constant.character", "constant.other"],
|
||||
"settings": {
|
||||
"foreground": "#d19a66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Language Variable",
|
||||
"scope": "variable.language",
|
||||
"settings": {
|
||||
"foreground": "#c678dd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Variable",
|
||||
"scope": ["variable.readwrite", "variable.block", "variable.support"],
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Variable",
|
||||
"scope": "variable.readwrite.var-single-variable.js",
|
||||
"settings": {
|
||||
"foreground": "#d19a66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Variable",
|
||||
"scope": "variable.readwrite.js",
|
||||
"settings": {
|
||||
"foreground": "#abb2bf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Keyword",
|
||||
"scope": [
|
||||
"keyword",
|
||||
"keyword.operator.logical",
|
||||
"keyword.operator.constructor",
|
||||
"keyword.operator.new"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#c678dd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Keyword Operator",
|
||||
"scope": "keyword.operator",
|
||||
"settings": {
|
||||
"foreground": "#61afef"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Storage",
|
||||
"scope": "storage",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#c678dd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Storage type",
|
||||
"scope": "storage.type.function",
|
||||
"settings": {
|
||||
"foreground": "#c678dd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Class name",
|
||||
"scope": ["entity.name.class", "entity.name.module", "entity.name.type"],
|
||||
"settings": {
|
||||
"foreground": "#e5c07b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Inherited class",
|
||||
"scope": "entity.other.inherited-class",
|
||||
"settings": {
|
||||
"foreground": "#98c379"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Tag name",
|
||||
"scope": "entity.name.tag",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Tag attribute",
|
||||
"scope": "entity.other.attribute-name",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#d19a66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Function name",
|
||||
"scope": "entity.name.function",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#61afef"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Function argument",
|
||||
"scope": "variable.parameter",
|
||||
"settings": {
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Function call",
|
||||
"scope": "entity.name.function-call",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#abb2bf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Builtin Functions",
|
||||
"scope": ["function.support.builtin", "function.support.core"],
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#56b6c2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Library function",
|
||||
"scope": "support.function",
|
||||
"settings": {
|
||||
"foreground": "#56b6c2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Library constant",
|
||||
"scope": "support.constant",
|
||||
"settings": {
|
||||
"fontStyle": "",
|
||||
"foreground": "#e5c07b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Library class/type",
|
||||
"scope": "support.class",
|
||||
"settings": {
|
||||
"foreground": "#e5c07b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Library type",
|
||||
"scope": "support.type",
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Json Property",
|
||||
"scope": "support.dictionary.json",
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "StyleSheet Property name",
|
||||
"scope": [
|
||||
"support.type.property-name.css",
|
||||
"support.type.property-name.scss",
|
||||
"support.type.property-name.less",
|
||||
"support.type.property-name.sass"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#abb2bf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "StyleSheet Property value",
|
||||
"scope": [
|
||||
"support.constant.css",
|
||||
"support.constant.scss",
|
||||
"support.constant.less",
|
||||
"support.constant.sass"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#56b6c2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "StyleSheet Variable",
|
||||
"scope": ["variable.css", "variable.scss", "variable.less", "variable.sass"],
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "StyleSheet Variable String",
|
||||
"scope": [
|
||||
"variable.css.string",
|
||||
"variable.scss.string",
|
||||
"variable.less.string",
|
||||
"variable.sass.string"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#98c379"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "StyleSheet Unit",
|
||||
"scope": ["unit.css", "unit.scss", "unit.less", "unit.sass"],
|
||||
"settings": {
|
||||
"foreground": "#d19a66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "StyleSheet Function",
|
||||
"scope": ["function.css", "function.scss", "function.less", "function.sass"],
|
||||
"settings": {
|
||||
"foreground": "#56b6c2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Other variable",
|
||||
"scope": [
|
||||
"variable.other.property",
|
||||
"variable.other.object",
|
||||
"variable.other.block"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Pug/Jade Import",
|
||||
"scope": ["jade.import.variable", "pug.import.variable"],
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Invalid",
|
||||
"scope": "invalid",
|
||||
"settings": {
|
||||
"background": "#c678dd",
|
||||
"fontStyle": "",
|
||||
"foreground": "#F8F8F0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Invalid deprecated",
|
||||
"scope": "invalid.deprecated",
|
||||
"settings": {
|
||||
"background": "#56b6c2",
|
||||
"foreground": "#F8F8F0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "JSON String",
|
||||
"scope": "structure.dictionary.property-name.json",
|
||||
"settings": {
|
||||
"foreground": "#e06c75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Link",
|
||||
"scope": "string.detected-link",
|
||||
"settings": {
|
||||
"foreground": "#c678dd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.header",
|
||||
"scope": ["meta.diff", "meta.diff.header"],
|
||||
"settings": {
|
||||
"foreground": "#75715E"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.deleted",
|
||||
"scope": "markup.deleted",
|
||||
"settings": {
|
||||
"foreground": "#c678dd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.inserted",
|
||||
"scope": "markup.inserted",
|
||||
"settings": {
|
||||
"foreground": "#e5c07b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "diff.changed",
|
||||
"scope": "markup.changed",
|
||||
"settings": {
|
||||
"foreground": "#98c379"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "constant.numeric.line-number.find-in-files - match",
|
||||
"settings": {
|
||||
"foreground": "#56b6c2A0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "entity.name.filename.find-in-files",
|
||||
"settings": {
|
||||
"foreground": "#98c379"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -900,7 +900,7 @@
|
|||
"@types/enzyme": "^3.1.8",
|
||||
"@types/fs-extra": "^5.0.2",
|
||||
"@types/highlight.js": "^9.12.2",
|
||||
"@types/jest": "^22.1.3",
|
||||
"@types/jest": "^23.3.1",
|
||||
"@types/jsdom": "11.0.0",
|
||||
"@types/json5": "^0.0.29",
|
||||
"@types/lodash": "4.14.38",
|
||||
|
@ -956,7 +956,8 @@
|
|||
"innosetup-compiler": "5.5.9",
|
||||
"istanbul-api": "^1.2.1",
|
||||
"istanbul-lib-coverage": "^1.1.1",
|
||||
"jest": "^23.2.0",
|
||||
"jest": "^23.5.0",
|
||||
"jest-styled-components": "^6.1.1",
|
||||
"jsdom": "11.0.0",
|
||||
"less": "2.7.1",
|
||||
"less-loader": "^4.1.0",
|
||||
|
|
|
@ -45,7 +45,7 @@ export const settings = {
|
|||
{
|
||||
scope: "variable.other",
|
||||
settings: {
|
||||
foregroundColor: "#00FF00",
|
||||
foreground: "#00FF00",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
import { TokenScorer } from "./../browser/src/Services/SyntaxHighlighting/TokenScorer"
|
||||
import { TokenColor } from "./../browser/src/Services/TokenColors"
|
||||
|
||||
describe("TokenScorer Tests", () => {
|
||||
const ranker = new TokenScorer()
|
||||
const theme: TokenColor[] = [
|
||||
{
|
||||
scope: "entity",
|
||||
settings: {
|
||||
foreground: "blue",
|
||||
background: "red",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: "entity.name",
|
||||
settings: {
|
||||
foreground: "blue",
|
||||
background: "red",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: "entity.name.interface",
|
||||
settings: {
|
||||
foreground: "blue",
|
||||
background: "red",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: "entity.name.interface.golang",
|
||||
settings: {
|
||||
foreground: "blue",
|
||||
background: "red",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
},
|
||||
]
|
||||
it("should correctly rank tokens based on how deep in the syntax tree they are", () => {
|
||||
const scopes = ["entity.name", "entity.name.interface", "entity.name.interface.golang"]
|
||||
const highest = ranker.rankTokenScopes(scopes, theme)
|
||||
expect(highest).toEqual({
|
||||
scope: "entity.name.interface.golang",
|
||||
settings: {
|
||||
foreground: "blue",
|
||||
background: "red",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("should only return a token that is included in the theme aka one that can be highlighted", () => {
|
||||
const scopes = [
|
||||
"entity.name",
|
||||
"entity.name.interface",
|
||||
"entity.name.interface.golang",
|
||||
"item.class.component.element.object",
|
||||
]
|
||||
const highest = ranker.rankTokenScopes(scopes, theme)
|
||||
expect(highest.scope).toBe("entity.name.interface.golang")
|
||||
})
|
||||
|
||||
it('should correctly prioritise fields with higher scope priorities like "support" ', () => {
|
||||
const scopes = [
|
||||
"entity.name",
|
||||
"entity.name.interface",
|
||||
"entity.name.interface.golang",
|
||||
"support.class.component.element",
|
||||
]
|
||||
const supportTheme: TokenColor[] = [
|
||||
...theme,
|
||||
{
|
||||
scope: "support.class.component.element",
|
||||
settings: {
|
||||
foreground: "blue",
|
||||
background: "red",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const highest = ranker.rankTokenScopes(scopes, supportTheme)
|
||||
expect(highest).toEqual({
|
||||
scope: "support.class.component.element",
|
||||
settings: {
|
||||
foreground: "blue",
|
||||
background: "red",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("should return null if none of the scopes it is passed have any matches", () => {
|
||||
const highest = ranker.rankTokenScopes(["testing.failure"], theme)
|
||||
expect(highest).toBeFalsy()
|
||||
})
|
||||
|
||||
it("should ignore banned scopes like meta", () => {
|
||||
const highest = ranker.rankTokenScopes(
|
||||
["meta.long.token.name", "source.other.long.name"],
|
||||
theme,
|
||||
)
|
||||
expect(highest).toBeFalsy()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,74 @@
|
|||
import * as React from "react"
|
||||
import { mount } from "enzyme"
|
||||
import "jest-styled-components"
|
||||
|
||||
import TokenThemeProvider from "./../browser/src/Services/SyntaxHighlighting/TokenThemeProvider"
|
||||
import { TokenColor } from "./../browser/src/Services/TokenColors"
|
||||
import styled, { css } from "./../browser/src/UI/components/common"
|
||||
|
||||
const tokenColors: TokenColor[] = [
|
||||
{
|
||||
scope: "string.quoted",
|
||||
settings: {
|
||||
foreground: "green",
|
||||
background: "blue",
|
||||
fontStyle: "bold italic",
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: "entity.name.struct",
|
||||
settings: {
|
||||
foreground: "rebeccapurple",
|
||||
background: "orange",
|
||||
fontStyle: "italic",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const TestComponent = styled<{ tokenStyles: any }, "div">("div")`
|
||||
${p => p.tokenStyles};
|
||||
`
|
||||
|
||||
describe("<TokenThemeProvider />", () => {
|
||||
const theme = {
|
||||
"editor.background": "black",
|
||||
"editor.foreground": "white",
|
||||
"menu.background": "green",
|
||||
"menu.foreground": "grey",
|
||||
}
|
||||
|
||||
const component = (
|
||||
<TokenThemeProvider
|
||||
theme={theme}
|
||||
tokenColors={tokenColors}
|
||||
render={props => (
|
||||
<TestComponent tokenStyles={props.styles}>
|
||||
<span className="string-quoted">test text</span>
|
||||
</TestComponent>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
|
||||
it("should render without crashing", () => {
|
||||
const wrapper = mount(component)
|
||||
expect(wrapper.length).toBe(1)
|
||||
})
|
||||
|
||||
test.each`
|
||||
className | cssRule | result
|
||||
${".string-quoted"} | ${"color"} | ${"green"}
|
||||
${".string-quoted"} | ${"font-style"} | ${"italic"}
|
||||
${".string-quoted"} | ${"font-weight"}| ${"bold"}
|
||||
${".entity-name-struct"} | ${"color"} | ${"rebeccapurple"}
|
||||
${".entity-name-struct"} | ${"font-style"} | ${"italic"}
|
||||
${".entity-name-struct"} | ${"font-weight"}| ${undefined}
|
||||
`(
|
||||
"the TokenThemeProvider returns a nested class rule with a style of $cssRule with a value of $result for $className",
|
||||
({ cssRule, result, className }) => {
|
||||
const wrapper = mount(component)
|
||||
expect(wrapper.find(TestComponent)).toHaveStyleRule(cssRule, result, {
|
||||
modifier: className,
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
386
yarn.lock
386
yarn.lock
|
@ -120,9 +120,9 @@
|
|||
version "9.12.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.3.tgz#b672cfaac25cbbc634a0fd92c515f66faa18dbca"
|
||||
|
||||
"@types/jest@^22.1.3":
|
||||
version "22.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-22.1.3.tgz#25da391935e6fac537551456f077ce03144ec168"
|
||||
"@types/jest@^23.3.1":
|
||||
version "23.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.1.tgz#a4319aedb071d478e6f407d1c4578ec8156829cf"
|
||||
|
||||
"@types/jsdom@11.0.0":
|
||||
version "11.0.0"
|
||||
|
@ -751,6 +751,10 @@ atob@^2.0.0:
|
|||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.0.tgz#ab2b150e51d7b122b9efc8d7340c06b6c41076bc"
|
||||
|
||||
atob@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
|
||||
atob@~1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773"
|
||||
|
@ -1018,6 +1022,13 @@ babel-jest@^23.2.0:
|
|||
babel-plugin-istanbul "^4.1.6"
|
||||
babel-preset-jest "^23.2.0"
|
||||
|
||||
babel-jest@^23.4.2:
|
||||
version "23.4.2"
|
||||
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.4.2.tgz#f276de67798a5d68f2d6e87ff518c2f6e1609877"
|
||||
dependencies:
|
||||
babel-plugin-istanbul "^4.1.6"
|
||||
babel-preset-jest "^23.2.0"
|
||||
|
||||
babel-messages@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
|
||||
|
@ -2911,6 +2922,15 @@ css@^2.0.0:
|
|||
source-map-resolve "^0.3.0"
|
||||
urix "^0.1.0"
|
||||
|
||||
css@^2.2.1:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
source-map "^0.6.1"
|
||||
source-map-resolve "^0.5.2"
|
||||
urix "^0.1.0"
|
||||
|
||||
cssesc@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
|
||||
|
@ -3925,17 +3945,6 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
|
|||
dependencies:
|
||||
homedir-polyfill "^1.0.1"
|
||||
|
||||
expect@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/expect/-/expect-23.2.0.tgz#53a7e135e36fe27e75867b1178ff08aaacc2b0dd"
|
||||
dependencies:
|
||||
ansi-styles "^3.2.0"
|
||||
jest-diff "^23.2.0"
|
||||
jest-get-type "^22.1.0"
|
||||
jest-matcher-utils "^23.2.0"
|
||||
jest-message-util "^23.2.0"
|
||||
jest-regex-util "^23.0.0"
|
||||
|
||||
expect@^23.3.0:
|
||||
version "23.3.0"
|
||||
resolved "https://registry.yarnpkg.com/expect/-/expect-23.3.0.tgz#ecb051adcbdc40ac4db576c16067f12fdb13cc61"
|
||||
|
@ -3947,6 +3956,17 @@ expect@^23.3.0:
|
|||
jest-message-util "^23.3.0"
|
||||
jest-regex-util "^23.3.0"
|
||||
|
||||
expect@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/expect/-/expect-23.5.0.tgz#18999a0eef8f8acf99023fde766d9c323c2562ed"
|
||||
dependencies:
|
||||
ansi-styles "^3.2.0"
|
||||
jest-diff "^23.5.0"
|
||||
jest-get-type "^22.1.0"
|
||||
jest-matcher-utils "^23.5.0"
|
||||
jest-message-util "^23.4.0"
|
||||
jest-regex-util "^23.3.0"
|
||||
|
||||
express@^4.16.2:
|
||||
version "4.16.3"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
|
||||
|
@ -5215,6 +5235,12 @@ invariant@^2.0.0, invariant@^2.1.0, invariant@^2.2.2:
|
|||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
invariant@^2.2.4:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
invert-kv@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
|
||||
|
@ -5734,15 +5760,15 @@ isurl@^1.0.0-alpha5:
|
|||
has-to-string-tag-x "^1.2.0"
|
||||
is-object "^1.0.1"
|
||||
|
||||
jest-changed-files@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.2.0.tgz#a145a6e4b66d0129fc7c99cee134dc937a643d9c"
|
||||
jest-changed-files@^23.4.2:
|
||||
version "23.4.2"
|
||||
resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83"
|
||||
dependencies:
|
||||
throat "^4.0.0"
|
||||
|
||||
jest-cli@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.2.0.tgz#3b543a3da5145dd8937931017282379fc696c45b"
|
||||
jest-cli@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.5.0.tgz#d316b8e34a38a610a1efc4f0403d8ef8a55e4492"
|
||||
dependencies:
|
||||
ansi-escapes "^3.0.0"
|
||||
chalk "^2.0.1"
|
||||
|
@ -5755,22 +5781,22 @@ jest-cli@^23.2.0:
|
|||
istanbul-lib-coverage "^1.2.0"
|
||||
istanbul-lib-instrument "^1.10.1"
|
||||
istanbul-lib-source-maps "^1.2.4"
|
||||
jest-changed-files "^23.2.0"
|
||||
jest-config "^23.2.0"
|
||||
jest-environment-jsdom "^23.2.0"
|
||||
jest-changed-files "^23.4.2"
|
||||
jest-config "^23.5.0"
|
||||
jest-environment-jsdom "^23.4.0"
|
||||
jest-get-type "^22.1.0"
|
||||
jest-haste-map "^23.2.0"
|
||||
jest-message-util "^23.2.0"
|
||||
jest-regex-util "^23.0.0"
|
||||
jest-resolve-dependencies "^23.2.0"
|
||||
jest-runner "^23.2.0"
|
||||
jest-runtime "^23.2.0"
|
||||
jest-snapshot "^23.2.0"
|
||||
jest-util "^23.2.0"
|
||||
jest-validate "^23.2.0"
|
||||
jest-watcher "^23.2.0"
|
||||
jest-haste-map "^23.5.0"
|
||||
jest-message-util "^23.4.0"
|
||||
jest-regex-util "^23.3.0"
|
||||
jest-resolve-dependencies "^23.5.0"
|
||||
jest-runner "^23.5.0"
|
||||
jest-runtime "^23.5.0"
|
||||
jest-snapshot "^23.5.0"
|
||||
jest-util "^23.4.0"
|
||||
jest-validate "^23.5.0"
|
||||
jest-watcher "^23.4.0"
|
||||
jest-worker "^23.2.0"
|
||||
micromatch "^3.1.10"
|
||||
micromatch "^2.3.11"
|
||||
node-notifier "^5.2.1"
|
||||
prompts "^0.1.9"
|
||||
realpath-native "^1.0.0"
|
||||
|
@ -5799,23 +5825,24 @@ jest-config@^23.0.0:
|
|||
jest-validate "^23.3.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-config@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.2.0.tgz#d2fb556fd5a2a19c39eb56d139dcca5dad2a1c88"
|
||||
jest-config@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.5.0.tgz#3770fba03f7507ee15f3b8867c742e48f31a9773"
|
||||
dependencies:
|
||||
babel-core "^6.0.0"
|
||||
babel-jest "^23.2.0"
|
||||
babel-jest "^23.4.2"
|
||||
chalk "^2.0.1"
|
||||
glob "^7.1.1"
|
||||
jest-environment-jsdom "^23.2.0"
|
||||
jest-environment-node "^23.2.0"
|
||||
jest-environment-jsdom "^23.4.0"
|
||||
jest-environment-node "^23.4.0"
|
||||
jest-get-type "^22.1.0"
|
||||
jest-jasmine2 "^23.2.0"
|
||||
jest-regex-util "^23.0.0"
|
||||
jest-resolve "^23.2.0"
|
||||
jest-util "^23.2.0"
|
||||
jest-validate "^23.2.0"
|
||||
pretty-format "^23.2.0"
|
||||
jest-jasmine2 "^23.5.0"
|
||||
jest-regex-util "^23.3.0"
|
||||
jest-resolve "^23.5.0"
|
||||
jest-util "^23.4.0"
|
||||
jest-validate "^23.5.0"
|
||||
micromatch "^2.3.11"
|
||||
pretty-format "^23.5.0"
|
||||
|
||||
jest-diff@^23.2.0:
|
||||
version "23.2.0"
|
||||
|
@ -5826,6 +5853,15 @@ jest-diff@^23.2.0:
|
|||
jest-get-type "^22.1.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-diff@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.5.0.tgz#250651a433dd0050290a07642946cc9baaf06fba"
|
||||
dependencies:
|
||||
chalk "^2.0.1"
|
||||
diff "^3.2.0"
|
||||
jest-get-type "^22.1.0"
|
||||
pretty-format "^23.5.0"
|
||||
|
||||
jest-docblock@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7"
|
||||
|
@ -5839,13 +5875,12 @@ jest-each@^23.2.0:
|
|||
chalk "^2.0.1"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-environment-jsdom@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.2.0.tgz#3634603a08a975b0ca8a658320f56a54a8e04558"
|
||||
jest-each@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.5.0.tgz#77f7e2afe6132a80954b920006e78239862b10ba"
|
||||
dependencies:
|
||||
jest-mock "^23.2.0"
|
||||
jest-util "^23.2.0"
|
||||
jsdom "^11.5.1"
|
||||
chalk "^2.0.1"
|
||||
pretty-format "^23.5.0"
|
||||
|
||||
jest-environment-jsdom@^23.3.0:
|
||||
version "23.3.0"
|
||||
|
@ -5855,12 +5890,13 @@ jest-environment-jsdom@^23.3.0:
|
|||
jest-util "^23.3.0"
|
||||
jsdom "^11.5.1"
|
||||
|
||||
jest-environment-node@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.2.0.tgz#b6fe41372e382093bb6f3d9bdf6c1c4ec0a50f18"
|
||||
jest-environment-jsdom@^23.4.0:
|
||||
version "23.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023"
|
||||
dependencies:
|
||||
jest-mock "^23.2.0"
|
||||
jest-util "^23.2.0"
|
||||
jest-util "^23.4.0"
|
||||
jsdom "^11.5.1"
|
||||
|
||||
jest-environment-node@^23.3.0:
|
||||
version "23.3.0"
|
||||
|
@ -5869,38 +5905,30 @@ jest-environment-node@^23.3.0:
|
|||
jest-mock "^23.2.0"
|
||||
jest-util "^23.3.0"
|
||||
|
||||
jest-environment-node@^23.4.0:
|
||||
version "23.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10"
|
||||
dependencies:
|
||||
jest-mock "^23.2.0"
|
||||
jest-util "^23.4.0"
|
||||
|
||||
jest-get-type@^22.1.0:
|
||||
version "22.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.1.0.tgz#4e90af298ed6181edc85d2da500dbd2753e0d5a9"
|
||||
|
||||
jest-haste-map@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.2.0.tgz#d10cbac007c695948c8ef1821a2b2ed2d4f2d4d8"
|
||||
jest-haste-map@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.5.0.tgz#d4ca618188bd38caa6cb20349ce6610e194a8065"
|
||||
dependencies:
|
||||
fb-watchman "^2.0.0"
|
||||
graceful-fs "^4.1.11"
|
||||
invariant "^2.2.4"
|
||||
jest-docblock "^23.2.0"
|
||||
jest-serializer "^23.0.1"
|
||||
jest-worker "^23.2.0"
|
||||
micromatch "^3.1.10"
|
||||
micromatch "^2.3.11"
|
||||
sane "^2.0.0"
|
||||
|
||||
jest-jasmine2@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.2.0.tgz#aa670cdb1e4d5f8ec774c94dda5e105fe33d8bb4"
|
||||
dependencies:
|
||||
chalk "^2.0.1"
|
||||
co "^4.6.0"
|
||||
expect "^23.2.0"
|
||||
is-generator-fn "^1.0.0"
|
||||
jest-diff "^23.2.0"
|
||||
jest-each "^23.2.0"
|
||||
jest-matcher-utils "^23.2.0"
|
||||
jest-message-util "^23.2.0"
|
||||
jest-snapshot "^23.2.0"
|
||||
jest-util "^23.2.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-jasmine2@^23.3.0:
|
||||
version "23.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.3.0.tgz#a8706baac23c8a130d5aa8ef5464a9d49096d1b5"
|
||||
|
@ -5917,11 +5945,28 @@ jest-jasmine2@^23.3.0:
|
|||
jest-util "^23.3.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-leak-detector@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.2.0.tgz#c289d961dc638f14357d4ef96e0431ecc1aa377d"
|
||||
jest-jasmine2@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.5.0.tgz#05fe7f1788e650eeb5a03929e6461ea2e9f3db53"
|
||||
dependencies:
|
||||
pretty-format "^23.2.0"
|
||||
babel-traverse "^6.0.0"
|
||||
chalk "^2.0.1"
|
||||
co "^4.6.0"
|
||||
expect "^23.5.0"
|
||||
is-generator-fn "^1.0.0"
|
||||
jest-diff "^23.5.0"
|
||||
jest-each "^23.5.0"
|
||||
jest-matcher-utils "^23.5.0"
|
||||
jest-message-util "^23.4.0"
|
||||
jest-snapshot "^23.5.0"
|
||||
jest-util "^23.4.0"
|
||||
pretty-format "^23.5.0"
|
||||
|
||||
jest-leak-detector@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.5.0.tgz#14ac2a785bd625160a2ea968fd5d98b7dcea3e64"
|
||||
dependencies:
|
||||
pretty-format "^23.5.0"
|
||||
|
||||
jest-matcher-utils@^23.2.0:
|
||||
version "23.2.0"
|
||||
|
@ -5931,15 +5976,13 @@ jest-matcher-utils@^23.2.0:
|
|||
jest-get-type "^22.1.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-message-util@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.2.0.tgz#591e8148fff69cf89b0414809c721756ebefe744"
|
||||
jest-matcher-utils@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.5.0.tgz#0e2ea67744cab78c9ab15011c4d888bdd3e49e2a"
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0-beta.35"
|
||||
chalk "^2.0.1"
|
||||
micromatch "^3.1.10"
|
||||
slash "^1.0.0"
|
||||
stack-utils "^1.0.1"
|
||||
jest-get-type "^22.1.0"
|
||||
pretty-format "^23.5.0"
|
||||
|
||||
jest-message-util@^23.3.0:
|
||||
version "23.3.0"
|
||||
|
@ -5951,24 +5994,30 @@ jest-message-util@^23.3.0:
|
|||
slash "^1.0.0"
|
||||
stack-utils "^1.0.1"
|
||||
|
||||
jest-message-util@^23.4.0:
|
||||
version "23.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f"
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0-beta.35"
|
||||
chalk "^2.0.1"
|
||||
micromatch "^2.3.11"
|
||||
slash "^1.0.0"
|
||||
stack-utils "^1.0.1"
|
||||
|
||||
jest-mock@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134"
|
||||
|
||||
jest-regex-util@^23.0.0:
|
||||
version "23.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.0.0.tgz#dd5c1fde0c46f4371314cf10f7a751a23f4e8f76"
|
||||
|
||||
jest-regex-util@^23.3.0:
|
||||
version "23.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5"
|
||||
|
||||
jest-resolve-dependencies@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.2.0.tgz#6df8d5709c6406639cd07f54bff074e01b5c0458"
|
||||
jest-resolve-dependencies@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.5.0.tgz#10c4d135beb9d2256de1fedc7094916c3ad74af7"
|
||||
dependencies:
|
||||
jest-regex-util "^23.0.0"
|
||||
jest-snapshot "^23.2.0"
|
||||
jest-regex-util "^23.3.0"
|
||||
jest-snapshot "^23.5.0"
|
||||
|
||||
jest-resolve@^23.2.0:
|
||||
version "23.2.0"
|
||||
|
@ -5978,27 +6027,35 @@ jest-resolve@^23.2.0:
|
|||
chalk "^2.0.1"
|
||||
realpath-native "^1.0.0"
|
||||
|
||||
jest-runner@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.2.0.tgz#0d91967ea82f72b0c705910926086d2055ce75af"
|
||||
jest-resolve@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.5.0.tgz#3b8e7f67e84598f0caf63d1530bd8534a189d0e6"
|
||||
dependencies:
|
||||
browser-resolve "^1.11.3"
|
||||
chalk "^2.0.1"
|
||||
realpath-native "^1.0.0"
|
||||
|
||||
jest-runner@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.5.0.tgz#570f7a044da91648b5bb9b6baacdd511076c71d7"
|
||||
dependencies:
|
||||
exit "^0.1.2"
|
||||
graceful-fs "^4.1.11"
|
||||
jest-config "^23.2.0"
|
||||
jest-config "^23.5.0"
|
||||
jest-docblock "^23.2.0"
|
||||
jest-haste-map "^23.2.0"
|
||||
jest-jasmine2 "^23.2.0"
|
||||
jest-leak-detector "^23.2.0"
|
||||
jest-message-util "^23.2.0"
|
||||
jest-runtime "^23.2.0"
|
||||
jest-util "^23.2.0"
|
||||
jest-haste-map "^23.5.0"
|
||||
jest-jasmine2 "^23.5.0"
|
||||
jest-leak-detector "^23.5.0"
|
||||
jest-message-util "^23.4.0"
|
||||
jest-runtime "^23.5.0"
|
||||
jest-util "^23.4.0"
|
||||
jest-worker "^23.2.0"
|
||||
source-map-support "^0.5.6"
|
||||
throat "^4.0.0"
|
||||
|
||||
jest-runtime@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.2.0.tgz#62dcb01766a1c4c64696dc090209e76ce1aadcbc"
|
||||
jest-runtime@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.5.0.tgz#eb503525a196dc32f2f9974e3482d26bdf7b63ce"
|
||||
dependencies:
|
||||
babel-core "^6.0.0"
|
||||
babel-plugin-istanbul "^4.1.6"
|
||||
|
@ -6007,15 +6064,15 @@ jest-runtime@^23.2.0:
|
|||
exit "^0.1.2"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
graceful-fs "^4.1.11"
|
||||
jest-config "^23.2.0"
|
||||
jest-haste-map "^23.2.0"
|
||||
jest-message-util "^23.2.0"
|
||||
jest-regex-util "^23.0.0"
|
||||
jest-resolve "^23.2.0"
|
||||
jest-snapshot "^23.2.0"
|
||||
jest-util "^23.2.0"
|
||||
jest-validate "^23.2.0"
|
||||
micromatch "^3.1.10"
|
||||
jest-config "^23.5.0"
|
||||
jest-haste-map "^23.5.0"
|
||||
jest-message-util "^23.4.0"
|
||||
jest-regex-util "^23.3.0"
|
||||
jest-resolve "^23.5.0"
|
||||
jest-snapshot "^23.5.0"
|
||||
jest-util "^23.4.0"
|
||||
jest-validate "^23.5.0"
|
||||
micromatch "^2.3.11"
|
||||
realpath-native "^1.0.0"
|
||||
slash "^1.0.0"
|
||||
strip-bom "3.0.0"
|
||||
|
@ -6026,17 +6083,6 @@ jest-serializer@^23.0.1:
|
|||
version "23.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165"
|
||||
|
||||
jest-snapshot@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.2.0.tgz#c7a3d017177bbad60c8a595869cf90a8782e6a7e"
|
||||
dependencies:
|
||||
chalk "^2.0.1"
|
||||
jest-diff "^23.2.0"
|
||||
jest-matcher-utils "^23.2.0"
|
||||
mkdirp "^0.5.1"
|
||||
natural-compare "^1.4.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-snapshot@^23.3.0:
|
||||
version "23.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.3.0.tgz#fc4e9f81e45432d10507e27f50bce60f44d81424"
|
||||
|
@ -6053,18 +6099,26 @@ jest-snapshot@^23.3.0:
|
|||
pretty-format "^23.2.0"
|
||||
semver "^5.5.0"
|
||||
|
||||
jest-util@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.2.0.tgz#62b770757696d96e094a04b8f1c373ca50a5ab2e"
|
||||
jest-snapshot@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.5.0.tgz#cc368ebd8513e1175e2a7277f37a801b7358ae79"
|
||||
dependencies:
|
||||
callsites "^2.0.0"
|
||||
babel-types "^6.0.0"
|
||||
chalk "^2.0.1"
|
||||
graceful-fs "^4.1.11"
|
||||
is-ci "^1.0.10"
|
||||
jest-message-util "^23.2.0"
|
||||
jest-diff "^23.5.0"
|
||||
jest-matcher-utils "^23.5.0"
|
||||
jest-message-util "^23.4.0"
|
||||
jest-resolve "^23.5.0"
|
||||
mkdirp "^0.5.1"
|
||||
slash "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
natural-compare "^1.4.0"
|
||||
pretty-format "^23.5.0"
|
||||
semver "^5.5.0"
|
||||
|
||||
jest-styled-components@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-styled-components/-/jest-styled-components-6.1.1.tgz#2b9b6e3ded212b43ea71df72e82d55b856e9d1ed"
|
||||
dependencies:
|
||||
css "^2.2.1"
|
||||
|
||||
jest-util@^23.3.0:
|
||||
version "23.3.0"
|
||||
|
@ -6079,14 +6133,18 @@ jest-util@^23.3.0:
|
|||
slash "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
jest-validate@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.2.0.tgz#67c8b909e11af1701765238894c67ac3291b195e"
|
||||
jest-util@^23.4.0:
|
||||
version "23.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561"
|
||||
dependencies:
|
||||
callsites "^2.0.0"
|
||||
chalk "^2.0.1"
|
||||
jest-get-type "^22.1.0"
|
||||
leven "^2.1.0"
|
||||
pretty-format "^23.2.0"
|
||||
graceful-fs "^4.1.11"
|
||||
is-ci "^1.0.10"
|
||||
jest-message-util "^23.4.0"
|
||||
mkdirp "^0.5.1"
|
||||
slash "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
jest-validate@^23.3.0:
|
||||
version "23.3.0"
|
||||
|
@ -6097,9 +6155,18 @@ jest-validate@^23.3.0:
|
|||
leven "^2.1.0"
|
||||
pretty-format "^23.2.0"
|
||||
|
||||
jest-watcher@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.2.0.tgz#678e852896e919e9d9a0eb4b8baf1ae279620ea9"
|
||||
jest-validate@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.5.0.tgz#f5df8f761cf43155e1b2e21d6e9de8a2852d0231"
|
||||
dependencies:
|
||||
chalk "^2.0.1"
|
||||
jest-get-type "^22.1.0"
|
||||
leven "^2.1.0"
|
||||
pretty-format "^23.5.0"
|
||||
|
||||
jest-watcher@^23.4.0:
|
||||
version "23.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c"
|
||||
dependencies:
|
||||
ansi-escapes "^3.0.0"
|
||||
chalk "^2.0.1"
|
||||
|
@ -6111,12 +6178,12 @@ jest-worker@^23.2.0:
|
|||
dependencies:
|
||||
merge-stream "^1.0.1"
|
||||
|
||||
jest@^23.2.0:
|
||||
version "23.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest/-/jest-23.2.0.tgz#828bf31a096d45dcf06824d1ea03013af7bcfc20"
|
||||
jest@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jest/-/jest-23.5.0.tgz#80de353d156ea5ea4a7332f7962ac79135fbc62e"
|
||||
dependencies:
|
||||
import-local "^1.0.0"
|
||||
jest-cli "^23.2.0"
|
||||
jest-cli "^23.5.0"
|
||||
|
||||
jmespath@0.15.0:
|
||||
version "0.15.0"
|
||||
|
@ -8327,6 +8394,13 @@ pretty-format@^23.2.0:
|
|||
ansi-regex "^3.0.0"
|
||||
ansi-styles "^3.2.0"
|
||||
|
||||
pretty-format@^23.5.0:
|
||||
version "23.5.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.5.0.tgz#0f9601ad9da70fe690a269cd3efca732c210687c"
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
ansi-styles "^3.2.0"
|
||||
|
||||
pretty-quick@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-1.5.0.tgz#304853ece7f8cb56bec74ba3ccd978037e7f2117"
|
||||
|
@ -9649,6 +9723,16 @@ source-map-resolve@^0.5.0:
|
|||
source-map-url "^0.4.0"
|
||||
urix "^0.1.0"
|
||||
|
||||
source-map-resolve@^0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"
|
||||
dependencies:
|
||||
atob "^2.1.1"
|
||||
decode-uri-component "^0.2.0"
|
||||
resolve-url "^0.2.1"
|
||||
source-map-url "^0.4.0"
|
||||
urix "^0.1.0"
|
||||
|
||||
source-map-support@^0.4.15:
|
||||
version "0.4.18"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
|
||||
|
|
Loading…
Reference in New Issue