Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
2e3dada5
Commit
2e3dada5
authored
Mar 22, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
go to file
parent
082b62ab
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
137 additions
and
7 deletions
+137
-7
ContractSourceCode.tsx
ui/address/contract/ContractSourceCode.tsx
+1
-1
CodeEditor.tsx
ui/shared/monaco/CodeEditor.tsx
+32
-6
addFileImportDecorations.ts
ui/shared/monaco/utils/addFileImportDecorations.ts
+19
-0
getFullPathOfImportedFile.test.ts
ui/shared/monaco/utils/getFullPathOfImportedFile.test.ts
+37
-0
getFullPathOfImportedFile.ts
ui/shared/monaco/utils/getFullPathOfImportedFile.ts
+42
-0
themes.ts
ui/shared/monaco/utils/themes.ts
+6
-0
No files found.
ui/address/contract/ContractSourceCode.tsx
View file @
2e3dada5
...
@@ -50,7 +50,7 @@ const ContractSourceCode = ({ data, hasSol2Yml, address, isViper, filePath, addi
...
@@ -50,7 +50,7 @@ const ContractSourceCode = ({ data, hasSol2Yml, address, isViper, filePath, addi
null
;
null
;
return
(
return
(
<
section
title=
"Source code"
>
<
section
>
<
Flex
justifyContent=
"space-between"
alignItems=
"center"
mb=
{
3
}
>
<
Flex
justifyContent=
"space-between"
alignItems=
"center"
mb=
{
3
}
>
{
heading
}
{
heading
}
{
diagramLink
}
{
diagramLink
}
...
...
ui/shared/monaco/CodeEditor.tsx
View file @
2e3dada5
import
type
{
SystemStyleObject
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
useColorMode
,
Flex
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
useColorMode
,
Flex
}
from
'
@chakra-ui/react
'
;
import
type
{
EditorProps
}
from
'
@monaco-editor/react
'
;
import
type
{
EditorProps
}
from
'
@monaco-editor/react
'
;
import
MonacoEditor
from
'
@monaco-editor/react
'
;
import
MonacoEditor
from
'
@monaco-editor/react
'
;
...
@@ -13,6 +14,8 @@ import CodeEditorBreadcrumbs from './CodeEditorBreadcrumbs';
...
@@ -13,6 +14,8 @@ import CodeEditorBreadcrumbs from './CodeEditorBreadcrumbs';
import
CodeEditorLoading
from
'
./CodeEditorLoading
'
;
import
CodeEditorLoading
from
'
./CodeEditorLoading
'
;
import
CodeEditorSideBar
,
{
CONTAINER_WIDTH
as
SIDE_BAR_WIDTH
}
from
'
./CodeEditorSideBar
'
;
import
CodeEditorSideBar
,
{
CONTAINER_WIDTH
as
SIDE_BAR_WIDTH
}
from
'
./CodeEditorSideBar
'
;
import
CodeEditorTabs
from
'
./CodeEditorTabs
'
;
import
CodeEditorTabs
from
'
./CodeEditorTabs
'
;
import
addFileImportDecorations
from
'
./utils/addFileImportDecorations
'
;
import
getFullPathOfImportedFile
from
'
./utils/getFullPathOfImportedFile
'
;
import
*
as
themes
from
'
./utils/themes
'
;
import
*
as
themes
from
'
./utils/themes
'
;
import
useThemeColors
from
'
./utils/useThemeColors
'
;
import
useThemeColors
from
'
./utils/useThemeColors
'
;
...
@@ -22,6 +25,7 @@ const EDITOR_OPTIONS: EditorProps['options'] = {
...
@@ -22,6 +25,7 @@ const EDITOR_OPTIONS: EditorProps['options'] = {
scrollbar
:
{
scrollbar
:
{
alwaysConsumeMouseWheel
:
true
,
alwaysConsumeMouseWheel
:
true
,
},
},
dragAndDrop
:
false
,
};
};
const
TABS_HEIGHT
=
35
;
const
TABS_HEIGHT
=
35
;
...
@@ -58,12 +62,13 @@ const CodeEditor = ({ data }: Props) => {
...
@@ -58,12 +62,13 @@ const CodeEditor = ({ data }: Props) => {
monaco
.
editor
.
defineTheme
(
'
blockscout-dark
'
,
themes
.
dark
);
monaco
.
editor
.
defineTheme
(
'
blockscout-dark
'
,
themes
.
dark
);
monaco
.
editor
.
setTheme
(
colorMode
===
'
light
'
?
'
blockscout-light
'
:
'
blockscout-dark
'
);
monaco
.
editor
.
setTheme
(
colorMode
===
'
light
'
?
'
blockscout-light
'
:
'
blockscout-dark
'
);
const
loadedModelsPaths
=
monaco
.
editor
.
getModels
().
map
((
model
)
=>
model
.
uri
.
path
);
const
loadedModels
=
monaco
.
editor
.
getModels
();
data
.
slice
(
1
)
const
loadedModelsPaths
=
loadedModels
.
map
((
model
)
=>
model
.
uri
.
path
);
const
newModels
=
data
.
slice
(
1
)
.
filter
((
file
)
=>
!
loadedModelsPaths
.
includes
(
file
.
file_path
))
.
filter
((
file
)
=>
!
loadedModelsPaths
.
includes
(
file
.
file_path
))
.
forEach
((
file
)
=>
{
.
map
((
file
)
=>
monaco
.
editor
.
createModel
(
file
.
source_code
,
'
sol
'
,
monaco
.
Uri
.
parse
(
file
.
file_path
)));
monaco
.
editor
.
createModel
(
file
.
source_code
,
'
sol
'
,
monaco
.
Uri
.
parse
(
file
.
file_path
));
}
);
loadedModels
.
concat
(
newModels
).
forEach
(
addFileImportDecorations
);
// componentDidMount
// componentDidMount
// eslint-disable-next-line react-hooks/exhaustive-deps
// eslint-disable-next-line react-hooks/exhaustive-deps
},
[
]);
},
[
]);
...
@@ -103,7 +108,20 @@ const CodeEditor = ({ data }: Props) => {
...
@@ -103,7 +108,20 @@ const CodeEditor = ({ data }: Props) => {
});
});
},
[
data
,
index
]);
},
[
data
,
index
]);
const
containerSx
=
React
.
useMemo
(()
=>
({
const
handleClick
=
React
.
useCallback
((
event
:
React
.
MouseEvent
)
=>
{
const
target
=
event
.
target
as
HTMLSpanElement
;
const
isImportLink
=
target
.
classList
.
contains
(
'
import-link
'
);
if
(
isImportLink
)
{
const
path
=
target
.
innerText
;
const
fullPath
=
getFullPathOfImportedFile
(
data
[
index
].
file_path
,
path
);
const
fileIndex
=
data
.
findIndex
((
file
)
=>
file
.
file_path
===
fullPath
);
if
(
fileIndex
>
-
1
)
{
handleSelectFile
(
fileIndex
);
}
}
},
[
data
,
handleSelectFile
,
index
]);
const
containerSx
:
SystemStyleObject
=
React
.
useMemo
(()
=>
({
'
.editor-container
'
:
{
'
.editor-container
'
:
{
position
:
'
absolute
'
,
position
:
'
absolute
'
,
top
:
0
,
top
:
0
,
...
@@ -114,6 +132,13 @@ const CodeEditor = ({ data }: Props) => {
...
@@ -114,6 +132,13 @@ const CodeEditor = ({ data }: Props) => {
'
.highlight
'
:
{
'
.highlight
'
:
{
backgroundColor
:
themeColors
[
'
custom.findMatchHighlightBackground
'
],
backgroundColor
:
themeColors
[
'
custom.findMatchHighlightBackground
'
],
},
},
'
.import-link
'
:
{
_hover
:
{
color
:
themeColors
[
'
custom.fileLink.hoverForeground
'
],
textDecoration
:
'
underline
'
,
cursor
:
'
pointer
'
,
},
},
}),
[
editorWidth
,
themeColors
]);
}),
[
editorWidth
,
themeColors
]);
if
(
data
.
length
===
1
)
{
if
(
data
.
length
===
1
)
{
...
@@ -140,6 +165,7 @@ const CodeEditor = ({ data }: Props) => {
...
@@ -140,6 +165,7 @@ const CodeEditor = ({ data }: Props) => {
position=
"relative"
position=
"relative"
ref=
{
containerNodeRef
}
ref=
{
containerNodeRef
}
sx=
{
containerSx
}
sx=
{
containerSx
}
onClick=
{
handleClick
}
>
>
<
Box
flexGrow=
{
1
}
>
<
Box
flexGrow=
{
1
}
>
<
CodeEditorTabs
tabs=
{
tabs
}
activeTab=
{
data
[
index
].
file_path
}
onTabSelect=
{
handleTabSelect
}
onTabClose=
{
handleTabClose
}
/>
<
CodeEditorTabs
tabs=
{
tabs
}
activeTab=
{
data
[
index
].
file_path
}
onTabSelect=
{
handleTabSelect
}
onTabClose=
{
handleTabClose
}
/>
...
...
ui/shared/monaco/utils/addFileImportDecorations.ts
0 → 100644
View file @
2e3dada5
import
type
*
as
monaco
from
'
monaco-editor/esm/vs/editor/editor.api
'
;
export
default
function
addFileImportDecorations
(
model
:
monaco
.
editor
.
ITextModel
)
{
const
matches
=
model
.
findMatches
(
'
^import "((
\\
/|
\\
.)(
\\
w|
\\
.|
\\
/|-)+)"
'
,
false
,
true
,
false
,
null
,
true
);
const
decorations
:
Array
<
monaco
.
editor
.
IModelDeltaDecoration
>
=
matches
.
map
(({
range
})
=>
({
range
:
{
...
range
,
startColumn
:
range
.
startColumn
+
8
,
endColumn
:
range
.
endColumn
-
1
,
},
options
:
{
inlineClassName
:
'
import-link
'
,
hoverMessage
:
{
value
:
'
Click to open file
'
,
},
},
}));
model
.
deltaDecorations
([],
decorations
);
}
ui/shared/monaco/utils/getFullPathOfImportedFile.test.ts
0 → 100644
View file @
2e3dada5
import
getFullPathOfImportedFile
from
'
./getFullPathOfImportedFile
'
;
it
(
'
construct correct absolute path
'
,
()
=>
{
const
result
=
getFullPathOfImportedFile
(
'
/foo/bar/baz/index.sol
'
,
'
./.././../abc/contract.sol
'
,
);
expect
(
result
).
toBe
(
'
/foo/abc/contract.sol
'
);
});
it
(
'
returns undefined if imported file is outside the base file folder
'
,
()
=>
{
const
result
=
getFullPathOfImportedFile
(
'
/index.sol
'
,
'
../../abc/contract.sol
'
,
);
expect
(
result
).
toBeUndefined
();
});
it
(
'
returns unmodified path if it is already absolute
'
,
()
=>
{
const
result
=
getFullPathOfImportedFile
(
'
/index.sol
'
,
'
/abc/contract.sol
'
,
);
expect
(
result
).
toBe
(
'
/abc/contract.sol
'
);
});
it
(
'
returns undefined for external path
'
,
()
=>
{
const
result
=
getFullPathOfImportedFile
(
'
/index.sol
'
,
'
https://github.com/ethereum/dapp/contract.sol
'
,
);
expect
(
result
).
toBeUndefined
();
});
ui/shared/monaco/utils/getFullPathOfImportedFile.ts
0 → 100644
View file @
2e3dada5
import
stripLeadingSlash
from
'
lib/stripLeadingSlash
'
;
export
default
function
getFullPathOfImportedFile
(
baseFilePath
:
string
,
importedFilePath
:
string
)
{
if
(
importedFilePath
[
0
]
===
'
/
'
)
{
return
importedFilePath
;
}
if
(
importedFilePath
[
0
]
!==
'
.
'
)
{
return
;
}
const
baseFileChunks
=
stripLeadingSlash
(
baseFilePath
).
split
(
'
/
'
);
const
importedFileChunks
=
importedFilePath
.
split
(
'
/
'
);
const
result
:
Array
<
string
>
=
baseFileChunks
.
slice
(
0
,
-
1
);
for
(
let
index
=
0
;
index
<
importedFileChunks
.
length
-
1
;
index
++
)
{
const
element
=
importedFileChunks
[
index
];
if
(
element
===
'
.
'
)
{
continue
;
}
if
(
element
===
'
..
'
)
{
if
(
result
.
length
===
0
)
{
break
;
}
result
.
pop
();
continue
;
}
result
.
push
(
element
);
}
if
(
result
.
length
===
0
)
{
return
;
}
result
.
push
(
importedFileChunks
[
importedFileChunks
.
length
-
1
]);
return
'
/
'
+
result
.
join
(
'
/
'
);
}
ui/shared/monaco/utils/themes.ts
View file @
2e3dada5
...
@@ -32,6 +32,9 @@ export const light = {
...
@@ -32,6 +32,9 @@ export const light = {
'
custom.findMatchHighlightBackground
'
:
'
rgba(234,92,0,0.33)
'
,
'
custom.findMatchHighlightBackground
'
:
'
rgba(234,92,0,0.33)
'
,
'
custom.inputOption.activeBackground
'
:
'
rgba(0, 144, 241, 0.2)
'
,
'
custom.inputOption.activeBackground
'
:
'
rgba(0, 144, 241, 0.2)
'
,
'
custom.inputOption.hoverBackground
'
:
'
rgba(184, 184, 184, 0.31)
'
,
'
custom.inputOption.hoverBackground
'
:
'
rgba(184, 184, 184, 0.31)
'
,
// don't know the name of this variables in vscode
'
custom.fileLink.hoverForeground
'
:
'
#4299E1
'
,
// blue.400
}
as
const
,
}
as
const
,
};
};
...
@@ -69,5 +72,8 @@ export const dark = {
...
@@ -69,5 +72,8 @@ export const dark = {
'
custom.findMatchHighlightBackground
'
:
'
rgba(234,92,0,0.33)
'
,
'
custom.findMatchHighlightBackground
'
:
'
rgba(234,92,0,0.33)
'
,
'
custom.inputOption.activeBackground
'
:
'
rgba(0, 127, 212, 0.4)
'
,
'
custom.inputOption.activeBackground
'
:
'
rgba(0, 127, 212, 0.4)
'
,
'
custom.inputOption.hoverBackground
'
:
'
rgba(90, 93, 94, 0.31)
'
,
'
custom.inputOption.hoverBackground
'
:
'
rgba(90, 93, 94, 0.31)
'
,
// don't know the name of this variables in vscode
'
custom.fileLink.hoverForeground
'
:
'
#4299E1
'
,
// blue.400
}
as
const
,
}
as
const
,
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment