Merge pull request #98 from xibyte/helpDocs

Help docs
This commit is contained in:
Val Erastov 2020-05-06 23:53:11 -07:00 committed by GitHub
commit 1b4068756d
39 changed files with 674 additions and 83 deletions

View file

@ -1,7 +1,10 @@
{
"presets": ["@babel/env", "@babel/react", "@babel/flow"],
"presets": ["@babel/typescript", "@babel/env", "@babel/react", "@babel/flow"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
"@babel/proposal-class-properties"
"@babel/proposal-class-properties",
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-optional-chaining"
]
}

View file

@ -13,6 +13,8 @@ JS.Sketcher is a **parametric** 2D and 3D CAD modeler written in pure javascript
[2D Sketcher](http://web-cad.org/sketcher.html#__sample2D__)
[Help Docs](./web/docs/index.md)
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=WADW7V7CC32CY&lc=US&item_name=web%2dcad%2eorg&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted)
Current Status

View file

@ -0,0 +1,96 @@
import React, {useEffect, useState} from 'react';
import {stream} from "lstream";
import Window from "ui/components/Window";
import {useStream} from "ui/effects";
import marked from 'marked';
export const DocumentationTopic$ = stream();
export const DocumentationUIState$ = stream();
export interface DocumentationRequest {
topic: string;
x: number,
y: number
}
export function DocumentationWindow() {
const request: DocumentationRequest = useStream(DocumentationTopic$);
const [content, setContent] = useState(null);
useEffect(() => {
window.__CAD_APP.DocumentationTopic$ = DocumentationTopic$;
if (!request) {
setContent(null);
return;
}
fetch(`/docs/${topic}.md`).then(res => res.text()).then(source => {
const tokens = marked.lexer(source);
fixLinks(tokens);
const html = marked.parser(tokens, {
baseUrl: 'docs/'
});
setContent(html);
}).catch(e => {
console.error();
setContent('No documentation for ' + topic + '.md');
});
}, [request?.topic]);
if (!request) {
return null;
}
const {topic, x, y} = request;
const stateJson = sessionStorage.getItem('DocumentationWindow');
let uiState;
try {
uiState = JSON.parse(stateJson);
} catch (ignore) {
}
if (!uiState) {
uiState = {
width: 350,
height: 700
}
}
return <Window initWidth={uiState.width} initHeight={uiState.height} initLeft={x} initTop={y}
title={topic}
enableResize={true}
onClose={() => DocumentationTopic$.next(null)}
onResize={el => DocumentationUIState$.next(el)}>
<p className='documentation-content' dangerouslySetInnerHTML={{__html: content}} />
</Window>
}
DocumentationUIState$.throttle(3000).attach(el => {
const rect = el.getBoundingClientRect();
sessionStorage.setItem('DocumentationWindow', JSON.stringify({
width: rect.width,
height: rect.height,
}));
});
function fixLinks(inputTokens: any[]) {
const stack = [];
inputTokens.forEach(t => stack.push(t));
while (stack.length) {
const token = stack.pop();
if (token.type === 'link' && token.href) {
//removing .md suffix
token.href = `javascript:__CAD_APP.DocumentationTopic$.next({topic: '${token.href.substring(0, token.href.length-3)}'});`
}
if (token.tokens) {
token.tokens.forEach(t => stack.push(t));
}
}
}

View file

@ -1,34 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import {NOOP} from "../gems/func";
//TODO: remove it
export default class WindowSystem extends React.Component {
constructor() {
super();
}
componentDidMount() {
}
componentWillUnMount() {
}
render() {
return this.props.children;
}
childContext = {
setWindowMoveHandler: NOOP
};
getChildContext() {
return this.childContext;
}
static childContextTypes = {
setWindowMoveHandler: PropTypes.func
}
}

View file

@ -1,10 +1,9 @@
import React from 'react';
import ls from './Window.less'
import Fa from "./Fa";
import WindowSystem from '../WindowSystem';
import cx from 'classnames';
import {NOOP} from "../../gems/func";
import {NOOP} from '../../gems/func';
import {FaTimes} from 'react-icons/fa';
export default class Window extends React.Component {
@ -12,15 +11,17 @@ export default class Window extends React.Component {
resizeHelper = new ResizeHelper();
render() {
let {initWidth, initHeight, initLeft, initTop, initRight, initBottom, setFocus, className,
resizeCapturingBuffer, resize,
children, title, icon, minimizable, onClose, ...props} = this.props;
return <div className={cx(ls.root, className)} {...props} ref={this.keepRef}>
resizeCapturingBuffer, resize, enableResize, children, title, icon, minimizable, onClose, controlButtons, ...props} = this.props;
return <div className={cx(ls.root, this.resizeConfig&&ls.mandatoryBorder, className)} {...props} ref={this.keepRef}>
<div className={ls.bar + ' disable-selection'} onMouseDown={this.startDrag} onMouseUp={this.stopDrag}>
<div>{icon}<b>{title.toUpperCase()}</b></div>
<div className={ls.controlButtons}>
{minimizable && <span className={ls.button}>_</span>}
<span className={ls.button} onClick={onClose}><Fa fw icon='close' /></span>
{controlButtons}
{minimizable && <WindowControlButton onClick={onClose}>_</WindowControlButton>}
<WindowControlButton danger={true} onClick={onClose}><FaTimes /></WindowControlButton>
</div>
</div>
<div className={cx(ls.content, 'compact-scroll')}>
@ -86,6 +87,7 @@ export default class Window extends React.Component {
this.el.style.left = this.originLocation.left + dx + 'px';
this.el.style.top = this.originLocation.top + dy + 'px';
e.preventDefault();
}
};
@ -97,7 +99,8 @@ export default class Window extends React.Component {
if (el === null) {
return;
}
let {initWidth, initHeight, initLeft, initTop, initRight, initBottom, resize, resizeCapturingBuffer, onResize, ...props} = this.props;
let {initWidth, initHeight, initLeft, initTop, initRight, initBottom, resizeCapturingBuffer, onResize, ...props} = this.props;
if (initWidth) {
el.style.width = initWidth + 'px';
}
@ -114,10 +117,17 @@ export default class Window extends React.Component {
} else if (initBottom) {
el.style.top = (window.innerHeight - el.offsetHeight - initBottom) + 'px';
}
this.resizeHelper.registerResize(el, resize, resizeCapturingBuffer);
this.resizeHelper.registerResize(el, this.resizeConfig, resizeCapturingBuffer, onResize);
this.el = el;
};
get resizeConfig() {
let {resize, enableResize} = this.props;
if (enableResize) {
resize= DIRECTIONS.NORTH | DIRECTIONS.SOUTH | DIRECTIONS.WEST | DIRECTIONS.EAST;
}
return resize;
}
}
Window.defaultProps = {
@ -168,8 +178,9 @@ export class ResizeHelper {
el.style.top = top + 'px';
}
if (onResize !== undefined) {
onResize();
onResize(el);
}
e.preventDefault();
};
if (this.controlGlobalListeners) {
const moveListener = e => {
@ -270,3 +281,7 @@ export const DIRECTIONS = {
function _maskTest(mask, value) {
return (mask & value) === value;
}
export function WindowControlButton({danger, ...props}) {
return <span className={cx(ls.button, danger&&ls.danger)} {...props} />;
}

View file

@ -11,9 +11,13 @@
min-height: 20px;
}
.mandatoryBorder {
border: 5px solid #444444;
}
.bar {
display: flex;
align-items: baseline;
align-items: center;
justify-content: space-between;
background-color: @bg-color;
line-height: 1;
@ -25,6 +29,14 @@
.button {
display: inline-block;
padding: 6px 5px 6px 5px;
.button-behavior(@color-accent);
svg {
width: 12px;
height: 12px;
}
}
.danger {
.button-behavior(@color-danger);
}

View file

@ -6,7 +6,7 @@ export function useStream(getStream) {
const basicStreams = useContext(StreamsContext);
const [state, setState] = useState();
const stream = getStream(basicStreams);
const stream = typeof getStream === 'function' ? getStream(basicStreams) : getStream;
if (!stream) {
console.log(getStream);
@ -24,7 +24,7 @@ export function useStreamWithUpdater(getStream) {
const data = useStream(getStream);
const basicStreams = useContext(StreamsContext);
const stream = getStream(basicStreams);
const stream = typeof getStream === 'function' ? getStream(basicStreams) : getStream;
const updater = useCallback((val) => {

View file

@ -0,0 +1,5 @@
.documentation-content {
background: #323444;
font-size: 13px;
padding: 10px;
}

View file

@ -8,3 +8,4 @@
@import "./svg.less";
@import "./icons.less";
@import "./scroll";
@import "./documentation";

352
package-lock.json generated
View file

@ -761,6 +761,15 @@
"@babel/helper-plugin-utils": "^7.8.3"
}
},
"@babel/plugin-syntax-typescript": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz",
"integrity": "sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
}
},
"@babel/plugin-transform-arrow-functions": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz",
@ -1127,6 +1136,135 @@
"@babel/helper-plugin-utils": "^7.8.3"
}
},
"@babel/plugin-transform-typescript": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.6.tgz",
"integrity": "sha512-8OvsRdvpt3Iesf2qsAn+YdlwAJD7zJ+vhFZmDCa4b8dTp7MmHtKk5FF2mCsGxjZwuwsy/yIIay/nLmxST1ctVQ==",
"dev": true,
"requires": {
"@babel/helper-create-class-features-plugin": "^7.9.6",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-syntax-typescript": "^7.8.3"
},
"dependencies": {
"@babel/generator": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
"integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
"dev": true,
"requires": {
"@babel/types": "^7.9.6",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-create-class-features-plugin": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.9.6.tgz",
"integrity": "sha512-6N9IeuyHvMBRyjNYOMJHrhwtu4WJMrYf8hVbEHD3pbbbmNOk1kmXSQs7bA4dYDUaIx4ZEzdnvo6NwC3WHd/Qow==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.9.5",
"@babel/helper-member-expression-to-functions": "^7.8.3",
"@babel/helper-optimise-call-expression": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-replace-supers": "^7.9.6",
"@babel/helper-split-export-declaration": "^7.8.3"
}
},
"@babel/helper-function-name": {
"version": "7.9.5",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
"integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.9.5"
}
},
"@babel/helper-replace-supers": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz",
"integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==",
"dev": true,
"requires": {
"@babel/helper-member-expression-to-functions": "^7.8.3",
"@babel/helper-optimise-call-expression": "^7.8.3",
"@babel/traverse": "^7.9.6",
"@babel/types": "^7.9.6"
}
},
"@babel/helper-validator-identifier": {
"version": "7.9.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
"integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
"dev": true
},
"@babel/parser": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
"integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
"dev": true
},
"@babel/traverse": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
"integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.9.6",
"@babel/helper-function-name": "^7.9.5",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.9.6",
"@babel/types": "^7.9.6",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
"integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.9.5",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
"dev": true
}
}
},
"@babel/plugin-transform-unicode-regex": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz",
@ -1268,6 +1406,16 @@
"integrity": "sha512-dStnEQgejNYIHFNACdDCigK4BF7wgW6Zahv9Dc2un7rGjbeVtZhBfR3sy0I7ZJOhBexkFxVdMZ5hqmll7BFShw==",
"dev": true
},
"@babel/preset-typescript": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz",
"integrity": "sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-transform-typescript": "^7.9.0"
}
},
"@babel/runtime": {
"version": "7.8.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz",
@ -1527,6 +1675,31 @@
"integrity": "sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==",
"dev": true
},
"@types/prop-types": {
"version": "15.7.3",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
"dev": true
},
"@types/react": {
"version": "16.9.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.34.tgz",
"integrity": "sha512-8AJlYMOfPe1KGLKyHpflCg5z46n0b5DbRfqDksxBLBTUpB75ypDBAO9eCUcjNwE6LCUslwTz00yyG/X9gaVtow==",
"dev": true,
"requires": {
"@types/prop-types": "*",
"csstype": "^2.2.0"
}
},
"@types/react-dom": {
"version": "16.9.7",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.7.tgz",
"integrity": "sha512-GHTYhM8/OwUCf254WO5xqR/aqD3gC9kSTLpopWGpQLpnw23jk44RvMHsyUSEplvRJZdHxhJGMMLF0kCPYHPhQA==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/sizzle": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
@ -3909,11 +4082,6 @@
"integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
"dev": true
},
"diff-match-patch": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.0.tgz",
"integrity": "sha1-HMPIOkkNZ/ldkeOfatHy4Ia2MEg="
},
"diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
@ -7638,6 +7806,11 @@
"object-visit": "^1.0.0"
}
},
"marked": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz",
"integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng=="
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@ -8646,6 +8819,12 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true
},
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
@ -11049,6 +11228,99 @@
"integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
"dev": true
},
"ts-loader": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.2.tgz",
"integrity": "sha512-DwpZFB67RoILQHx42dMjSgv2STpacsQu5X+GD/H9ocd8IhU0m8p3b/ZrIln2KmcucC6xep2PdEMEblpWT71euA==",
"dev": true,
"requires": {
"chalk": "^2.3.0",
"enhanced-resolve": "^4.0.0",
"loader-utils": "^1.0.2",
"micromatch": "^4.0.0",
"semver": "^6.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
"dev": true,
"requires": {
"braces": "^3.0.1",
"picomatch": "^2.0.5"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
}
}
},
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
@ -11122,6 +11394,76 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
"typescript": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
"dev": true
},
"typescript-loader": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/typescript-loader/-/typescript-loader-1.1.3.tgz",
"integrity": "sha1-X/fmfLO6WSUZAUqswar2ZqcJ3gE=",
"dev": true,
"requires": {
"bluebird": "^2.7.1",
"loader-utils": "^0.2.6",
"object-assign": "^2.0.0",
"typescript": "^1.4.1"
},
"dependencies": {
"big.js": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
"dev": true
},
"bluebird": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=",
"dev": true
},
"json5": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
"dev": true
},
"loader-utils": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
"dev": true,
"requires": {
"big.js": "^3.1.3",
"emojis-list": "^2.0.0",
"json5": "^0.5.0",
"object-assign": "^4.0.1"
},
"dependencies": {
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
}
}
},
"object-assign": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
"integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=",
"dev": true
},
"typescript": {
"version": "1.8.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-1.8.10.tgz",
"integrity": "sha1-tHXW4N/wv1DyluXKbvn7tccyDx4=",
"dev": true
}
}
},
"ua-parser-js": {
"version": "0.7.18",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",

View file

@ -28,11 +28,16 @@
"@babel/core": "^7.9.0",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-decorators": "^7.8.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@babel/preset-flow": "^7.9.0",
"@babel/preset-react": "^7.9.1",
"@babel/preset-stage-2": "^7.8.3",
"@babel/preset-typescript": "^7.9.0",
"@cypress/webpack-preprocessor": "^4.1.3",
"@types/react": "^16.9.34",
"@types/react-dom": "^16.9.7",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
@ -48,6 +53,9 @@
"less-loader": "^5.0.0",
"raw-loader": "^4.0.0",
"style-loader": "^1.1.3",
"ts-loader": "^7.0.2",
"typescript": "^3.8.3",
"typescript-loader": "^1.1.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
@ -55,11 +63,11 @@
"dependencies": {
"classnames": "2.2.5",
"clipper-lib": "6.2.1",
"diff-match-patch": "1.0.0",
"earcut": "2.1.1",
"less": "^3.11.1",
"libtess": "1.2.2",
"lodash": "^4.17.15",
"marked": "^1.0.0",
"mousetrap": "1.6.1",
"numeric": "1.2.6",
"prop-types": "15.6.0",

17
tsconfig.json Normal file
View file

@ -0,0 +1,17 @@
{
"compilerOptions": {
"lib": ["es2018", "dom"],
"sourceMap": true,
"jsx": "react",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "ES5",
"baseUrl": ".",
"paths": {
"*": [
"modules/*",
"node_modules/*"
]
}
}
}

View file

@ -1,5 +1,5 @@
import React from 'react';
import Window from 'ui/components/Window';
import Window, {WindowControlButton} from 'ui/components/Window';
import Stack from 'ui/components/Stack';
import Button from 'ui/components/controls/Button';
import ButtonGroup from 'ui/components/controls/ButtonGroup';
@ -9,6 +9,8 @@ import CadError from '../../../../utils/errors';
import {FormContext} from './form/Form';
import connect from 'ui/connect';
import {combine} from 'lstream';
import {DocumentationTopic$} from "../../../../../../modules/doc/DocumentationWindow";
import {IoMdHelp} from "react-icons/io";
@connect((streams, props) => combine(props.context.workingRequest$, props.context.state$)
.map(([workingRequest, state]) => ({
@ -57,7 +59,16 @@ export default class Wizard extends React.Component {
title={title}
onClose={this.cancel}
onKeyDown={this.onKeyDown}
setFocus={this.focusFirstInput}>
setFocus={this.focusFirstInput}
controlButtons={<>
<WindowControlButton title='help' onClick={(e) => DocumentationTopic$.next({
topic: operation.id,
x: e.pageX + 40,
y: e.pageY
})}>
<IoMdHelp />
</WindowControlButton>
</>}>
<FormContext.Provider value={formContext}>
<Form/>
</FormContext.Provider>

View file

@ -2,10 +2,15 @@ import React from 'react';
import PropTypes from 'prop-types';
import MenuHolder from '../menu/MenuHolder';
import WindowSystem from 'ui/WindowSystem';
import ActionInfo from '../actionInfo/ActionInfo';
import ContributedComponents from './ContributedComponents';
import {stream} from '../../../../../modules/lstream';
import {stream} from 'lstream';
import {DocumentationWindow} from 'doc/DocumentationWindow';
import {Scope} from "../../../sketcher/components/Scope";
import {ContextualControls} from "../../../sketcher/components/ContextualControls";
import {ConstraintEditor} from "../../../sketcher/components/ConstraintEditor";
import SketcherOperationWizard from "../../../sketcher/components/SketcherOperationWizard";
import {StageControl} from "../../../sketcher/components/StageControl";
export default class UISystem extends React.Component {
@ -15,10 +20,9 @@ export default class UISystem extends React.Component {
return <div {...this.props} onMouseDown={this.closeAllUpPopups} >
<MenuHolder />
<ActionInfo />
<WindowSystem>
{this.props.children}
<ContributedComponents />
</WindowSystem>
{this.props.children}
<ContributedComponents />
<Scope><DocumentationWindow /></Scope>
</div>
}

View file

@ -14,6 +14,10 @@ import SketcherMode from '../../sketch/components/SketcherMode';
import {ConstraintExplorer} from '../../../sketcher/components/ConstraintExplorer';
import {Scope} from "../../../sketcher/components/Scope";
import {InplaceSketcher} from "../../sketch/components/InplaceSketcher";
import {ContextualControls} from "../../../sketcher/components/ContextualControls";
import {ConstraintEditor} from "../../../sketcher/components/ConstraintEditor";
import SketcherOperationWizard from "../../../sketcher/components/SketcherOperationWizard";
import {StageControl} from "../../../sketcher/components/StageControl";
export default class View3d extends React.Component {
@ -40,6 +44,10 @@ export default class View3d extends React.Component {
<div className={ls.overlayingPanel} >
<Scope><SketchObjectExplorer /></Scope>
<Scope><ConstraintExplorer /></Scope>
<Scope><ContextualControls /></Scope>
<Scope><ConstraintEditor /></Scope>
<Scope><SketcherOperationWizard /></Scope>
<Scope><StageControl /></Scope>
</div>
</InplaceSketcher>
</SketcherMode>

View file

@ -1,9 +1,8 @@
import diff_match_patch from 'diff-match-patch';
/** @constructor */
function HistoryManager(viewer) {
this.viewer = viewer;
this.dmp = new diff_match_patch();
// this.dmp = new diff_match_patch();
this.init({});
// this.init(this.viewer.io.serializeSketch());
}
@ -80,9 +79,9 @@ HistoryManager.prototype.redo = function () {
};
HistoryManager.prototype.applyDiff = function (text1, diff) {
var dmp = this.dmp;
var results = dmp.patch_apply(diff, text1);
return results[0];
// var dmp = this.dmp;
// var results = dmp.patch_apply(diff, text1);
// return results[0];
};
HistoryManager.prototype.applyDiffInv = function (text1, diff) {
@ -103,17 +102,17 @@ HistoryManager.prototype.reversePatch = function (plist) {
};
HistoryManager.prototype.getDiff = function (text1, text2) {
var dmp = this.dmp;
var diff = dmp.diff_main(text1, text2, true);
if (diff.length > 2) {
dmp.diff_cleanupSemantic(diff);
}
var patch_list = dmp.patch_make(text1, text2, diff);
//var patch_text = dmp.patch_toText(patch_list);
//console.log(patch_list);
return patch_list;
// var dmp = this.dmp;
// var diff = dmp.diff_main(text1, text2, true);
//
// if (diff.length > 2) {
// dmp.diff_cleanupSemantic(diff);
// }
//
// var patch_list = dmp.patch_make(text1, text2, diff);
// //var patch_text = dmp.patch_toText(patch_list);
// //console.log(patch_list);
// return patch_list;
};
export {HistoryManager}

View file

@ -0,0 +1,20 @@
# ![](../img/cad/union32.png)![](../img/cad/subtract32.png)![](../img/cad/intersection32.png)BOOLEAN OPPERATIONS
Boolean operations allow for solids to be used as tools to shape and modify other solids.
# ![](../img/cad/union32.png)UNION
Union allows solids to be combined to create a new solid.
![](img/bool-UNION.gif)
# ![](../img/cad/subtract32.png)SUBTRACT
Subtract allows one solid to be used as a cuttong tool for another sold. Usefull for making hole features.
Selection A will have selection B removed from it.
![](img/bool-SUBTRACT.gif)
# ![](../img/cad/intersection32.png)INTERSECTION
Intersection allows for the creation of a new solid in the space where 2 exising solids overlap.
![](img/bool-INTERSECTION.gif)

7
web/docs/BOX.md Normal file
View file

@ -0,0 +1,7 @@
# ![](../img/cad/cube32.png)BOX
![](img/box-dialog.gif)
The BOX command can be accesed by hovering over the center point of an existing datum and clicking. This brings up a menue with the BOX command as an option.
Size of the box can be specified with the width, height and depth fields.
The boolean drop down allows for boolean operations with existing 3d solids. See [BOOLEAN_OPPERATIONS.md](BOOLEAN_OPPERATIONS.md "BOOLEAN_OPPERATIONS.md").

1
web/docs/CONE.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/CUT.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/CYLINDER.md Normal file
View file

@ -0,0 +1 @@
place holder

13
web/docs/DATUM_CREATE.md Normal file
View file

@ -0,0 +1,13 @@
# ![](../img/cad/datum32.png)Datum Create
![](img/create-datum.gif)
While the CREATE DATUM dialog is open the datum can be dragged using the vector arrows. Optionally the values can be enter in the fields of the dialog.
Datiums consist of a point and 3 vectors defining a relative location and orientation. The location and orientation can be moved after initial creation. See ![](../img/cad/datum-move32.png)[DATUM_MOVE.md](DATUM_MOVE.md "DATUM_MOVE.md")
![](../img/cad/datum-rotate32.png)[DATUM_ROTATE.md](DATUM_ROTATE.md "DATUM_ROTATE.md")
The datium feature provides a point that can be used as the baisus for plane features or the origin point of a 3d primitive.
The datium feature also provides 3 vectors. These vectors can be used for defining a direction of an extride/cut or the acces of a revolve feature.

9
web/docs/DATUM_MOVE.md Normal file
View file

@ -0,0 +1,9 @@
# ![](../img/cad/datum-move32.png)Datum Move
![](img/move-datum.gif)
The MOVE DATUM dialog can be accesed by hovering over the center point of an existing datum and clicking. This brings up a menue with the MOVE DATUM command as an option.
While the MOVE DATUM dialog is open the datum can be dragged using the vector arrows. Optionally the values can be enter in the fields of the dialog.
Optionally a new copy of the exisintg datum can be created rather than the translation of the original.

7
web/docs/DATUM_ROTATE.md Normal file
View file

@ -0,0 +1,7 @@
# ![](../img/cad/datum-rotate32.png)Datum Rotate
![](img/rotate-datum.gif)
The ROTATE DATUM dialog can be accesed by hovering over the center point of an existing datum and clicking. This brings up a menue with the ROTATE DATUM command as an option.
While the ROTATE DATUM dialog is open the rotational axis can be selected. An angle then can be entered to change the orientation of datum.

1
web/docs/EditFace.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/FILLET.md Normal file
View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
Place holder

1
web/docs/INTERSECTION.md Normal file
View file

@ -0,0 +1 @@
See [BOOLEAN_OPPERATIONS.md](BOOLEAN_OPPERATIONS.md "BOOLEAN_OPPERATIONS.md").

1
web/docs/PLANE.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/REVOLVE.md Normal file
View file

@ -0,0 +1 @@
place holder

View file

@ -0,0 +1 @@
Place holder

1
web/docs/SPHERE.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/SUBTRACT.md Normal file
View file

@ -0,0 +1 @@
See [BOOLEAN_OPPERATIONS.md](BOOLEAN_OPPERATIONS.md "BOOLEAN_OPPERATIONS.md").

1
web/docs/Save.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/StlExport.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/TORUS.md Normal file
View file

@ -0,0 +1 @@
place holder

1
web/docs/UNION.md Normal file
View file

@ -0,0 +1 @@
See [BOOLEAN_OPPERATIONS.md](BOOLEAN_OPPERATIONS.md "BOOLEAN_OPPERATIONS.md").

30
web/docs/index.md Normal file
View file

@ -0,0 +1,30 @@
- ![](../img/cad/datum32.png)[DATUM_CREATE.md](DATUM_CREATE.md "DATUM_CREATE.md")
- ![](../img/cad/datum-move32.png)[DATUM_MOVE.md](DATUM_MOVE.md "DATUM_MOVE.md")
- ![](../img/cad/datum-rotate32.png)[DATUM_ROTATE.md](DATUM_ROTATE.md "DATUM_ROTATE.md")
- ![](../img/cad/plane32.png)[PLANE.md](PLANE.md "PLANE.md")
- ![](../img/cad/face-edit96.png)[EditFace.md](EditFace.md "EditFace.md")
- ![](../img/cad/revolve32.png)[REVOLVE.md](REVOLVE.md "REVOLVE.md")
- ![](../img/cad/cut32.png)[CUT.md](CUT.md "CUT.md")
- ![](../img/cad/fillet32.png)[FILLET.md](FILLET.md "FILLET.md")
- ![](../img/cad/xxxxxxxx.png)[ReassignSketch.md](ReassignSketch.md "ReassignSketch.md")
- ![](../img/cad/cylinder32.png)[CYLINDER.md](CYLINDER.md "CYLINDER.md")
- ![](../img/cad/cone32.png)[CONE.md](CONE.md "CONE.md")
- ![](../img/cad/sphere32.png)[SPHERE.md](SPHERE.md "SPHERE.md")
- ![](../img/cad/torus32.png)[TORUS.md](TORUS.md "TORUS.md")
- ![](../img/cad/union32.png)[UNION.md](UNION.md "UNION.md")
- ![](../img/cad/subtract32.png)[SUBTRACT.md](SUBTRACT.md "SUBTRACT.md")
- ![](../img/cad/intersection32.png)[INTERSECTION.md](INTERSECTION.md "INTERSECTION.md")
- ![](../img/cad/stl32.png)[StlExport.md](StlExport.md "StlExport.md")
- ![](../img/cad/cone32.png)[Save.md](Save.md "Save.md")
- [index.md](index.md "index.md")

View file

@ -29,7 +29,7 @@ module.exports = {
new webpack.HotModuleReplacementPlugin(),
],
resolve: {
extensions: ['.js', '.jsx'],
extensions: ['.js', '.jsx', ".ts", ".tsx"],
modules: [MODULES, "node_modules"]
},
devServer: {
@ -48,7 +48,7 @@ module.exports = {
},
module: {
rules: [{
test: /\.(js|jsx)$/,
test: /\.(js|jsx|ts|tsx)$/,
loader: 'babel-loader',
include: [MODULES, WEB_APP, INTEGRATION_TESTS]
}, {