Skip to content

Commit

Permalink
Version 3.2 (#92)
Browse files Browse the repository at this point in the history
* checkpoint before syntax highlighter

* syntax highlighter

* Create process-strings.ts

* improve sprite handling

* improve g element parsing

* update to 3.2
  • Loading branch information
rossmoody authored Jul 15, 2021
1 parent 0b262b9 commit 259e97f
Show file tree
Hide file tree
Showing 16 changed files with 564 additions and 73 deletions.
2 changes: 1 addition & 1 deletion extension/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "SVG Gobbler",
"version": "3.1",
"version": "3.2",
"description": "Download and optimize icons, logos, and vector SVGs from websites.",
"homepage_url": "https://github.com/rossmoody/svg-gobbler",
"icons": {
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svg-gobbler",
"version": "3.1.0",
"version": "3.2.0",
"author": "rossmoody <ross@rossmoody.com>",
"description": "SVG Gobbler is a simple browser extension that highlights any available SVG content in your current window and lets you download it.",
"license": "apache-2.0",
Expand Down Expand Up @@ -32,6 +32,7 @@
"@types/file-saver": "^2.0.2",
"@types/react": "^17.0.11",
"@types/react-dom": "^17.0.8",
"@types/react-syntax-highlighter": "^13.5.2",
"@types/svgo": "^2.3.0",
"eslint-config-rossmoody": "^1.1.6",
"file-saver": "^2.0.5",
Expand All @@ -43,6 +44,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.2.0",
"react-syntax-highlighter": "^15.4.3",
"svgo": "^2.3.1",
"ts-loader": "^9.2.3",
"typescript": "^4.3.5",
Expand Down
98 changes: 55 additions & 43 deletions src/build/components/card/card-action-footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ import {
MenuItem,
IconButton,
MenuDivider,
MenuGroup,
useColorModeValue,
useToast,
} from '@chakra-ui/react'
import { FaChevronDown } from 'react-icons/fa'
import {
FiChevronDown,
FiCode,
FiImage,
FiDownload,
FiCopy,
} from 'react-icons/fi'

import Drawer from '../drawer'
import { handle } from '../utils/actions'

import ImageModal from './image-modal'
Expand All @@ -26,6 +32,7 @@ interface CardActionFooter {

const CardActionFooter = ({ svgString, height, width }: CardActionFooter) => {
const [showModal, setShowModal] = React.useState(false)
const [showDrawer, setShowDrawer] = React.useState(false)

const toast = useToast({
status: 'success',
Expand Down Expand Up @@ -67,54 +74,59 @@ const CardActionFooter = ({ svgString, height, width }: CardActionFooter) => {
>
Copy
</Button>
<Menu>
<Menu placement="top">
<MenuButton
as={IconButton}
icon={<FaChevronDown />}
icon={<FiChevronDown />}
aria-label="Options"
borderRadius="md"
/>
<MenuList>
<MenuGroup title="Optimized SVG">
<MenuItem
onClick={() => {
handle.downloadOptimized(svgString)
toast({
title: 'Download successful',
description:
'The SVG has been successfully optimized using SVGO and is downloading now.',
})
}}
>
Download
</MenuItem>
<MenuItem
onClick={() => {
handle.copyOptimized(svgString)
toast({
title: 'Copied to clipboard',
description:
'The SVG has been successfully optimized using SVGO and is available in your clipboard.',
})
}}
>
Copy to clipboard
</MenuItem>
</MenuGroup>
<MenuItem
icon={<FiDownload />}
onClick={() => {
handle.downloadOptimized(svgString)
toast({
title: 'Download successful',
description:
'The SVG has been successfully optimized using SVGO and is downloading now.',
})
}}
>
Download optimized
</MenuItem>
<MenuItem
icon={<FiCopy />}
onClick={() => {
handle.copyOptimized(svgString)
toast({
title: 'Copied to clipboard',
description:
'The SVG has been successfully optimized using SVGO and is available in your clipboard.',
})
}}
>
Copy optimized
</MenuItem>
<MenuDivider />
<MenuItem icon={<FiImage />} onClick={() => setShowModal(true)}>
Export as PNG…
</MenuItem>
{showModal && (
<ImageModal
callback={setShowModal}
svgString={svgString}
height={height}
width={width}
/>
)}
<MenuDivider />
<MenuGroup defaultValue="asc" title="Image" type="radio">
<MenuItem onClick={() => setShowModal(true)}>
Export as PNG
</MenuItem>
{showModal && (
<ImageModal
callback={setShowModal}
svgString={svgString}
height={height}
width={width}
/>
)}
</MenuGroup>
<MenuItem icon={<FiCode />} onClick={() => setShowDrawer(true)}>
View code…
</MenuItem>
{showDrawer && (
<Drawer svgString={svgString} callback={setShowDrawer} />
)}
</MenuList>
</Menu>
</Grid>
Expand Down
68 changes: 68 additions & 0 deletions src/build/components/drawer/drawer-tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react'
import {
Box,
Button,
Tabs,
TabList,
TabPanels,
Tab,
TabPanel,
} from '@chakra-ui/react'

import { handle } from '../utils/actions'

import { SVGHighlighter } from './syntax-highlighter'

interface DrawerTabsProps {
svgString: {
prettySVG: string
optimizedSVG: string
}
}

function DrawerTabs({ svgString }: DrawerTabsProps) {
const { prettySVG, optimizedSVG } = svgString

return (
<Tabs colorScheme="red" isFitted>
<TabList>
<Tab>Original</Tab>
<Tab>Optimized</Tab>
</TabList>

<TabPanels>
<TabPanel>
<Box position="relative">
<Button
size="xs"
position="absolute"
bottom={6}
right={6}
onClick={() => handle.copyToClipboard(prettySVG)}
>
Copy
</Button>
<SVGHighlighter>{prettySVG}</SVGHighlighter>
</Box>
</TabPanel>

<TabPanel>
<Box position="relative">
<Button
size="xs"
position="absolute"
bottom={6}
right={6}
onClick={() => handle.copyToClipboard(optimizedSVG)}
>
Copy
</Button>
<SVGHighlighter>{optimizedSVG}</SVGHighlighter>
</Box>
</TabPanel>
</TabPanels>
</Tabs>
)
}

export { DrawerTabs }
51 changes: 51 additions & 0 deletions src/build/components/drawer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react'
import {
Drawer,
DrawerBody,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
DrawerContent,
DrawerCloseButton,
Button,
Divider,
} from '@chakra-ui/react'

import { DrawerTabs } from './drawer-tabs'
import { prettifySvg, optimizeSvg } from './process-strings'

function CodeDrawer({
callback,
svgString,
}: {
callback: any
svgString: string
}) {
const processedSVGString = {
prettySVG: prettifySvg(svgString),
optimizedSVG: optimizeSvg(svgString),
}

return (
<Drawer isOpen placement="right" size="lg" onClose={() => callback(false)}>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader>SVG Markup</DrawerHeader>
<Divider />

<DrawerBody>
<DrawerTabs svgString={processedSVGString} />
</DrawerBody>

<DrawerFooter>
<Button colorScheme="red" onClick={() => callback(false)}>
Done
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
)
}

export default CodeDrawer
81 changes: 81 additions & 0 deletions src/build/components/drawer/process-strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { optimize, extendDefaultPlugins } from 'svgo/dist/svgo.browser'

const plugins = [
{ name: 'removeDoctype', active: false },
{ name: 'removeXMLProcInst', active: false },
{ name: 'removeComments', active: false },
{ name: 'removeMetadata', active: false },
{ name: 'removeEditorsNSData', active: false },
{ name: 'cleanupAttrs', active: false },
{ name: 'mergeStyles', active: false },
{ name: 'inlineStyles', active: false },
{ name: 'minifyStyles', active: false },
{ name: 'cleanupIDs', active: false },
{ name: 'removeUselessDefs', active: false },
{ name: 'cleanupNumericValues', active: false },
{ name: 'convertColors', active: false },
{ name: 'removeUnknownsAndDefaults', active: false },
{ name: 'removeNonInheritableGroupAttrs', active: false },
{ name: 'removeUselessStrokeAndFill', active: false },
{ name: 'removeViewBox', active: false },
{ name: 'cleanupEnableBackground', active: false },
{ name: 'removeHiddenElems', active: false },
{ name: 'removeEmptyText', active: false },
{ name: 'convertShapeToPath', active: false },
{ name: 'convertEllipseToCircle', active: false },
{ name: 'moveElemsAttrsToGroup', active: false },
{ name: 'moveGroupAttrsToElems', active: false },
{ name: 'collapseGroups', active: false },
{ name: 'convertPathData', active: false },
{ name: 'convertTransform', active: false },
{ name: 'removeEmptyAttrs', active: false },
{ name: 'removeEmptyContainers', active: false },
{ name: 'mergePaths', active: false },
{ name: 'removeUnusedNS', active: false },
{ name: 'sortDefsChildren', active: false },
{ name: 'removeTitle', active: false },
{ name: 'removeDesc', active: false },
]

const prettyConfig = {
multipass: true,
plugins: extendDefaultPlugins(plugins),
js2svg: {
indent: 2,
pretty: true,
},
}

const defaultConfig = {
multipass: true,
plugins: extendDefaultPlugins([
{
name: 'removeDimensions',
active: true,
},
{
name: 'removeViewBox',
active: false,
},
{
name: 'sortAttrs',
active: true,
},
]),
js2svg: {
indent: 2,
pretty: true,
},
}

function prettifySvg(svgString: string): string {
const { data } = optimize(svgString, prettyConfig)
return data
}

function optimizeSvg(svgString: string): string {
const { data } = optimize(svgString, defaultConfig)
return data
}

export { prettifySvg, optimizeSvg }
19 changes: 19 additions & 0 deletions src/build/components/drawer/syntax-highlighter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { dracula } from 'react-syntax-highlighter/dist/esm/styles/prism'

const SVGHighlighter: React.FC = ({ children }) => {
return (
<SyntaxHighlighter
wrapLines
wrapLongLines
style={dracula}
language="markup"
customStyle
>
{children}
</SyntaxHighlighter>
)
}

export { SVGHighlighter }
Loading

0 comments on commit 259e97f

Please sign in to comment.