diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 8155a709ab..5038cac23f 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -51,6 +51,7 @@ const remixLib = require('@remix-project/remix-lib') import { QueryParams } from '@remix-project/remix-lib' import { SearchPlugin } from './app/tabs/search' +import { DocGen } from './app/plugins/docgen' const Storage = remixLib.Storage const RemixDProvider = require('./app/files/remixDProvider') @@ -180,6 +181,9 @@ class AppComponent { //----- search const search = new SearchPlugin() + //---- docgen plugin + const docgen = new DocGen() + //---------------- Solidity UML Generator ------------------------- const solidityumlgen = new SolidityUmlGen(appManager) @@ -298,7 +302,8 @@ class AppComponent { this.walkthroughService, search, solidityumlgen, - contractFlattener + contractFlattener, + docgen ]) // LAYOUT & SYSTEM VIEWS @@ -413,7 +418,7 @@ class AppComponent { await this.appManager.activatePlugin(['settings', 'config']) await this.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'codeParser', 'codeFormatter', 'fileDecorator', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport', 'gistHandler']) await this.appManager.activatePlugin(['settings']) - await this.appManager.activatePlugin(['walkthrough', 'storage', 'search', 'compileAndRun', 'recorder']) + await this.appManager.activatePlugin(['walkthrough', 'storage', 'search', 'compileAndRun', 'recorder', 'docgen']) this.appManager.on( 'filePanel', diff --git a/apps/remix-ide/src/app/plugins/docgen.ts b/apps/remix-ide/src/app/plugins/docgen.ts index 1e8f6f504a..3c366cfcbc 100644 --- a/apps/remix-ide/src/app/plugins/docgen.ts +++ b/apps/remix-ide/src/app/plugins/docgen.ts @@ -30,10 +30,11 @@ export class DocGen extends Plugin { } async docgen(builds: Build[], userConfig?: Config): Promise { - const config = { ...defaults, ...userConfig }; - const templates = await loadTemplates(config.theme, config.root, config.templates); - const site = buildSite(builds, config, templates.properties ?? {}); - const renderedSite = render(site, templates, config.collapseNewlines); + const config = { ...defaults, ...userConfig } + const templates = await loadTemplates(config.theme, config.root, config.templates) + const site = buildSite(builds, config, templates.properties ?? {}) + const renderedSite = render(site, templates, config.collapseNewlines) + console.log({ renderedSite }) for (const { id, contents } of renderedSite) { await this.call('fileManager', 'setFile', id, contents) } diff --git a/apps/remixdocgen/src/app/App.tsx b/apps/remixdocgen/src/app/App.tsx index 063fb4e4c3..df0a9d3729 100644 --- a/apps/remixdocgen/src/app/App.tsx +++ b/apps/remixdocgen/src/app/App.tsx @@ -10,7 +10,9 @@ import { Status } from "@remixproject/plugin-utils"; import { AppContext } from "./AppContext"; import { Routes } from "./routes"; -import { useLocalStorage } from "./hooks/useLocalStorage"; +import { useLocalStorage } from "./hooks/useLocalStorage" + +import { RemixUiDocgenClient } from '@remix-ui/docgenclient-ui' // eslint-disable-line import "./App.css"; @@ -101,7 +103,7 @@ const App = () => { // //
-

Testing

+
) }; diff --git a/apps/remixdocgen/src/app/docgen-client.ts b/apps/remixdocgen/src/app/docgen-client.ts new file mode 100644 index 0000000000..569e271a71 --- /dev/null +++ b/apps/remixdocgen/src/app/docgen-client.ts @@ -0,0 +1,28 @@ +import { PluginClient } from '@remixproject/plugin' +import { IRemixApi } from '@remixproject/plugin-api' +import { Api, PluginApi } from '@remixproject/plugin-utils' +import { createClient } from '@remixproject/plugin-webview' + +export class DocGenClient extends PluginClient { + private client + + constructor() { + super() + this.client = createClient(this) + this.methods = ['generateDocs', 'publishDocs'] + + this.client.onload(async () => { + await this.client.activate() + }) + } + + async generateDocs() { + console.log('docgen client generateDocs') + // await this.client.call('docgen', 'docgen', []) + } + + async publishDocs() { + console.log('docgen client publishDocs') + // await this.client.call('docgen', 'docgen', []) + } +} \ No newline at end of file diff --git a/apps/remixdocgen/webpack.config.js b/apps/remixdocgen/webpack.config.js index 45c7c5dd14..ac6e2f27cc 100644 --- a/apps/remixdocgen/webpack.config.js +++ b/apps/remixdocgen/webpack.config.js @@ -1,10 +1,11 @@ const { composePlugins, withNx } = require('@nrwl/webpack') +const { withReact } = require('@nrwl/react') const webpack = require('webpack') const TerserPlugin = require("terser-webpack-plugin") const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") // Nx plugins for webpack. -module.exports = composePlugins(withNx(), (config) => { +module.exports = composePlugins(withNx(), withReact(), (config) => { // Update the webpack config as needed here. // e.g. `config.plugins.push(new MyPlugin())` diff --git a/libs/remix-ui/docgenclient-ui/src/index.ts b/libs/remix-ui/docgenclient-ui/src/index.ts new file mode 100644 index 0000000000..96a7f59d7c --- /dev/null +++ b/libs/remix-ui/docgenclient-ui/src/index.ts @@ -0,0 +1 @@ +export * from './lib/docgenclient-ui' \ No newline at end of file diff --git a/libs/remix-ui/docgenclient-ui/src/lib/docgenclient-ui.tsx b/libs/remix-ui/docgenclient-ui/src/lib/docgenclient-ui.tsx new file mode 100644 index 0000000000..7ea634d0eb --- /dev/null +++ b/libs/remix-ui/docgenclient-ui/src/lib/docgenclient-ui.tsx @@ -0,0 +1,10 @@ +import React from 'react' + + +export function RemixUiDocgenClient() { + return ( +
+

DocgenClientUI

+
+ ) +} \ No newline at end of file diff --git a/libs/remix-ui/solidity-compiler/src/lib/logic/pdfSaveLogic.ts b/libs/remix-ui/solidity-compiler/src/lib/logic/pdfSaveLogic.ts deleted file mode 100644 index c93c990990..0000000000 --- a/libs/remix-ui/solidity-compiler/src/lib/logic/pdfSaveLogic.ts +++ /dev/null @@ -1,294 +0,0 @@ -/* eslint-disable prefer-const */ -import domToImage from 'dom-to-image'; -import { jsPDF } from 'jspdf'; - -const _cloneNode = (node, javascriptEnabled) => { - let child = node.firstChild - const clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false) - while (child) { - if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') { - clone.appendChild(_cloneNode(child, javascriptEnabled)) - } - child = child.nextSibling - } - if (node.nodeType === 1) { - if (node.nodeName === 'CANVAS') { - clone.width = node.width - clone.height = node.height - clone.getContext('2d').drawImage(node, 0, 0) - } else if (node.nodeName === 'TEXTAREA' || node.nodeName === 'SELECT') { - clone.value = node.value - } - clone.addEventListener('load', (() => { - clone.scrollTop = node.scrollTop - clone.scrollLeft = node.scrollLeft - }), true) - } - return clone -} - -const _createElement = (tagName, {className, innerHTML, style}) => { - let i - let scripts - const el = document.createElement(tagName) - if (className) { - el.className = className - } - if (innerHTML) { - el.innerHTML = innerHTML - scripts = el.getElementsByTagName('script') - i = scripts.length - while (i-- > 0) { - scripts[i].parentNode.removeChild(scripts[i]) - } - } - for (const key in style) { - el.style[key] = style[key]; - } - return el; -}; - -const _isCanvasBlank = canvas => { - const blank = document.createElement('canvas'); - blank.width = canvas.width; - blank.height = canvas.height; - const ctx = blank.getContext('2d'); - ctx.fillStyle = '#FFFFFF'; - ctx.fillRect(0, 0, blank.width, blank.height); - return canvas.toDataURL() === blank.toDataURL(); -}; - -const downloadPdf = (dom, options, cb) => { - const a4Height = 841.89; - const a4Width = 595.28; - let overrideWidth; - let container; - let containerCSS; - let containerWidth; - let elements; - let excludeClassNames; - let excludeTagNames; - let filename; - let filterFn; - let innerRatio; - let overlay; - let overlayCSS; - let pageHeightPx; - let proxyUrl; - let compression = 'NONE'; - let scale; - let opts; - let offsetHeight; - let offsetWidth; - let scaleObj; - let style; - const transformOrigin = 'top left'; - const pdfOptions: any = { - orientation: 'l', - unit: 'pt', - format: 'a4' - }; - - ({filename, excludeClassNames = [], excludeTagNames = ['button', 'input', 'select'], overrideWidth, proxyUrl, compression, scale} = options); - - overlayCSS = { - position: 'fixed', - zIndex: 1000, - opacity: 0, - left: 0, - right: 0, - bottom: 0, - top: 0, - backgroundColor: 'rgba(0,0,0,0.8)' - }; - if (overrideWidth) { - overlayCSS.width = `${overrideWidth}px`; - } - containerCSS = { - position: 'absolute', - left: 0, - right: 0, - top: 0, - height: 'auto', - margin: 'auto', - overflow: 'auto', - backgroundColor: 'white' - }; - overlay = _createElement('div', { - style: overlayCSS, - className: '', - innerHTML: '' - }); - container = _createElement('div', { - style: containerCSS, - className: '', - innerHTML: '' - }); - //@ts-ignore - container.appendChild(_cloneNode(dom)); - overlay.appendChild(container); - document.body.appendChild(overlay); - innerRatio = a4Height / a4Width; - containerWidth = overrideWidth || container.getBoundingClientRect().width; - pageHeightPx = Math.floor(containerWidth * innerRatio); - elements = container.querySelectorAll('*'); - - for (let i = 0, len = excludeClassNames.length; i < len; i++) { - const clName = excludeClassNames[i]; - container.querySelectorAll(`.${clName}`).forEach(function(a) { - return a.remove(); - }); - } - - for (let j = 0, len1 = excludeTagNames.length; j < len1; j++) { - const tName = excludeTagNames[j]; - let els = container.getElementsByTagName(tName); - - for (let k = els.length - 1; k >= 0; k--) { - if (!els[k]) { - continue; - } - els[k].parentNode.removeChild(els[k]); - } - } - - Array.prototype.forEach.call(elements, el => { - let clientRect; - let endPage; - let nPages; - let pad; - let rules; - let startPage; - rules = { - before: false, - after: false, - avoid: true - }; - clientRect = el.getBoundingClientRect(); - if (rules.avoid && !rules.before) { - startPage = Math.floor(clientRect.top / pageHeightPx); - endPage = Math.floor(clientRect.bottom / pageHeightPx); - nPages = Math.abs(clientRect.bottom - clientRect.top) / pageHeightPx; - // Turn on rules.before if the el is broken and is at most one page long. - if (endPage !== startPage && nPages <= 1) { - rules.before = true; - } - // Before: Create a padding div to push the element to the next page. - if (rules.before) { - pad = _createElement('div', { - className: '', - innerHTML: '', - style: { - display: 'block', - height: `${pageHeightPx - clientRect.top % pageHeightPx}px` - } - }); - return el.parentNode.insertBefore(pad, el); - } - } - }); - - // Remove unnecessary elements from result pdf - filterFn = ({classList, tagName}) => { - let cName; - let j; - let len; - let ref; - if (classList) { - for (j = 0, len = excludeClassNames.length; j < len; j++) { - cName = excludeClassNames[j]; - if (Array.prototype.indexOf.call(classList, cName) >= 0) { - return false; - } - } - } - ref = tagName != null ? tagName.toLowerCase() : undefined; - return excludeTagNames.indexOf(ref) < 0; - }; - - opts = { - filter: filterFn, - proxy: proxyUrl - }; - - if (scale) { - offsetWidth = container.offsetWidth; - offsetHeight = container.offsetHeight; - style = { - transform: 'scale(' + scale + ')', - transformOrigin: transformOrigin, - width: offsetWidth + 'px', - height: offsetHeight + 'px' - }; - scaleObj = { - width: offsetWidth * scale, - height: offsetHeight * scale, - quality: 1, - style: style - }; - opts = Object.assign(opts, scaleObj); - } - - return domToImage.toCanvas(container, opts).then(canvas => { - let h; - let imgData; - let nPages; - let page; - let pageCanvas; - let pageCtx; - let pageHeight; - let pdf; - let pxFullHeight; - let w; - // Remove overlay - document.body.removeChild(overlay); - // Initialize the PDF. - pdf = new jsPDF(pdfOptions); - // Calculate the number of pages. - pxFullHeight = canvas.height; - nPages = Math.ceil(pxFullHeight / pageHeightPx); - // Define pageHeight separately so it can be trimmed on the final page. - pageHeight = a4Height; - pageCanvas = document.createElement('canvas'); - pageCtx = pageCanvas.getContext('2d'); - pageCanvas.width = canvas.width; - pageCanvas.height = pageHeightPx; - page = 0; - while (page < nPages) { - if (page === nPages - 1 && pxFullHeight % pageHeightPx !== 0) { - pageCanvas.height = pxFullHeight % pageHeightPx; - pageHeight = pageCanvas.height * a4Width / pageCanvas.width; - } - w = pageCanvas.width; - h = pageCanvas.height; - pageCtx.fillStyle = 'white'; - pageCtx.fillRect(0, 0, w, h); - pageCtx.drawImage(canvas, 0, page * pageHeightPx, w, h, 0, 0, w, h); - // Don't create blank pages - if (_isCanvasBlank(pageCanvas)) { - ++page; - continue; - } - // Add the page to the PDF. - if (page) { - pdf.addPage(); - } - imgData = pageCanvas.toDataURL('image/PNG'); - pdf.addImage(imgData, 'PNG', 0, 0, a4Width, pageHeight, undefined, compression); - ++page; - } - if (typeof cb === "function") { - cb(pdf); - } - return pdf.save(filename); - }).catch(error => { - // Remove overlay - document.body.removeChild(overlay); - if (typeof cb === "function") { - cb(null); - } - return console.error(error); - }); -}; - -module.exports = downloadPdf; \ No newline at end of file diff --git a/tsconfig.paths.json b/tsconfig.paths.json index e45b011400..20989bfbd2 100644 --- a/tsconfig.paths.json +++ b/tsconfig.paths.json @@ -148,9 +148,12 @@ "@remix-ui/solidity-uml-gen": [ "libs/remix-ui/solidity-uml-gen/src/index.ts" ], + "@remix-ui/docgenclient-ui": [ + "libs/remix-ui/docgenclient-ui/src/index.ts" + ], "@remix-project/ghaction-helper": [ "libs/ghaction-helper/src/index.ts" - ] + ], } } } \ No newline at end of file