Skip to content

Commit

Permalink
fix(remote loading) (jscad#275)
Browse files Browse the repository at this point in the history
- add standard (normal) url param parsing : ?uri=xxx
- remote url is renamed proxyUrl (in src/ui/index.js)
- can be set to undefined to disable use of proxy
- added back & cleaned up support for '#URL' remote & local
- added information about build commands & dev
- added explanation about use of proxies
  • Loading branch information
kaosat-dev authored Jun 3, 2017
1 parent b648b93 commit 5b02eab
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 25 deletions.
65 changes: 60 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ as well CLI (command-line interface) for server-side computations with NodeJS.
## Table of Contents

- [Usage](#usage)
- [Development](#development)
- [Documentation](#documentation)
- [Contribute](#contribute)
- [Community](#community)
Expand Down Expand Up @@ -43,6 +44,29 @@ And then access the contents via the URL of the web-site.

>NOTE: You might need configuration changes to allow access to the some of the contents (examples etc).
#### Use of proxies for remote file loading:

if you want the capability , just like the official OpenJSCAD.org site, to load remote projects/files directly
from the web based user interface, but without the hassle with CORS issues,
you can use a proxy file (see [remote.pl](./remote.pl) & [remote.php](./remote.php)):
this is a server side script that does the following
- caches the remote file locally on the server
- returns the local path to the downloaded file for OpenJSCAD to use

use and path of the proxy can be set by:
- changing the `proxyUrl` value in [src/ui/index.js](src/ui/index.js)
- since this is hardcoded , if you do not use the provided dev server,
rebuild your main file (npm run build-web etc, see [Development](#development))


then you can use it like so:
https://<YOURSITE>/?uri=http://www.thingiverse.com/download:164128
or
https://<YOURSITE>/#http://www.thingiverse.com/download:164128

>Note: a PR with a node.js based proxy would be a welcome addition :)

### Use as Command Line Interface (CLI)

For CLI(command-line interface) use
Expand Down Expand Up @@ -148,6 +172,42 @@ dependencies of **all** packages

This will be expanded upon in the future, and is the backbone of the newer, modular Jscad

## Development

We offer pre-built versions of OpenJSCAD to be uses directly here :
- [standard](./dist/index.js)
- [minimalist](./dist/min.js)
- [with options](./dist/options.js)

but you can also rebuild them manually if you need :

- standard: ```npm run build-web```
- minimalist: ```npm run build-min```
- with options: ```npm run build-opt```

### Adding new features in CSG.js or other modules:
Since OpenJSCAD is made up of multiple dependent modules (csg.js, openscad-openjscad-translator etc),
the easiest method is to use ```npm link``` to have a 'live' updating development version of OpenJSCAD:

For example for CSG.js
- create a base directory
- clone this repository ```git clone [email protected]:jscad/OpenJSCAD.org.git```
- go into OpenJSCAD.org folder ```cd OpenJSCAD.org```
- install dependencies ```npm install```
- start dev server : ```npm run start-dev```
- go back to base directory ```cd ..```
- clone CSG.js ```git clone [email protected]:jscad/csg.js.git```
- go into OpenJSCAD.org folder again ```cd OpenJSCAD.org```
- now type ```npm link ../csg.js/ @jscad/csg```

You can now make changes to the CSG.js code and see it impact your locally running
copy of OpenJSCAD live.

## Documentation

- [OpenJSCAD User & Programming Guide](https://en.wikibooks.org/wiki/OpenJSCAD_User_Guide)
- [OpenJSCAD Quick Reference](https://en.wikibooks.org/wiki/OpenJSCAD_Quick_Reference)

## Contribute

OpenJSCAD.org is part of the JSCAD Organization, and is maintained by a group of volunteers. We welcome and encourage anyone to pitch in but please take a moment to read the following guidelines.
Expand All @@ -164,11 +224,6 @@ OpenJSCAD.org is part of the JSCAD Organization, and is maintained by a group of

Small Note: If editing this README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.

## Documentation

- [OpenJSCAD User & Programming Guide](https://en.wikibooks.org/wiki/OpenJSCAD_User_Guide)
- [OpenJSCAD Quick Reference](https://en.wikibooks.org/wiki/OpenJSCAD_Quick_Reference)

## Community

See for more details
Expand Down
80 changes: 65 additions & 15 deletions src/ui/examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,61 @@ function fetchExample (filename, url, {memFs, gProcessor, gEditor}) {
}
}

const url = require('url')

function fetchUriParams (uri, paramName, defaultValue = undefined) {
let params = url.parse(uri, true)
let result = params.query
if (paramName in result) return result[paramName]
return defaultValue
}

// helper function to retrieve the nth element of an array
function nth (index, data) {
if (!data) {
return undefined
}
if (data.length < index) {
return undefined
}
return data[index]
}

function loadViaProxy (url, {memFs, gProcessor, gEditor, proxyUrl}) {
console.log('loadViaProxy', url, proxyUrl)
var xhr = new XMLHttpRequest()
xhr.open('GET', proxyUrl + url, true)
if (url.match(/\.(stl|gcode)$/i)) {
xhr.overrideMimeType('text/plain; charset=x-user-defined') // our pseudo binary retrieval (works with Chrome)
}
gProcessor.setStatus('loading', url)
xhr.onload = function () {
const data = JSON.parse(this.responseText)
console.log('data from proxy', data)
const baseUrl = location.protocol + '//' + location.host + location.pathname
const url = `${baseUrl}/${data.file}`
fetchExample(data.file, url, {memFs, gProcessor, gEditor})
// document.location = docUrl.replace(/#.*$/, '#') // this won't reload the entire web-page
}
xhr.send()
}

function loadInitialExample (me, params) {
if (me === 'web-online') { // we are online, fetch first example
const docUrl = document.URL
const isRemote = docUrl.match(/#(https?:\/\/\S+)$/)
const isLocal = docUrl.match(/#(examples\/\S+)$/)
if (me === 'web-online') {
const url = location.href

// const proxyPath = fetchUriParams(url, 'proxyPath', undefined)
const useProxy = params.proxyUrl !== undefined || document.URL.match(/#(https?:\/\/\S+)$/) !== null
const documentUri = fetchUriParams(url, 'uri', undefined) || nth(1, document.URL.match(/#(https?:\/\/\S+)$/)) || nth(1, document.URL.match(/#(examples\/\S+)$/))
const baseUrl = location.protocol + '//' + location.host + location.pathname

const isRemote = documentUri ? documentUri.match(/(https?:\/\/\S+)$/) !== null : false
const isLocal = documentUri ? documentUri.match(/(examples\/\S+)$/)!== null : false
const isInLocalStorage = localStorage.editorContent && localStorage.editorContent.length

//console.log('useProxy', useProxy, 'documentUri', documentUri, 'baseUrl', baseUrl)
//console.log('isRemote', isRemote, 'isLocal', isLocal)

function loadLocalStorage (content, {gProcessor, gEditor}) {
// load content from local storage if found
if (content && content.length) {
Expand All @@ -156,25 +204,27 @@ function loadInitialExample (me, params) {
}

function loadLocal (filename, {memFs, gProcessor, gEditor}) {
console.log('loadLocal')
//console.log('loadLocal')
fetchExample(filename, undefined, {memFs, gProcessor, gEditor})
document.location = docUrl.replace(/#.*$/, '#')
// document.location = docUrl.replace(/#.*$/, '#')
}

function loadRemote (u, {memFs, gProcessor, gEditor, remoteUrl}) {
console.log('loadRemote')
gProcessor.setStatus('loading', u)
fetchExample(u.replace(/^.+\//, ''), u, {memFs, gProcessor, gEditor})
document.location = docUrl.replace(/#.*$/, '#') // this won't reload the entire web-page
function loadRemote (url, {memFs, gProcessor, gEditor, proxyUrl}) {
//console.log('loadRemote', url)
gProcessor.setStatus('loading', url)
if (useProxy) {
loadViaProxy(url, {memFs, gProcessor, gEditor, proxyUrl})
} else {
fetchExample(url.replace(/^.+\//, ''), url, {memFs, gProcessor, gEditor})
}
// document.location = baseUrl// docUrl.replace(/#.*$/, '#') // this won't reload the entire web-page
}

if (isRemote) // remote file referenced, e.g. http://openjscad.org/#http://somewhere/something.ext
{
const u = isRemote[1] // RegExp.$1
loadRemote(u, params)
loadRemote(documentUri, params)
} else if (isLocal) { // local example, e.g. http://openjscad.org/#examples/example001.jscad
const filename = isLocal[1] // RegExp.$1
loadLocal(filename, params)
loadLocal(documentUri, params)
} else if (isInLocalStorage) {
loadLocalStorage(localStorage.editorContent, params)
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/ui/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ const Processor = require('../jscad/processor')
const me = document.location.toString().match(/^file:/) ? 'web-offline' : 'web-online'
const browser = detectBrowser()

var showEditor = true
var remoteUrl = './remote.pl?url='
// var remoteUrl = './remote.php?url='
const showEditor = true
const proxyUrl = './remote.pl?url='
// const proxyUrl = './remote.php?url='

var gProcessor = null
var gEditor = null

var memFs = [] // associated array, contains file content in source memFs[i].{name,source}
var currentFiles = [] // linear array, contains files (to read)


function getElementHeight (element) {
return parseInt(getComputedStyle(element).height)
}
Expand Down Expand Up @@ -101,7 +101,7 @@ function init () {
let examples = document.getElementById('examples');
if (examples) {
createExamples(me)
loadInitialExample(me, {memFs, gProcessor, gEditor, remoteUrl})
loadInitialExample(me, {memFs, gProcessor, gEditor, proxyUrl})

// -- Examples
examplesTitle.addEventListener('click', function (e) {
Expand Down

0 comments on commit 5b02eab

Please sign in to comment.