mirror of
https://github.com/enso-org/enso.git
synced 2025-01-03 12:34:06 +03:00
Introducing single config for prettier and applying it across the codebase. (#3141)
This commit is contained in:
parent
22cefa7659
commit
e18322e802
@ -13,5 +13,5 @@ distribution/lib/Standard/Database/*/THIRD-PARTY
|
||||
built-distribution/
|
||||
THIRD-PARTY
|
||||
|
||||
# GUI has its own config in the subdirectory.
|
||||
gui/
|
||||
gui/dist/
|
||||
**/scala-parser.js
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"proseWrap": "always"
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
overrides:
|
||||
|
||||
- files: "*.[j|t]s"
|
||||
options:
|
||||
printWidth: 100
|
11
gui/.github/ISSUE_TEMPLATE/bug-report.md
vendored
11
gui/.github/ISSUE_TEMPLATE/bug-report.md
vendored
@ -1,10 +1,9 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug in Enso IDE.
|
||||
title: ''
|
||||
labels: 'Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
title: ""
|
||||
labels: "Type: Bug"
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
<!--
|
||||
@ -13,22 +12,26 @@ the bug! It may have been fixed since.
|
||||
-->
|
||||
|
||||
### What did you do?
|
||||
|
||||
<!--
|
||||
If possible, provide a recipe for reproducing the bug.
|
||||
-->
|
||||
|
||||
### What did you expect to see?
|
||||
|
||||
<!--
|
||||
- A description of the results you expected to get from the recipe above.
|
||||
-->
|
||||
|
||||
### What did you see instead?
|
||||
|
||||
<!--
|
||||
- A description of what actually happens when you perform these steps.
|
||||
- Please include any error output if relevant.
|
||||
-->
|
||||
|
||||
### Enso Version
|
||||
|
||||
<!--
|
||||
- Please include the version of Enso IDE you are using here.
|
||||
-->
|
||||
|
11
gui/.github/ISSUE_TEMPLATE/epic.md
vendored
11
gui/.github/ISSUE_TEMPLATE/epic.md
vendored
@ -1,30 +1,33 @@
|
||||
---
|
||||
name: Epic
|
||||
about: Create a new epic for Enso IDE development.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
title: ""
|
||||
labels: ""
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
### Summary
|
||||
|
||||
<!--
|
||||
- This section should summarise the work we want to accomplish during the epic.
|
||||
-->
|
||||
|
||||
### Value
|
||||
|
||||
<!--
|
||||
- A description of the value this epic brings to users.
|
||||
- The motivation behind this epic.
|
||||
-->
|
||||
|
||||
### Specification
|
||||
|
||||
<!--
|
||||
- The high-level requirements of the epic.
|
||||
- Any performance requirements for the epic.
|
||||
-->
|
||||
|
||||
### Acceptance Criteria & Test Cases
|
||||
|
||||
<!--
|
||||
- The high-level acceptance criteria for the epic.
|
||||
- The test plan for the epic.
|
||||
|
@ -1,10 +1,9 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Request a new feature in Enso IDE.
|
||||
title: ''
|
||||
labels: 'Type: Enhancement'
|
||||
assignees: ''
|
||||
|
||||
title: ""
|
||||
labels: "Type: Enhancement"
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
<!--
|
||||
@ -13,11 +12,13 @@ has been implemented.
|
||||
-->
|
||||
|
||||
### General Summary
|
||||
|
||||
<!--
|
||||
- Describe the feature you are requesting.
|
||||
-->
|
||||
|
||||
### Motivation
|
||||
|
||||
<!--
|
||||
- A description of the motivation for adding this feature to Enso IDE.
|
||||
- Ideally this would include use-cases that support the feature.
|
||||
|
11
gui/.github/ISSUE_TEMPLATE/task.md
vendored
11
gui/.github/ISSUE_TEMPLATE/task.md
vendored
@ -1,30 +1,33 @@
|
||||
---
|
||||
name: Task
|
||||
about: Create a new development task for Enso IDE.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
title: ""
|
||||
labels: ""
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
### Summary
|
||||
|
||||
<!--
|
||||
- A summary of the task.
|
||||
-->
|
||||
|
||||
### Value
|
||||
|
||||
<!--
|
||||
- This section should describe the value of this task.
|
||||
- This value can be for users, to the team, etc.
|
||||
-->
|
||||
|
||||
### Specification
|
||||
|
||||
<!--
|
||||
- Detailed requirements for the feature.
|
||||
- The performance requirements for the feature.
|
||||
-->
|
||||
|
||||
### Acceptance Criteria & Test Cases
|
||||
|
||||
<!--
|
||||
- Any criteria that must be satisfied for the task to be accepted.
|
||||
- The test plan for the feature, related to the acceptance criteria.
|
||||
|
13
gui/.github/PULL_REQUEST_TEMPLATE.md
vendored
13
gui/.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,24 +1,31 @@
|
||||
### Pull Request Description
|
||||
|
||||
<!--
|
||||
- Please describe the nature of your PR here, as well as the motivation for it.
|
||||
- If it fixes an open issue, please mention that issue number here.
|
||||
-->
|
||||
|
||||
### Important Notes
|
||||
|
||||
<!--
|
||||
- Mention important elements of the design.
|
||||
- Mention any notable changes to APIs.
|
||||
-->
|
||||
|
||||
### Checklist
|
||||
|
||||
Please include the following checklist in your PR:
|
||||
|
||||
- [ ] The `CHANGELOG.md` was updated with the changes introduced in this PR.
|
||||
- [ ] The documentation has been updated if necessary.
|
||||
- [ ] All code conforms to the [Rust](https://github.com/enso-org/enso/blob/develop/docs/style-guide/rust.md) style guide.
|
||||
- [ ] All code conforms to the
|
||||
[Rust](https://github.com/enso-org/enso/blob/develop/docs/style-guide/rust.md)
|
||||
style guide.
|
||||
- [ ] All code has automatic tests where possible.
|
||||
- [ ] All code has been profiled where possible.
|
||||
- [ ] All code has been manually tested in the IDE.
|
||||
- [ ] All code has been manually tested in the "debug/interface" scene.
|
||||
- [ ] All code has been manually tested by the PR owner against our [test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
||||
- [ ] All code has been manually tested by at least one reviewer against our [test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
||||
- [ ] All code has been manually tested by the PR owner against our
|
||||
[test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
||||
- [ ] All code has been manually tested by at least one reviewer against our
|
||||
[test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
||||
|
6
gui/.github/workflows/docs.yml
vendored
6
gui/.github/workflows/docs.yml
vendored
@ -5,7 +5,7 @@ on:
|
||||
branches:
|
||||
- develop
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- "docs/**"
|
||||
|
||||
jobs:
|
||||
checkout:
|
||||
@ -13,8 +13,8 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'enso-org/enso-org.github.io'
|
||||
ref: 'sources'
|
||||
repository: "enso-org/enso-org.github.io"
|
||||
ref: "sources"
|
||||
token: ${{ secrets.ENSO_PAT }}
|
||||
- name: set identity email
|
||||
run: git config --global user.email "actions@github.com"
|
||||
|
@ -1,2 +0,0 @@
|
||||
**/lib/**/*.js
|
||||
**/target/*
|
@ -4,11 +4,13 @@ const exec = require('child_process').exec
|
||||
|
||||
function download(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
https.get(url,(res) => {
|
||||
let data = ""
|
||||
res.on("data", (chunk) => data += chunk)
|
||||
res.on("end", () => resolve(data))
|
||||
}).on("error", (error) => reject(error))
|
||||
https
|
||||
.get(url, res => {
|
||||
let data = ''
|
||||
res.on('data', chunk => (data += chunk))
|
||||
res.on('end', () => resolve(data))
|
||||
})
|
||||
.on('error', error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
@ -37,7 +39,7 @@ function run(cmd,args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log(`Calling '${cmd} ${args.join(' ')}'`)
|
||||
let proc = spawn(cmd, args, { stdio: 'inherit', shell: true })
|
||||
proc.on('exit', (code) => {
|
||||
proc.on('exit', code => {
|
||||
if (code) process.exit(code)
|
||||
resolve(out)
|
||||
})
|
||||
@ -49,19 +51,25 @@ function run_read(cmd,args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let proc = spawn(cmd, args, { shell: true })
|
||||
proc.stderr.pipe(process.stderr)
|
||||
proc.stdout.on('data', (data) => { out += data })
|
||||
proc.on('exit', (code) => {
|
||||
if (code) process.exit(code);
|
||||
proc.stdout.on('data', data => {
|
||||
out += data
|
||||
})
|
||||
proc.on('exit', code => {
|
||||
if (code) process.exit(code)
|
||||
resolve(out)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function check_version(name, required, cfg) {
|
||||
if (!cfg) { cfg = {} }
|
||||
if (!cfg) {
|
||||
cfg = {}
|
||||
}
|
||||
let version = await run_read(name, ['--version'])
|
||||
version = version.trim()
|
||||
if (cfg.preprocess) { version = cfg.preprocess(version) }
|
||||
if (cfg.preprocess) {
|
||||
version = cfg.preprocess(version)
|
||||
}
|
||||
if (cfg.silent !== true) {
|
||||
console.log(`Checking if '${name}' version is '${required}'.`)
|
||||
}
|
||||
@ -96,12 +104,21 @@ async function get_node_lts_version() {
|
||||
}
|
||||
}
|
||||
if (!newest) {
|
||||
throw "Cannot fetch the info about node LTS version."
|
||||
throw 'Cannot fetch the info about node LTS version.'
|
||||
}
|
||||
let node = newest.version
|
||||
let npm = newest.npm
|
||||
return [node, npm]
|
||||
}
|
||||
|
||||
module.exports = {section,run,run_read,check_version,get_npm_info,get_npm_lts_version_of,with_cwd,
|
||||
get_node_dist_index,get_node_lts_version}
|
||||
module.exports = {
|
||||
section,
|
||||
run,
|
||||
run_read,
|
||||
check_version,
|
||||
get_npm_info,
|
||||
get_npm_lts_version_of,
|
||||
with_cwd,
|
||||
get_node_dist_index,
|
||||
get_node_lts_version,
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Paths ===
|
||||
// =============
|
||||
@ -59,7 +57,7 @@ function get_project_manager_extension() {
|
||||
}
|
||||
|
||||
paths.get_project_manager_path = function (root) {
|
||||
let base_path = path.join(root, 'enso', 'bin',)
|
||||
let base_path = path.join(root, 'enso', 'bin')
|
||||
const extension = get_project_manager_extension()
|
||||
return path.join(base_path, 'project-manager') + extension
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ const paths = require('./paths')
|
||||
const semver = require('semver')
|
||||
const config = require('../config')
|
||||
|
||||
|
||||
|
||||
// =================
|
||||
// === Constants ===
|
||||
// =================
|
||||
@ -17,8 +15,6 @@ const CHANGELOG_FILE_NAME = 'CHANGELOG.md'
|
||||
const CHANGELOG_FILE = path.join(paths.root, CHANGELOG_FILE_NAME)
|
||||
const ENGINE_VERSION = config.engineVersion
|
||||
|
||||
|
||||
|
||||
// ===============
|
||||
// === Version ===
|
||||
// ===============
|
||||
@ -26,7 +22,7 @@ const ENGINE_VERSION = config.engineVersion
|
||||
class NextReleaseVersion {
|
||||
/// Version used for config files when building the package with "next version" in changelog.
|
||||
toString() {
|
||||
return "0.0.0"
|
||||
return '0.0.0'
|
||||
}
|
||||
|
||||
isPrerelease() {
|
||||
@ -46,19 +42,39 @@ class Version {
|
||||
}
|
||||
|
||||
lt(that) {
|
||||
if (this.major < that.major) { return true }
|
||||
if (this.minor < that.minor) { return true }
|
||||
if (this.patch < that.patch) { return true }
|
||||
if (this.tag === 'alpha' && that.tag === 'beta') { return true }
|
||||
if (this.tag === 'alpha' && that.tag === 'rc') { return true }
|
||||
if (this.tag === 'beta' && that.tag === 'rc') { return true }
|
||||
if (this.tagVersion < that.tagVersion) { return true }
|
||||
if (this.rcTagVersion < that.rcTagVersion) { return true }
|
||||
if (this.major < that.major) {
|
||||
return true
|
||||
}
|
||||
if (this.minor < that.minor) {
|
||||
return true
|
||||
}
|
||||
if (this.patch < that.patch) {
|
||||
return true
|
||||
}
|
||||
if (this.tag === 'alpha' && that.tag === 'beta') {
|
||||
return true
|
||||
}
|
||||
if (this.tag === 'alpha' && that.tag === 'rc') {
|
||||
return true
|
||||
}
|
||||
if (this.tag === 'beta' && that.tag === 'rc') {
|
||||
return true
|
||||
}
|
||||
if (this.tagVersion < that.tagVersion) {
|
||||
return true
|
||||
}
|
||||
if (this.rcTagVersion < that.rcTagVersion) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
isPrerelease() {
|
||||
if (this.tag) { return true } else { return false }
|
||||
if (this.tag) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
@ -73,8 +89,6 @@ class Version {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ======================
|
||||
// === ChangelogEntry ===
|
||||
// ======================
|
||||
@ -94,14 +108,14 @@ class ChangelogEntry {
|
||||
assert_is_unstable() {
|
||||
this.assert_is_newest_version_defined()
|
||||
if (!this.isPrerelease()) {
|
||||
throw "Assertion failed. The version is stable."
|
||||
throw 'Assertion failed. The version is stable.'
|
||||
}
|
||||
}
|
||||
|
||||
assert_is_stable() {
|
||||
this.assert_is_newest_version_defined()
|
||||
if (this.isPrerelease()) {
|
||||
throw "Assertion failed. The version is unstable."
|
||||
throw 'Assertion failed. The version is unstable.'
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,8 +124,6 @@ class ChangelogEntry {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =================
|
||||
// === Changelog ===
|
||||
// =================
|
||||
@ -131,9 +143,9 @@ class Changelog {
|
||||
}
|
||||
|
||||
function changelogSections() {
|
||||
let text = '\n' + fss.readFileSync(CHANGELOG_FILE,"utf8")
|
||||
let text = '\n' + fss.readFileSync(CHANGELOG_FILE, 'utf8')
|
||||
let chunks = text.split(/\r?\n#(?!#)/)
|
||||
return chunks.filter((s) => s != '')
|
||||
return chunks.filter(s => s != '')
|
||||
}
|
||||
|
||||
function changelogEntries() {
|
||||
@ -145,16 +157,25 @@ function changelogEntries() {
|
||||
let header = section.substring(0, splitPoint)
|
||||
let body = section.substring(splitPoint).trim()
|
||||
if (firstSection && header.startsWith(' Next Release')) {
|
||||
let version = new NextReleaseVersion
|
||||
let version = new NextReleaseVersion()
|
||||
entries.push(new ChangelogEntry(version, body))
|
||||
} else {
|
||||
let headerReg = /^ Enso (?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)(-(?<tag>alpha|beta|rc)\.(?<tagVersion>[0-9]+))?(.(?<rcTag>rc)\.(?<rcTagVersion>[0-9]+))? \((?<year>[0-9][0-9][0-9][0-9])-(?<month>[0-9][0-9])-(?<day>[0-9][0-9])\)/
|
||||
let headerReg =
|
||||
/^ Enso (?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)(-(?<tag>alpha|beta|rc)\.(?<tagVersion>[0-9]+))?(.(?<rcTag>rc)\.(?<rcTagVersion>[0-9]+))? \((?<year>[0-9][0-9][0-9][0-9])-(?<month>[0-9][0-9])-(?<day>[0-9][0-9])\)/
|
||||
let match = header.match(headerReg)
|
||||
if (!match) {
|
||||
throw `Improper changelog entry header: '${header}'. See the 'CHANGELOG_TEMPLATE.md' for details.`
|
||||
}
|
||||
let grps = match.groups
|
||||
let version = new Version(grps.major,grps.minor,grps.patch,grps.tag,grps.tagVersion,grps.rcTag,grps.rcTagVersion)
|
||||
let version = new Version(
|
||||
grps.major,
|
||||
grps.minor,
|
||||
grps.patch,
|
||||
grps.tag,
|
||||
grps.tagVersion,
|
||||
grps.rcTag,
|
||||
grps.rcTagVersion
|
||||
)
|
||||
entries.push(new ChangelogEntry(version, body))
|
||||
}
|
||||
firstSection = false
|
||||
@ -179,15 +200,13 @@ function changelogEntries() {
|
||||
}
|
||||
|
||||
function changelog() {
|
||||
return new Changelog
|
||||
return new Changelog()
|
||||
}
|
||||
|
||||
function currentVersion() {
|
||||
return changelog().currentVersion()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ===============
|
||||
// === Exports ===
|
||||
// ===============
|
||||
|
168
gui/build/run.js
168
gui/build/run.js
@ -9,7 +9,7 @@ const ncp = require('ncp').ncp
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const paths = require('./paths')
|
||||
const prettier = require("prettier")
|
||||
const prettier = require('prettier')
|
||||
const release = require('./release')
|
||||
const stream = require('stream')
|
||||
const workflow = require('./workflow')
|
||||
@ -18,17 +18,15 @@ const zlib = require('zlib')
|
||||
const { promisify } = require('util')
|
||||
const pipe = promisify(stream.pipeline)
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Errors ===
|
||||
// ==============
|
||||
|
||||
process.on('unhandledRejection', error => { throw(error) })
|
||||
process.on('unhandledRejection', error => {
|
||||
throw error
|
||||
})
|
||||
process.chdir(paths.root)
|
||||
|
||||
|
||||
|
||||
// ========================
|
||||
// === Global Variables ===
|
||||
// ========================
|
||||
@ -41,8 +39,6 @@ let cargoArgs = undefined
|
||||
// command line args get parsed.
|
||||
let targetArgs = undefined
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Utils ===
|
||||
// =============
|
||||
@ -57,8 +53,10 @@ async function gzip(input, output) {
|
||||
/// Copy files and directories.
|
||||
async function copy(src, tgt) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ncp(src,tgt,(err) => {
|
||||
if (err) { reject(`${err}`) }
|
||||
ncp(src, tgt, err => {
|
||||
if (err) {
|
||||
reject(`${err}`)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
@ -74,7 +72,6 @@ async function run(command,args) {
|
||||
await cmd.run(command, args)
|
||||
}
|
||||
|
||||
|
||||
/// Defines a new command argument builder.
|
||||
function command(docs) {
|
||||
return { docs }
|
||||
@ -103,8 +100,6 @@ function run_project_manager() {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Commands ===
|
||||
// ================
|
||||
@ -112,7 +107,6 @@ function run_project_manager() {
|
||||
const DEFAULT_CRATE = 'ide'
|
||||
let commands = {}
|
||||
|
||||
|
||||
// === Clean ===
|
||||
|
||||
commands.clean = command(`Clean all build artifacts`)
|
||||
@ -130,7 +124,6 @@ commands.clean.rust = async function() {
|
||||
await run_cargo('cargo', ['clean'])
|
||||
}
|
||||
|
||||
|
||||
// === Check ===
|
||||
|
||||
commands.check = command(`Fast check if project builds (only Rust target)`)
|
||||
@ -138,15 +131,14 @@ commands.check.rust = async function() {
|
||||
await run_cargo('cargo', ['check'])
|
||||
}
|
||||
|
||||
|
||||
// === Build ===
|
||||
|
||||
commands.build = command(`Build the sources in release mode`)
|
||||
commands.build.options = {
|
||||
'crate': {
|
||||
crate: {
|
||||
describe: 'Target crate to build',
|
||||
type: 'string',
|
||||
}
|
||||
},
|
||||
}
|
||||
commands.build.js = async function () {
|
||||
await installJsDeps()
|
||||
@ -158,8 +150,19 @@ commands.build.rust = async function(argv) {
|
||||
let crate = argv.crate || DEFAULT_CRATE
|
||||
let crate_sfx = crate ? ` '${crate}'` : ``
|
||||
console.log(`Building WASM target${crate_sfx}.`)
|
||||
let args = ['build','--target','web','--out-dir',paths.dist.wasm.root,'--out-name','ide',crate]
|
||||
if (argv.dev) { args.push('--dev') }
|
||||
let args = [
|
||||
'build',
|
||||
'--target',
|
||||
'web',
|
||||
'--out-dir',
|
||||
paths.dist.wasm.root,
|
||||
'--out-name',
|
||||
'ide',
|
||||
crate,
|
||||
]
|
||||
if (argv.dev) {
|
||||
args.push('--dev')
|
||||
}
|
||||
await run_cargo('wasm-pack', args)
|
||||
await patch_file(paths.dist.wasm.glue, js_workaround_patcher)
|
||||
await fs.rename(paths.dist.wasm.mainRaw, paths.dist.wasm.main)
|
||||
@ -173,10 +176,10 @@ commands.build.rust = async function(argv) {
|
||||
|
||||
console.log('Checking the resulting WASM size.')
|
||||
let stats = fss.statSync(paths.dist.wasm.mainOptGz)
|
||||
let limit = 4.60
|
||||
let size = Math.round(100 * stats.size / 1024 / 1024) / 100
|
||||
let limit = 4.6
|
||||
let size = Math.round((100 * stats.size) / 1024 / 1024) / 100
|
||||
if (size > limit) {
|
||||
throw(`Output file size exceeds the limit (${size}MB > ${limit}MB).`)
|
||||
throw `Output file size exceeds the limit (${size}MB > ${limit}MB).`
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,7 +189,7 @@ function js_workaround_patcher(code) {
|
||||
code = code.replace(/if \(\(typeof URL.*}\);/gs, 'return imports')
|
||||
code = code.replace(/if \(typeof module.*let result/gs, 'let result')
|
||||
code = code.replace(/export default init;/gs, 'export default init')
|
||||
code += '\nexport function after_load\(w,m\) { wasm = w; init.__wbindgen_wasm_module = m;}'
|
||||
code += '\nexport function after_load(w,m) { wasm = w; init.__wbindgen_wasm_module = m;}'
|
||||
return code
|
||||
}
|
||||
|
||||
@ -196,7 +199,6 @@ async function patch_file(path,patcher) {
|
||||
await fs.writeFile(path, patched_code)
|
||||
}
|
||||
|
||||
|
||||
// === Start ===
|
||||
|
||||
commands.start = command(`Build and start desktop client`)
|
||||
@ -211,14 +213,17 @@ commands.start.js = async function (argv) {
|
||||
// The backend path is being prepended here, as appending would be incorrect.
|
||||
// That is because `targetArgs` might include `-- …` and appended args could
|
||||
// end up being passed to the spawned backend process.
|
||||
const args = ['--backend-path', paths.get_project_manager_path(paths.dist.bin)].concat(targetArgs)
|
||||
if (argv.dev) { args.push('--dev') }
|
||||
const args = ['--backend-path', paths.get_project_manager_path(paths.dist.bin)].concat(
|
||||
targetArgs
|
||||
)
|
||||
if (argv.dev) {
|
||||
args.push('--dev')
|
||||
}
|
||||
await cmd.with_cwd(paths.js.root, async () => {
|
||||
await run('npm', ['run', 'start', '--'].concat(args))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// === Test ===
|
||||
|
||||
commands.test = command(`Run test suites`)
|
||||
@ -230,12 +235,19 @@ commands.test.rust = async function(argv) {
|
||||
|
||||
if (argv.wasm) {
|
||||
console.log(`Running Rust WASM test suite.`)
|
||||
let args = ['run','--manifest-path=test/Cargo.toml','--bin','test_all','--','--headless','--chrome']
|
||||
let args = [
|
||||
'run',
|
||||
'--manifest-path=test/Cargo.toml',
|
||||
'--bin',
|
||||
'test_all',
|
||||
'--',
|
||||
'--headless',
|
||||
'--chrome',
|
||||
]
|
||||
await run_cargo('cargo', args)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Lint ===
|
||||
|
||||
commands.lint = command(`Lint the codebase`)
|
||||
@ -244,23 +256,21 @@ commands.lint.rust = async function() {
|
||||
await run_cargo('cargo', ['fmt', '--', '--check'])
|
||||
}
|
||||
|
||||
|
||||
// === TomlFmt ===
|
||||
|
||||
commands['toml-fmt'] = command(`Lint the codebase`)
|
||||
commands['toml-fmt'].rust = async function () {
|
||||
console.log("Looking for all TOML files.")
|
||||
let files = glob.sync(paths.rust.root + "/**/*.toml", {cwd:paths.root});
|
||||
console.log('Looking for all TOML files.')
|
||||
let files = glob.sync(paths.rust.root + '/**/*.toml', { cwd: paths.root })
|
||||
console.log(`Found ${files.length} entries. Running auto-formatter.`)
|
||||
for (let file of files) {
|
||||
console.log(` Formatting '${file}'.`)
|
||||
let text = fss.readFileSync(file, "utf8")
|
||||
let text = fss.readFileSync(file, 'utf8')
|
||||
let out = prettier.format(text, { parser: 'toml' })
|
||||
fss.writeFileSync(file, out)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Watch ===
|
||||
|
||||
commands.watch = command(`Start a file-watch utility and run interactive mode`)
|
||||
@ -279,7 +289,7 @@ commands.watch.common = async function(argv) {
|
||||
// Run build processes.
|
||||
|
||||
await cmd.with_cwd(paths.rust.root, async () => {
|
||||
return commands.build.rust(argv);
|
||||
return commands.build.rust(argv)
|
||||
})
|
||||
await cmd.with_cwd(paths.js.root, async () => {
|
||||
// Among other things, this will call the build script of the project-manager package. But
|
||||
@ -305,14 +315,13 @@ commands.watch.common = async function(argv) {
|
||||
return cmd.run('cargo', args)
|
||||
})
|
||||
const js_process = cmd.with_cwd(paths.js.root, async () => {
|
||||
return run('npm',['run','watch']);
|
||||
return run('npm', ['run', 'watch'])
|
||||
})
|
||||
|
||||
await rust_process
|
||||
await js_process
|
||||
}
|
||||
|
||||
|
||||
// === Dist ===
|
||||
|
||||
commands.dist = command(`Build the sources and create distribution packages`)
|
||||
@ -327,7 +336,6 @@ commands.dist.js = async function() {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// === CI Gen ===
|
||||
|
||||
/// The command is used by CI to generate the file `CURRENT_RELEASE_CHANGELOG.json`, which contains
|
||||
@ -339,7 +347,7 @@ commands['ci-gen'].rust = async function(argv) {
|
||||
let body = entry.body
|
||||
let version = entry.version.toString()
|
||||
let prerelease = entry.isPrerelease()
|
||||
let obj = {version,body,prerelease};
|
||||
let obj = { version, body, prerelease }
|
||||
let json = JSON.stringify(obj)
|
||||
fss.writeFileSync(path.join(paths.root, 'CURRENT_RELEASE_CHANGELOG.json'), json)
|
||||
}
|
||||
@ -356,8 +364,6 @@ commands['assert-version-stable'].rust = async function(argv) {
|
||||
let entry = release.changelog().newestEntry().assert_is_stable()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ===========================
|
||||
// === Command Line Parser ===
|
||||
// ===========================
|
||||
@ -370,7 +376,7 @@ For example, 'run start -- --dev -- --debug-scene shapes' will pass '--dev' to c
|
||||
and '--debug-scene shapes' to the output binary.`
|
||||
|
||||
let optParser = yargs
|
||||
.scriptName("")
|
||||
.scriptName('')
|
||||
.usage(usage)
|
||||
.help()
|
||||
.parserConfiguration({ 'populate--': true })
|
||||
@ -379,22 +385,22 @@ let optParser = yargs
|
||||
optParser.options('rust', {
|
||||
describe: 'Run the Rust target',
|
||||
type: 'bool',
|
||||
default : true
|
||||
default: true,
|
||||
})
|
||||
|
||||
optParser.options('js', {
|
||||
describe: 'Run the JavaScript target',
|
||||
type: 'bool',
|
||||
default : true
|
||||
default: true,
|
||||
})
|
||||
|
||||
optParser.options('release', {
|
||||
describe : "Enable all optimizations",
|
||||
describe: 'Enable all optimizations',
|
||||
type: 'bool',
|
||||
})
|
||||
|
||||
optParser.options('dev', {
|
||||
describe : "Optimize for fast builds",
|
||||
describe: 'Optimize for fast builds',
|
||||
type: 'bool',
|
||||
})
|
||||
|
||||
@ -415,7 +421,7 @@ let commandList = Object.keys(commands)
|
||||
commandList.sort()
|
||||
for (let command of commandList) {
|
||||
let config = commands[command]
|
||||
optParser.command(command,config.docs,(args) => {
|
||||
optParser.command(command, config.docs, args => {
|
||||
for (let option in config.options) {
|
||||
args.options(option, config.options[option])
|
||||
}
|
||||
@ -425,18 +431,16 @@ for (let command of commandList) {
|
||||
args.options('native', {
|
||||
describe: 'Run native tests',
|
||||
type: 'bool',
|
||||
default : true
|
||||
default: true,
|
||||
})
|
||||
args.options('wasm', {
|
||||
describe: 'Run WASM tests',
|
||||
type: 'bool',
|
||||
default : true
|
||||
default: true,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ======================
|
||||
// === Package Config ===
|
||||
// ======================
|
||||
@ -445,24 +449,24 @@ function defaultConfig() {
|
||||
return {
|
||||
version: `${release.currentVersion()}`,
|
||||
author: {
|
||||
name: "Enso Team",
|
||||
email: "contact@enso.org"
|
||||
name: 'Enso Team',
|
||||
email: 'contact@enso.org',
|
||||
},
|
||||
homepage: "https://github.com/enso-org/ide",
|
||||
homepage: 'https://github.com/enso-org/ide',
|
||||
repository: {
|
||||
type: "git",
|
||||
url: "git@github.com:enso-org/ide.git"
|
||||
type: 'git',
|
||||
url: 'git@github.com:enso-org/ide.git',
|
||||
},
|
||||
bugs: {
|
||||
url: "https://github.com/enso-org/ide/issues"
|
||||
url: 'https://github.com/enso-org/ide/issues',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async function processPackageConfigs() {
|
||||
let files = []
|
||||
files = files.concat(glob.sync(paths.js.root + "/package.js", {cwd:paths.root}))
|
||||
files = files.concat(glob.sync(paths.js.root + "/lib/*/package.js", {cwd:paths.root}))
|
||||
files = files.concat(glob.sync(paths.js.root + '/package.js', { cwd: paths.root }))
|
||||
files = files.concat(glob.sync(paths.js.root + '/lib/*/package.js', { cwd: paths.root }))
|
||||
for (file of files) {
|
||||
let dirPath = path.dirname(file)
|
||||
let outPath = path.join(dirPath, 'package.json')
|
||||
@ -471,14 +475,14 @@ async function processPackageConfigs() {
|
||||
let fn = new Function('require', 'paths', modSrc)
|
||||
let mod = fn(require, paths)
|
||||
let config = mod.config
|
||||
if (!config) { throw(`Package config '${file}' do not export 'module.config'.`) }
|
||||
if (!config) {
|
||||
throw `Package config '${file}' do not export 'module.config'.`
|
||||
}
|
||||
config = Object.assign(defaultConfig(), config)
|
||||
fs.writeFile(outPath, JSON.stringify(config, undefined, 4))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Main ===
|
||||
// ============
|
||||
@ -493,11 +497,7 @@ async function updateBuildVersion (argv) {
|
||||
config = JSON.parse(configFile)
|
||||
}
|
||||
|
||||
let commitHashCmd = await cmd.run_read('git', [
|
||||
'rev-parse',
|
||||
'--short',
|
||||
'HEAD'
|
||||
])
|
||||
let commitHashCmd = await cmd.run_read('git', ['rev-parse', '--short', 'HEAD'])
|
||||
let commitHash = commitHashCmd.trim()
|
||||
|
||||
if (config.buildVersion !== commitHash || config.target !== target) {
|
||||
@ -506,7 +506,6 @@ async function updateBuildVersion (argv) {
|
||||
await fs.mkdir(paths.dist.root, { recursive: true })
|
||||
await fs.writeFile(configPath, JSON.stringify(config, undefined, 2))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function installJsDeps() {
|
||||
@ -556,12 +555,13 @@ async function runCommand(command, argv) {
|
||||
console.error(`Invalid command '${command}'.`)
|
||||
return
|
||||
}
|
||||
if(cargoArgs === undefined) { cargoArgs = [] }
|
||||
if (cargoArgs === undefined) {
|
||||
cargoArgs = []
|
||||
}
|
||||
let index = cargoArgs.indexOf('--')
|
||||
if (index == -1) {
|
||||
targetArgs = []
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
targetArgs = cargoArgs.slice(index + 1)
|
||||
cargoArgs = cargoArgs.slice(0, index)
|
||||
}
|
||||
@ -575,14 +575,26 @@ async function runCommand(command, argv) {
|
||||
let jsCmd = () => cmd.with_cwd(paths.js.root, async () => await config.js(argv))
|
||||
if (config.parallel) {
|
||||
let promises = []
|
||||
if (do_common ) { promises.push(commonCmd()) }
|
||||
if (do_rust) { promises.push(rustCmd()) }
|
||||
if (do_js) { promises.push(jsCmd()) }
|
||||
if (do_common) {
|
||||
promises.push(commonCmd())
|
||||
}
|
||||
if (do_rust) {
|
||||
promises.push(rustCmd())
|
||||
}
|
||||
if (do_js) {
|
||||
promises.push(jsCmd())
|
||||
}
|
||||
await Promise.all(promises)
|
||||
} else {
|
||||
if (do_common) { await commonCmd() }
|
||||
if (do_rust) { await rustCmd() }
|
||||
if (do_js) { await jsCmd() }
|
||||
if (do_common) {
|
||||
await commonCmd()
|
||||
}
|
||||
if (do_rust) {
|
||||
await rustCmd()
|
||||
}
|
||||
if (do_js) {
|
||||
await jsCmd()
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd.section(command)
|
||||
|
@ -129,8 +129,8 @@ let installClippy = {
|
||||
}
|
||||
|
||||
let installFmt = {
|
||||
name: "Install Clippy",
|
||||
run: "rustup component add rustfmt"
|
||||
name: 'Install Clippy',
|
||||
run: 'rustup component add rustfmt',
|
||||
}
|
||||
|
||||
// Install fixed version to avoid upgrading to a breaking version.
|
||||
@ -424,8 +424,7 @@ let assertReleaseDoNotExists = [
|
||||
|
||||
assertNoSquashCommitForRelease = {
|
||||
name: `Fail if squash commit to the 'unstable' or the 'stable' branch.`,
|
||||
run:
|
||||
'if [[ "${{ github.base_ref }}" == "unstable" || "${{ github.base_ref }}" == "stable" ]]; then exit 1; fi',
|
||||
run: 'if [[ "${{ github.base_ref }}" == "unstable" || "${{ github.base_ref }}" == "stable" ]]; then exit 1; fi',
|
||||
}
|
||||
|
||||
let assertions = list(
|
||||
|
@ -1,72 +1,96 @@
|
||||
# Next Release
|
||||
This update contains major performance improvements and exposes new privacy user settings. We will
|
||||
work towards stabilizing it in the next weeks in order to make these updates be shipped in a stable
|
||||
release before the end of the year.
|
||||
|
||||
This update contains major performance improvements and exposes new privacy user
|
||||
settings. We will work towards stabilizing it in the next weeks in order to make
|
||||
these updates be shipped in a stable release before the end of the year.
|
||||
|
||||
<br/>![New Features](/docs/assets/tags/new_features.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
<br/>![Bug Fixes](/docs/assets/tags/bug_fixes.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
<br/>![Release Notes](/docs/assets/tags/release_notes.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
[79270]: http://github.com/ticket
|
||||
[79271]: http://github.com/ticket
|
||||
@ -74,79 +98,102 @@ release before the end of the year.
|
||||
[79273]: http://github.com/ticket
|
||||
[79274]: http://github.com/ticket
|
||||
[79275]: http://github.com/ticket
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
# Enso 47.0.0-alpha.8 (2049-01-22)
|
||||
This update contains major performance improvements and exposes new privacy user settings. We will
|
||||
work towards stabilizing it in the next weeks in order to make these updates be shipped in a stable
|
||||
release before the end of the year.
|
||||
|
||||
This update contains major performance improvements and exposes new privacy user
|
||||
settings. We will work towards stabilizing it in the next weeks in order to make
|
||||
these updates be shipped in a stable release before the end of the year.
|
||||
|
||||
<br/>![New Features](/docs/assets/tags/new_features.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
<br/>![Bug Fixes](/docs/assets/tags/bug_fixes.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
<br/>![Release Notes](/docs/assets/tags/release_notes.svg)
|
||||
|
||||
#### Visual Environment
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
||||
|
||||
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||
- [The graph editor stops shaking and running away when you are pasting
|
||||
JavaScript code][79271].
|
||||
|
||||
#### Runtime
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
||||
|
||||
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||
than C++][79272].
|
||||
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||
crashing anymore][79273].
|
||||
|
||||
#### Libraries
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
||||
|
||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||
- [The Regexp library exposes now methods to test the expressions directly on
|
||||
humans][79275].
|
||||
|
||||
[79270]: http://github.com/ticket
|
||||
[79271]: http://github.com/ticket
|
||||
@ -154,9 +201,9 @@ release before the end of the year.
|
||||
[79273]: http://github.com/ticket
|
||||
[79274]: http://github.com/ticket
|
||||
[79275]: http://github.com/ticket
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
# Enso 47.0.0-alpha.7 (2049-01-07)
|
||||
|
||||
...
|
||||
|
@ -7,7 +7,7 @@ tags: [doc-index]
|
||||
|
||||
# Enso IDE documentation
|
||||
|
||||
* [**Contributing guidelines**](./contributing/README.md) - helpful
|
||||
instructions for anyone who wants to contribute.
|
||||
* [**Product specification**](./product/README.md) - a specification from
|
||||
the user perspective.
|
||||
- [**Contributing guidelines**](./contributing/README.md) - helpful instructions
|
||||
for anyone who wants to contribute.
|
||||
- [**Product specification**](./product/README.md) - a specification from the
|
||||
user perspective.
|
||||
|
@ -7,8 +7,9 @@ tags: [contributing]
|
||||
|
||||
# Enso IDE Contributing Documentation
|
||||
|
||||
This directory contains helpful resources for anyone who wants to start Enso IDE development. The
|
||||
main guideline is available [here](../CONTRIBUTING.md).
|
||||
This directory contains helpful resources for anyone who wants to start Enso IDE
|
||||
development. The main guideline is available [here](../CONTRIBUTING.md).
|
||||
|
||||
* [**Enso Team Process**](./process.md) - the development cycle in the core Enso IDE team.
|
||||
* [**Style Guide**](./style-guide.md) - Our coding standards.
|
||||
- [**Enso Team Process**](./process.md) - the development cycle in the core Enso
|
||||
IDE team.
|
||||
- [**Style Guide**](./style-guide.md) - Our coding standards.
|
||||
|
@ -7,16 +7,21 @@ tags: [contributing]
|
||||
|
||||
# Enso IDE Team Process
|
||||
|
||||
This document specify our core team workflow, described as a lifecycle of a task:
|
||||
This document specify our core team workflow, described as a lifecycle of a
|
||||
task:
|
||||
|
||||
* A newly created task should be appropriately described, but not estimated yet - it will be during
|
||||
Backlog Refinement meeting. The task is put in "New Tasks" column.
|
||||
* At the beginning of the sprint team leads put to the "To Refine" column all tasks which will be
|
||||
refined during the next Backlog refinement.
|
||||
* Each team member should read the descriptions of tasks in "To Refine" column and ask questions
|
||||
and raise all concerns. All the conversation should be recorded in the issue's comments.
|
||||
* During Backlog Refinement we confirm that the task description is clear and estimate it. The
|
||||
estimate is expressed in work days of one person, and should include the review process. The task
|
||||
is then moved to the "Backlog" column. If it turns out that there is no agreement about the task's
|
||||
scope and estimation, it may be postponed to the next Backlog Refinement.
|
||||
* During Planning meeting the team decides which tasks are took into next sprint and assign them.
|
||||
- A newly created task should be appropriately described, but not estimated
|
||||
yet - it will be during Backlog Refinement meeting. The task is put in "New
|
||||
Tasks" column.
|
||||
- At the beginning of the sprint team leads put to the "To Refine" column all
|
||||
tasks which will be refined during the next Backlog refinement.
|
||||
- Each team member should read the descriptions of tasks in "To Refine" column
|
||||
and ask questions and raise all concerns. All the conversation should be
|
||||
recorded in the issue's comments.
|
||||
- During Backlog Refinement we confirm that the task description is clear and
|
||||
estimate it. The estimate is expressed in work days of one person, and should
|
||||
include the review process. The task is then moved to the "Backlog" column. If
|
||||
it turns out that there is no agreement about the task's scope and estimation,
|
||||
it may be postponed to the next Backlog Refinement.
|
||||
- During Planning meeting the team decides which tasks are took into next sprint
|
||||
and assign them.
|
||||
|
@ -1,9 +1,9 @@
|
||||
# Repository Structure Overview
|
||||
|
||||
* `build` - Helper JS scripts used by `run` script in the main directory.
|
||||
* `docs` - Documentation.
|
||||
* `src/js` - The JS part of IDE application.
|
||||
* `src/rust` - All Rust crates.
|
||||
- `build` - Helper JS scripts used by `run` script in the main directory.
|
||||
- `docs` - Documentation.
|
||||
- `src/js` - The JS part of IDE application.
|
||||
- `src/rust` - All Rust crates.
|
||||
|
||||
## Crates
|
||||
|
||||
@ -11,15 +11,15 @@ The crates structure is currently in process of refactoring, and there are still
|
||||
places where code does not fit the crate it is placed. The work is tracked in
|
||||
#448 epic.
|
||||
|
||||
The detailed description of each crate is placed in its documentation at top
|
||||
of its `lib.rs` file.
|
||||
The detailed description of each crate is placed in its documentation at top of
|
||||
its `lib.rs` file.
|
||||
|
||||
There are two main parts of our codebase: **EnsoGL library** and the **Enso
|
||||
IDE application**. The crates used in common by those parts are put in `src
|
||||
/rust/lib`, and should be documented at the top of their `lib.rs` file.
|
||||
There are two main parts of our codebase: **EnsoGL library** and the **Enso IDE
|
||||
application**. The crates used in common by those parts are put in
|
||||
`src /rust/lib`, and should be documented at the top of their `lib.rs` file.
|
||||
|
||||
Other crates usually contains code shared by those two. The one noteworthy
|
||||
is the **prelude** crate (`src/rust/prelude`) which gathers the commonly used
|
||||
Other crates usually contains code shared by those two. The one noteworthy is
|
||||
the **prelude** crate (`src/rust/prelude`) which gathers the commonly used
|
||||
imports across all crates in our repository.
|
||||
|
||||
### EnsoGL (`src/rust/ensogl`)
|
||||
@ -28,16 +28,16 @@ EnsoGL is a library providing fast 2D vector rendering engine with a rich set of
|
||||
primitives and high-level GUI components. Its structure will be described after
|
||||
the planned refactoring in #598.
|
||||
|
||||
|
||||
### Enso IDE (`src/rust/ide`)
|
||||
|
||||
The Enso IDE crate contains entry point function of application, and
|
||||
integrates two main parts of it:
|
||||
* IDE View (`src/rust/ide/lib/view`) - The visual part of IDE. It contains
|
||||
no logic and connections to backend - instead it delivers FRP endpoints to
|
||||
be integrated with controllers. That design allow us to measure of vis-part
|
||||
only performance.
|
||||
* IDE Controllers (`src/rust/ide/lib/controller`) - The logic part of IDE,
|
||||
that is synchronizing graph a text and communication with Engine. It
|
||||
should not know anything about visual part. In the future we may consider
|
||||
creating some sort of CLI for automatic integration tests.
|
||||
The Enso IDE crate contains entry point function of application, and integrates
|
||||
two main parts of it:
|
||||
|
||||
- IDE View (`src/rust/ide/lib/view`) - The visual part of IDE. It contains no
|
||||
logic and connections to backend - instead it delivers FRP endpoints to be
|
||||
integrated with controllers. That design allow us to measure of vis-part only
|
||||
performance.
|
||||
- IDE Controllers (`src/rust/ide/lib/controller`) - The logic part of IDE, that
|
||||
is synchronizing graph a text and communication with Engine. It should not
|
||||
know anything about visual part. In the future we may consider creating some
|
||||
sort of CLI for automatic integration tests.
|
||||
|
@ -4,16 +4,16 @@ layout: style-guide title: Rust Style Guide category: style-guide tags: [style-g
|
||||
|
||||
# Rust Style Guide
|
||||
|
||||
We are using `rustfmt` for the basic formatting of our rust code, which is also checked on CI. We
|
||||
have some additional guidelines for imports, naming, sections within files and naming which are
|
||||
documented here.
|
||||
We are using `rustfmt` for the basic formatting of our rust code, which is also
|
||||
checked on CI. We have some additional guidelines for imports, naming, sections
|
||||
within files and naming which are documented here.
|
||||
|
||||
## Styling rules
|
||||
|
||||
### Imports
|
||||
|
||||
Imports should be divided into 4 groups separated by blank lines. Items in the groups should be
|
||||
sorted alphabetically.
|
||||
Imports should be divided into 4 groups separated by blank lines. Items in the
|
||||
groups should be sorted alphabetically.
|
||||
|
||||
```rust
|
||||
// Group 1: sub-module definitions.
|
||||
@ -40,12 +40,14 @@ use nalgebra::Vector3;
|
||||
|
||||
### Sections
|
||||
|
||||
Source files should be divided into sections. Section headers should be placed before each new "
|
||||
concept" defined in a file. By "concept" we normally mean a structure with related implementations.
|
||||
In case related implementations use some helper structs with very small implementations, these
|
||||
helper structs may be defined in the same section. Moreover, the code in each section should be
|
||||
divided into sub-sections, grouping related definitions. At least one section should be defined in a
|
||||
file (if there is at least one struct definition as well). For example:
|
||||
Source files should be divided into sections. Section headers should be placed
|
||||
before each new " concept" defined in a file. By "concept" we normally mean a
|
||||
structure with related implementations. In case related implementations use some
|
||||
helper structs with very small implementations, these helper structs may be
|
||||
defined in the same section. Moreover, the code in each section should be
|
||||
divided into sub-sections, grouping related definitions. At least one section
|
||||
should be defined in a file (if there is at least one struct definition as
|
||||
well). For example:
|
||||
|
||||
```rust
|
||||
// =================
|
||||
@ -141,10 +143,11 @@ impl<OnChange: Callback0> HierarchicalTransform<OnChange> {
|
||||
|
||||
### Multiline Expressions
|
||||
|
||||
Most (preferably all) expressions should be single line. Multiline expressions are hard to read and
|
||||
introduce noise in the code. Often, it is also an indicator of code that is not properly refactored.
|
||||
Try to refactor parts of multiline expressions to well-named variables, and divide them to several
|
||||
single-line expressions.
|
||||
Most (preferably all) expressions should be single line. Multiline expressions
|
||||
are hard to read and introduce noise in the code. Often, it is also an indicator
|
||||
of code that is not properly refactored. Try to refactor parts of multiline
|
||||
expressions to well-named variables, and divide them to several single-line
|
||||
expressions.
|
||||
|
||||
Example of poorly formatted code:
|
||||
|
||||
@ -172,9 +175,9 @@ pub fn new() -> Self {
|
||||
|
||||
### Getters and Setters
|
||||
|
||||
Getters do not have the `get_` prefix, while setters do. If a setter is provided (method with
|
||||
the `set_` prefix), a `mut` accessor should be provided as well. The correct way of defining getters
|
||||
and setters is presented below:
|
||||
Getters do not have the `get_` prefix, while setters do. If a setter is provided
|
||||
(method with the `set_` prefix), a `mut` accessor should be provided as well.
|
||||
The correct way of defining getters and setters is presented below:
|
||||
|
||||
```rust
|
||||
fn field(&self) -> &Type {
|
||||
@ -192,13 +195,14 @@ fn set_field(&mut self, val: Type) {
|
||||
|
||||
### Trait exporting
|
||||
|
||||
All names should be designed to be used in a qualified fashion. However, this makes one situation
|
||||
tricky. In order to use methods defined in a trait, it has to be in scope. Consider a trait
|
||||
`display::Object`. We want to use it as function bound like `fn test<T:display::Object>(t:T) {...}`,
|
||||
and we also want to use methods defined in this trait (so it has to be in scope). In such a case,
|
||||
`Clippy` warns that `display::Object` is unnecessary qualification and could be replaced simply by
|
||||
`Object`, which is not what we want. Thus, in order to export traits, please always rename them
|
||||
using the following convention:
|
||||
All names should be designed to be used in a qualified fashion. However, this
|
||||
makes one situation tricky. In order to use methods defined in a trait, it has
|
||||
to be in scope. Consider a trait `display::Object`. We want to use it as
|
||||
function bound like `fn test<T:display::Object>(t:T) {...}`, and we also want to
|
||||
use methods defined in this trait (so it has to be in scope). In such a case,
|
||||
`Clippy` warns that `display::Object` is unnecessary qualification and could be
|
||||
replaced simply by `Object`, which is not what we want. Thus, in order to export
|
||||
traits, please always rename them using the following convention:
|
||||
|
||||
```rust
|
||||
/// Common traits.
|
||||
@ -209,5 +213,6 @@ pub mod traits {
|
||||
}
|
||||
```
|
||||
|
||||
Having such a definition, we can import traits to scope using `use display::object::traits::*`, and
|
||||
we would not have any warning about unnecessary qualification anymore.
|
||||
Having such a definition, we can import traits to scope using
|
||||
`use display::object::traits::*`, and we would not have any warning about
|
||||
unnecessary qualification anymore.
|
||||
|
@ -10,6 +10,6 @@ This section contains detailed specification of Enso IDE from the user
|
||||
perspective. The implementation is documented in rust code and in the crate's
|
||||
`docs` directory.
|
||||
|
||||
* [**List of Shortcuts**](./shortcuts.md)
|
||||
* [**Visualizations**](./visualizations.md)
|
||||
* [**Searcher in Graph Editor**](./searcher.md)
|
||||
- [**List of Shortcuts**](./shortcuts.md)
|
||||
- [**Visualizations**](./visualizations.md)
|
||||
- [**Searcher in Graph Editor**](./searcher.md)
|
||||
|
@ -10,12 +10,13 @@ tags: [product]
|
||||
### Behaviour
|
||||
|
||||
The Searcher Panel can be brought to the screen in two different ways:
|
||||
* when user starts to edit node's expression - the node becomes Searcher input
|
||||
|
||||
- when user starts to edit node's expression - the node becomes Searcher input
|
||||
and panel appears below,
|
||||
* when user press tab with mouse over Graph Editor Panel - the new Searcher
|
||||
input appears with Searcher panel below. Additionally, if there is exactly
|
||||
one node selected, the connection is displayed between the selected node
|
||||
and the Searcher input.
|
||||
- when user press tab with mouse over Graph Editor Panel - the new Searcher
|
||||
input appears with Searcher panel below. Additionally, if there is exactly one
|
||||
node selected, the connection is displayed between the selected node and the
|
||||
Searcher input.
|
||||
|
||||
### Suggestion of Node Expressions
|
||||
|
||||
@ -27,7 +28,7 @@ connected to selection. The current implementation can be found in
|
||||
|
||||
### Suggestion Database
|
||||
|
||||
The `search/completion` method of Language Server returns a list of keys to
|
||||
the Suggestion Database instead of the whole entries. The database is
|
||||
retrieved by IDE on Project opening, and keeps it up to date. The Database
|
||||
is implemented in `ide::model::suggestion_database` module.
|
||||
The `search/completion` method of Language Server returns a list of keys to the
|
||||
Suggestion Database instead of the whole entries. The database is retrieved by
|
||||
IDE on Project opening, and keeps it up to date. The Database is implemented in
|
||||
`ide::model::suggestion_database` module.
|
||||
|
@ -8,29 +8,34 @@ tags: [product,ui]
|
||||
## General Assumptions
|
||||
|
||||
#### The <kbd>meta</kbd> key.
|
||||
The <kbd>meta</kbd> key was introduced to make the shortcuts consistent across platforms.
|
||||
It is defined as <kbd>command</kbd> on macOS, and as <kbd>ctrl</kbd> on Windows and Linux.
|
||||
|
||||
The <kbd>meta</kbd> key was introduced to make the shortcuts consistent across
|
||||
platforms. It is defined as <kbd>command</kbd> on macOS, and as <kbd>ctrl</kbd>
|
||||
on Windows and Linux.
|
||||
|
||||
#### Keyboard-only Workflow
|
||||
The GUI and all shortcuts were designed in a way to allow both efficient mouse-only as well as
|
||||
keyboard-only workflows. In most cases, there is a relation between mouse and keyboard shortcuts,
|
||||
namely, the `left-mouse-button` corresponds to `enter`. For example, stepping into a node is done
|
||||
by either double clicking the node, or just pressing the enter key.
|
||||
|
||||
The GUI and all shortcuts were designed in a way to allow both efficient
|
||||
mouse-only as well as keyboard-only workflows. In most cases, there is a
|
||||
relation between mouse and keyboard shortcuts, namely, the `left-mouse-button`
|
||||
corresponds to `enter`. For example, stepping into a node is done by either
|
||||
double clicking the node, or just pressing the enter key.
|
||||
|
||||
#### Missing / not working shortcuts
|
||||
Some of the shortcuts presented below are marked with the :warning: icon, which means, that they are
|
||||
planned, but not yet implemented. Feel free to contribute and help us implement them!
|
||||
|
||||
Shortcuts marked with the :bangbang: icon should work, but are reported to be broken and require
|
||||
further investigation.
|
||||
|
||||
Some of the shortcuts presented below are marked with the :warning: icon, which
|
||||
means, that they are planned, but not yet implemented. Feel free to contribute
|
||||
and help us implement them!
|
||||
|
||||
Shortcuts marked with the :bangbang: icon should work, but are reported to be
|
||||
broken and require further investigation.
|
||||
|
||||
## Graph Editor
|
||||
|
||||
#### General Shortcuts
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | ------ |
|
||||
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <kbd>cmd</kbd>+<kbd>alt</kbd>+<kbd>shift</kbd>+<kbd>t</kbd> | Toggle light/dark application style. Currently doesn't work properly, as the Theme Switcher is not created yet. (https://github.com/enso-org/ide/issues/795) |
|
||||
| <kbd>ctrl</kbd>+<kbd>`</kbd> | Show Code Editor. Please note that the Code Editor implementation is in a very early stage and you should not use it. Even just openning it can cause errors in the IDE. Do not try using the graph editor while having the code editor tab openned. |
|
||||
| <kbd>cmd</kbd>+<kbd>o</kbd> | Open project |
|
||||
@ -43,36 +48,36 @@ further investigation.
|
||||
| <kbd>ctrl</kbd>+<kbd>w</kbd> | Close the application (Windows, Linux) |
|
||||
| :warning: <kbd>ctrl</kbd>+<kbd>p</kbd> | Toggle profiling mode |
|
||||
|
||||
|
||||
#### Navigation
|
||||
| Shortcut | Action |
|
||||
| -------- | ------ |
|
||||
| Drag gesture (two fingers) | Pan the scene.
|
||||
| Pinch gesture (two fingers) | Zoom the scene.
|
||||
| <kbd>MMB</kbd> drag | Pan the scene.
|
||||
| <kbd>RMB</kbd> drag | Zoom the scene.
|
||||
| <kbd>LMB</kbd> double press node name | Step into the node.
|
||||
| :warning: <kbd>LMB</kbd> double press background | Step out of the current node.
|
||||
| <kbd>enter</kbd> | Step in the last selected node.
|
||||
| <kbd>alt</kbd>+<kbd>enter</kbd> | Step out of the current node.
|
||||
|
||||
| Shortcut | Action |
|
||||
| ------------------------------------------------ | ------------------------------- |
|
||||
| Drag gesture (two fingers) | Pan the scene. |
|
||||
| Pinch gesture (two fingers) | Zoom the scene. |
|
||||
| <kbd>MMB</kbd> drag | Pan the scene. |
|
||||
| <kbd>RMB</kbd> drag | Zoom the scene. |
|
||||
| <kbd>LMB</kbd> double press node name | Step into the node. |
|
||||
| :warning: <kbd>LMB</kbd> double press background | Step out of the current node. |
|
||||
| <kbd>enter</kbd> | Step in the last selected node. |
|
||||
| <kbd>alt</kbd>+<kbd>enter</kbd> | Step out of the current node. |
|
||||
|
||||
#### Node Layout
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | ------ |
|
||||
| ------------------------------------------ | ----------------------------------------------------------------- |
|
||||
| <kbd>LMB</kbd> drag non-selected node name | Move the node to new position (dragging do not modify selection). |
|
||||
| <kbd>LMB</kbd> drag selected node name | Move all selected nodes the node to new positions. |
|
||||
|
||||
|
||||
#### Node Selection
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| <kbd>LMB</kbd> click node name | Deselect all nodes. Select the target node. |
|
||||
| <kbd>LMB</kbd> click background | Deselect all nodes. |
|
||||
| :warning: <kbd>LMB</kbd> drag background | Select nodes using selection-box. |
|
||||
| <kbd>shift</kbd> + <kbd>LMB</kbd> click node name | Add / remove node to the selection group. |
|
||||
| :warning: <kbd>shift</kbd> + <kbd>LMB</kbd> drag background | Add / remove nodes to the selection group. |
|
||||
| :warning: <kbd>*-arrow</kbd> | Select node on the right side of the newest selected node. |
|
||||
| :warning: <kbd>\*-arrow</kbd> | Select node on the right side of the newest selected node. |
|
||||
| :warning: <kbd>cmd</kbd> + <kbd>a</kbd> | Select all nodes. |
|
||||
| :warning: <kbd>escape</kbd> | Deselect all nodes (if not in a mode, like edit mode). |
|
||||
| <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>LMB</kbd> click node name | Add node to the selection group. |
|
||||
@ -82,10 +87,10 @@ further investigation.
|
||||
| <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>LMB</kbd> click node name | Inverse node selection. |
|
||||
| :warning: <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>LMB</kbd> drag background | Inverse nodes selection. |
|
||||
|
||||
|
||||
#### Node Editing
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | ------ |
|
||||
| ------------------------------------------------ | -------------------------------------------- |
|
||||
| <kbd>tab</kbd> | Show / hide node searcher. |
|
||||
| <kbd>backspace</kbd> or <kbd>delete</kbd> | Remove selected nodes. |
|
||||
| <kbd>cmd</kbd>+<kbd>g</kbd> | Collapse (group) selected nodes. |
|
||||
@ -93,27 +98,27 @@ further investigation.
|
||||
| <kbd>meta</kbd>+<kbd>enter</kbd> | Start editing node expression. |
|
||||
| <kbd>enter</kbd> or <kbd>LMB</kbd> on suggestion | Pick selected suggestion and commit editing. |
|
||||
|
||||
|
||||
#### Visualization
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | ------ |
|
||||
| ----------------------------------------- | ------------------------------------------------------------- |
|
||||
| <kbd>space</kbd> | Toggle visualization visibility of the selected node. |
|
||||
| <kbd>space</kbd> hold | Preview visualization of the selected node (hide on release). |
|
||||
| :warning: <kbd>space</kbd> double press | Toggle visualization fullscreen mode |
|
||||
| <kbd>ctrl</kbd> + <kbd>space</kbd> | Cycle visualizations of the selected node. |
|
||||
| :bangbang: <kbd>cmd</kbd> + <kbd>\\</kbd> | Toggle documentation view visibility |
|
||||
|
||||
|
||||
#### Visualizations Implementations
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | ------ |
|
||||
| ------------------------------ | -------------------------------------------------- |
|
||||
| <kbd>meta</kbd> + <kbd>a</kbd> | Show all points if available in visualization. |
|
||||
| <kbd>meta</kbd> + <kbd>z</kbd> | Zoom into selection if available in visualization. |
|
||||
|
||||
|
||||
#### Debug
|
||||
|
||||
| Shortcut | Action |
|
||||
| -------- | ------ |
|
||||
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>shift</kbd> + <kbd>i</kbd> | Open the developer console. |
|
||||
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>shift</kbd> + <kbd>r</kbd> | Reload the visual interface. |
|
||||
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>0 - 10</kbd> | Switch between debug rendering modes (0 is the normal mode). |
|
||||
|
@ -1,9 +1,10 @@
|
||||
# What is a Self-XSS scam?
|
||||
|
||||
A Self-XSS scam tricks you into compromising your account by claiming to provide a way to log into
|
||||
someone else's account, or some other kind of reward, after pasting a special code or link into your
|
||||
web browser. Never copy and paste scripts into the developer console.
|
||||
A Self-XSS scam tricks you into compromising your account by claiming to provide
|
||||
a way to log into someone else's account, or some other kind of reward, after
|
||||
pasting a special code or link into your web browser. Never copy and paste
|
||||
scripts into the developer console.
|
||||
|
||||
This kind of scam can often include malicious software and can give the attacker access to your
|
||||
account and your data. Read the following article to learn more:
|
||||
This kind of scam can often include malicious software and can give the attacker
|
||||
access to your account and your data. Read the following article to learn more:
|
||||
https://en.wikipedia.org/wiki/Self-XSS.
|
||||
|
@ -4,8 +4,6 @@
|
||||
"hoist": true
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"lib/*"
|
||||
],
|
||||
"packages": ["lib/*"],
|
||||
"version": "0.0.0"
|
||||
}
|
||||
|
@ -12,27 +12,27 @@ function get_build_config() {
|
||||
const build = get_build_config()
|
||||
|
||||
let config = {
|
||||
name: "Enso",
|
||||
description: "Enso Data Processing Environment.",
|
||||
main: "index.js",
|
||||
name: 'Enso',
|
||||
description: 'Enso Data Processing Environment.',
|
||||
main: 'index.js',
|
||||
|
||||
dependencies: {
|
||||
"create-servers": "^3.1.0",
|
||||
"electron-is-dev": "^1.1.0",
|
||||
"enso-studio-common": "1.0.0",
|
||||
"enso-studio-content": "1.0.0",
|
||||
"enso-studio-icons": "1.0.0",
|
||||
"yargs": "^15.3.0"
|
||||
'create-servers': '^3.1.0',
|
||||
'electron-is-dev': '^1.1.0',
|
||||
'enso-studio-common': '1.0.0',
|
||||
'enso-studio-content': '1.0.0',
|
||||
'enso-studio-icons': '1.0.0',
|
||||
yargs: '^15.3.0',
|
||||
},
|
||||
|
||||
devDependencies: {
|
||||
"compression-webpack-plugin": "^3.1.0",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"devtron": "^1.4.0",
|
||||
"electron": "11.1.1",
|
||||
"electron-builder": "^22.10.5",
|
||||
"crypto-js": "4.0.0",
|
||||
"electron-notarize" : "1.0.0",
|
||||
'compression-webpack-plugin': '^3.1.0',
|
||||
'copy-webpack-plugin': '^5.1.1',
|
||||
devtron: '^1.4.0',
|
||||
electron: '11.1.1',
|
||||
'electron-builder': '^22.10.5',
|
||||
'crypto-js': '4.0.0',
|
||||
'electron-notarize': '1.0.0',
|
||||
},
|
||||
|
||||
scripts: {
|
||||
@ -76,18 +76,14 @@ config.build = {
|
||||
icon: `${paths.dist.root}/icons/png`,
|
||||
category: 'Development',
|
||||
},
|
||||
files: [
|
||||
{ from: paths.dist.content, to: '.' }
|
||||
],
|
||||
extraResources: [
|
||||
{ from: paths.dist.bin, to: '.' , filter: ["!**.tar.gz", "!**.zip"]}
|
||||
],
|
||||
files: [{ from: paths.dist.content, to: '.' }],
|
||||
extraResources: [{ from: paths.dist.bin, to: '.', filter: ['!**.tar.gz', '!**.zip'] }],
|
||||
fileAssociations: [
|
||||
{
|
||||
ext: 'enso',
|
||||
name: 'Enso Source File',
|
||||
role: 'Editor',
|
||||
}
|
||||
},
|
||||
],
|
||||
directories: {
|
||||
output: paths.dist.client,
|
||||
@ -100,7 +96,7 @@ config.build = {
|
||||
// are handled by us. More info:
|
||||
// https://github.com/electron-userland/electron-builder/issues/2851
|
||||
// https://github.com/electron-userland/electron-builder/issues/2900
|
||||
differentialPackage: false
|
||||
differentialPackage: false,
|
||||
},
|
||||
dmg: {
|
||||
// Disables "block map" generation during electron building. Block maps
|
||||
@ -116,7 +112,7 @@ config.build = {
|
||||
// notarised application it will still be detected as trusted.
|
||||
// For more details see step (4) at
|
||||
// https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/
|
||||
sign: false
|
||||
sign: false,
|
||||
},
|
||||
publish: [],
|
||||
afterAllArtifactBuild: 'tasks/computeHashes.js',
|
||||
|
@ -17,16 +17,12 @@ import paths from '../../../../../build/paths'
|
||||
const child_process = require('child_process')
|
||||
const fss = require('fs')
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Paths ===
|
||||
// =============
|
||||
|
||||
const root = Electron.app.getAppPath()
|
||||
const resources = path.join(root, "..")
|
||||
|
||||
|
||||
const resources = path.join(root, '..')
|
||||
|
||||
// FIXME default options parsed wrong
|
||||
// https://github.com/yargs/yargs/issues/1590
|
||||
@ -40,8 +36,6 @@ let windowCfg = {
|
||||
height: 900,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Utils ===
|
||||
// =============
|
||||
@ -50,8 +44,7 @@ function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
}
|
||||
|
||||
const execFile = util.promisify(child_process.execFile);
|
||||
|
||||
const execFile = util.promisify(child_process.execFile)
|
||||
|
||||
// The list of hosts that the app can access. They are required for
|
||||
// user authentication to work.
|
||||
@ -77,7 +70,7 @@ Arguments that follow the two dashes (\`--\`) will be passed to the backend proc
|
||||
if IDE spawns backend, i.e. if '--backend false' has not been set.`
|
||||
|
||||
let optParser = yargs
|
||||
.scriptName("")
|
||||
.scriptName('')
|
||||
.usage(usage)
|
||||
.epilogue(epilogue)
|
||||
.help()
|
||||
@ -85,7 +78,6 @@ let optParser = yargs
|
||||
.parserConfiguration({ 'populate--': true })
|
||||
.strict()
|
||||
|
||||
|
||||
// === Config Options ===
|
||||
|
||||
let configOptionsGroup = 'Config Options:'
|
||||
@ -137,7 +129,7 @@ optParser.options('verbose', {
|
||||
group: debugOptionsGroup,
|
||||
describe: `Increase logs verbosity. Affects both IDE and the backend.`,
|
||||
default: false,
|
||||
type : `boolean`
|
||||
type: `boolean`,
|
||||
})
|
||||
|
||||
optParser.options('entry-point', {
|
||||
@ -156,7 +148,6 @@ optParser.options('devtron', {
|
||||
describe: 'Install the Devtron Developer Tools extension',
|
||||
})
|
||||
|
||||
|
||||
// === Style Options ===
|
||||
|
||||
let styleOptionsGroup = 'Style Options:'
|
||||
@ -164,36 +155,35 @@ let styleOptionsGroup = 'Style Options:'
|
||||
optParser.options('frame', {
|
||||
group: styleOptionsGroup,
|
||||
describe: 'Draw window frame. Defaults to `false` on MacOS and `true` otherwise.',
|
||||
type : `boolean`
|
||||
type: `boolean`,
|
||||
})
|
||||
|
||||
optParser.options('vibrancy', {
|
||||
group: styleOptionsGroup,
|
||||
describe: 'Use the vibrancy effect',
|
||||
default: false,
|
||||
type : `boolean`
|
||||
type: `boolean`,
|
||||
})
|
||||
|
||||
optParser.options('window-size', {
|
||||
group: styleOptionsGroup,
|
||||
describe: `Set the window size [${windowCfg.width}x${windowCfg.height}]`,
|
||||
requiresArg : true
|
||||
requiresArg: true,
|
||||
})
|
||||
|
||||
optParser.options('theme', {
|
||||
group: styleOptionsGroup,
|
||||
describe: 'Use the provided theme. Defaults to `light`.',
|
||||
type : `string`
|
||||
type: `string`,
|
||||
})
|
||||
|
||||
optParser.options('node-labels', {
|
||||
group: styleOptionsGroup,
|
||||
describe: 'Show node labels. Defaults to `true`.',
|
||||
default: true,
|
||||
type : `boolean`
|
||||
type: `boolean`,
|
||||
})
|
||||
|
||||
|
||||
// === Other Options ===
|
||||
|
||||
optParser.options('info', {
|
||||
@ -205,19 +195,19 @@ optParser.options('version', {
|
||||
})
|
||||
|
||||
optParser.options('crash-report-host', {
|
||||
describe : 'The address of the server that will receive crash reports. ' +
|
||||
describe:
|
||||
'The address of the server that will receive crash reports. ' +
|
||||
'Consists of a hostname, optionally followed by a ":" and a port number',
|
||||
requiresArg: true,
|
||||
default : cfg.defaultLogServerHost
|
||||
default: cfg.defaultLogServerHost,
|
||||
})
|
||||
|
||||
optParser.options('data-gathering', {
|
||||
describe: 'Enable the sharing of any usage data',
|
||||
type: 'boolean',
|
||||
default : true
|
||||
default: true,
|
||||
})
|
||||
|
||||
|
||||
// === Parsing ===
|
||||
|
||||
function parseCmdArgs() {
|
||||
@ -232,7 +222,7 @@ let args = parseCmdArgs()
|
||||
// borderless on Mac. See https://github.com/enso-org/ide/issues/1101 and
|
||||
// https://github.com/electron/electron/issues/3647 for details.
|
||||
if (args.frame === undefined) {
|
||||
args.frame = (process.platform !== 'darwin')
|
||||
args.frame = process.platform !== 'darwin'
|
||||
}
|
||||
|
||||
if (args.theme === undefined) {
|
||||
@ -251,8 +241,6 @@ if (args.windowSize) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==================
|
||||
// === Debug Info ===
|
||||
// ==================
|
||||
@ -289,11 +277,9 @@ async function getDebugInfo() {
|
||||
async function printDebugInfo() {
|
||||
let info = await getDebugInfo()
|
||||
console.log(JSON.stringify(info, undefined, 4))
|
||||
process.exit();
|
||||
process.exit()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Security ===
|
||||
// ================
|
||||
@ -307,7 +293,9 @@ async function printDebugInfo() {
|
||||
/// security features. Follow the link to learn more:
|
||||
/// https://www.electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
|
||||
function secureWebPreferences(webPreferences) {
|
||||
if(!webPreferences) { webPreferences = {} }
|
||||
if (!webPreferences) {
|
||||
webPreferences = {}
|
||||
}
|
||||
delete webPreferences.preload
|
||||
delete webPreferences.preloadURL
|
||||
delete webPreferences.nodeIntegration
|
||||
@ -335,7 +323,6 @@ Electron.app.on('web-contents-created', (event,contents) => {
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// === Prevent Navigation ===
|
||||
|
||||
/// Navigation is a common attack vector. If an attacker can convince your app to navigate away from
|
||||
@ -352,7 +339,6 @@ Electron.app.on('web-contents-created', (event,contents) => {
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// === Disable New Windows Creation ===
|
||||
|
||||
/// Much like navigation, the creation of new webContents is a common attack vector. Attackers
|
||||
@ -367,8 +353,6 @@ Electron.app.on('web-contents-created', (event,contents) => {
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
// =======================
|
||||
// === Project Manager ===
|
||||
// =======================
|
||||
@ -395,7 +379,9 @@ function projectManagerPath() {
|
||||
*/
|
||||
async function execProjectManager(args) {
|
||||
let binPath = projectManagerPath()
|
||||
return await execFile(binPath,args).catch(function(err) {throw err})
|
||||
return await execFile(binPath, args).catch(function (err) {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -414,11 +400,11 @@ function spawnProjectManager(args) {
|
||||
let stdout = 'inherit'
|
||||
let stderr = 'inherit'
|
||||
let opts = {
|
||||
stdio: [stdin,stdout,stderr]
|
||||
stdio: [stdin, stdout, stderr],
|
||||
}
|
||||
let out = child_process.spawn(binPath, args, opts)
|
||||
console.log(`Project Manager has been spawned, pid = ${out.pid}.`)
|
||||
out.on('exit', (code) => {
|
||||
out.on('exit', code => {
|
||||
console.log(`Project Manager exited with code ${code}.`)
|
||||
})
|
||||
return out
|
||||
@ -430,19 +416,17 @@ function runBackend() {
|
||||
if (args.verbose === true) {
|
||||
opts.push('-vv')
|
||||
}
|
||||
console.log("Starting the backend process with the following options:", opts)
|
||||
console.log('Starting the backend process with the following options:', opts)
|
||||
return spawnProjectManager(opts)
|
||||
}
|
||||
}
|
||||
|
||||
async function backendVersion() {
|
||||
if (args.backend !== false) {
|
||||
return await execProjectManager(['--version']).then((t) => t.stdout)
|
||||
return await execProjectManager(['--version']).then(t => t.stdout)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Main ===
|
||||
// ============
|
||||
@ -456,7 +440,7 @@ let origin = null
|
||||
async function main(args) {
|
||||
setUserAgent()
|
||||
runBackend()
|
||||
console.log("Starting the IDE service.")
|
||||
console.log('Starting the IDE service.')
|
||||
if (args.server !== false) {
|
||||
let serverCfg = Object.assign({}, args)
|
||||
serverCfg.dir = root
|
||||
@ -465,9 +449,9 @@ async function main(args) {
|
||||
origin = `http://localhost:${server.port}`
|
||||
}
|
||||
if (args.window !== false) {
|
||||
console.log("Starting the IDE client.")
|
||||
console.log('Starting the IDE client.')
|
||||
mainWindow = createWindow()
|
||||
mainWindow.on("close", (evt) => {
|
||||
mainWindow.on('close', evt => {
|
||||
if (hideInsteadOfQuit) {
|
||||
evt.preventDefault()
|
||||
mainWindow.hide()
|
||||
@ -495,7 +479,7 @@ function urlParamsFromObject(obj) {
|
||||
let val = obj[key]
|
||||
params.push(`${key}=${val}`)
|
||||
}
|
||||
return params.join("&")
|
||||
return params.join('&')
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
@ -511,7 +495,7 @@ function createWindow() {
|
||||
sandbox: true,
|
||||
backgroundThrottling: false,
|
||||
transparent: false,
|
||||
titleBarStyle : 'default'
|
||||
titleBarStyle: 'default',
|
||||
}
|
||||
|
||||
if (args.dev) {
|
||||
@ -550,8 +534,12 @@ function createWindow() {
|
||||
verbose: args.verbose,
|
||||
}
|
||||
|
||||
if (args.project) { urlCfg.project = args.project }
|
||||
if (args.entryPoint) { urlCfg.entry = args.entryPoint }
|
||||
if (args.project) {
|
||||
urlCfg.project = args.project
|
||||
}
|
||||
if (args.entryPoint) {
|
||||
urlCfg.entry = args.entryPoint
|
||||
}
|
||||
|
||||
let params = urlParamsFromObject(urlCfg)
|
||||
let address = `${origin}?${params}`
|
||||
@ -574,8 +562,6 @@ function setupPermissions() {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Events ===
|
||||
// ==============
|
||||
@ -596,16 +582,16 @@ Electron.app.on('ready', () => {
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Frontend:")
|
||||
console.log('Frontend:')
|
||||
for (let name in versionInfo) {
|
||||
let label = capitalizeFirstLetter(name)
|
||||
let spacing = ' '.repeat(maxNameLen - name.length)
|
||||
console.log(`${indent}${label}:${spacing} ${versionInfo[name]}`)
|
||||
}
|
||||
|
||||
console.log("")
|
||||
console.log("Backend:")
|
||||
backendVersion().then((backend) => {
|
||||
console.log('')
|
||||
console.log('Backend:')
|
||||
backendVersion().then(backend => {
|
||||
if (!backend) {
|
||||
console.log(`${indent}No backend available.`)
|
||||
} else {
|
||||
@ -630,8 +616,6 @@ if (process.platform === 'darwin') {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =================
|
||||
// === Shortcuts ===
|
||||
// =================
|
||||
@ -657,12 +641,12 @@ Electron.app.on('web-contents-created', (webContentsCreatedEvent, webContents) =
|
||||
let quit_on_win = process.platform == 'win32' && (alt_f4 || ctrl_w)
|
||||
let quit_on_lin = process.platform == 'linux' && (alt_f4 || ctrl_q || ctrl_w)
|
||||
let quit = quit_on_mac || quit_on_win || quit_on_lin
|
||||
if (quit) { Electron.app.quit() }
|
||||
if (quit) {
|
||||
Electron.app.quit()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
// =============================
|
||||
// === Deprecations & Fixmes ===
|
||||
// =============================
|
||||
|
@ -1,22 +1,20 @@
|
||||
const remote = require('electron').remote
|
||||
|
||||
let win;
|
||||
let win
|
||||
if (remote !== undefined) {
|
||||
win = remote.getCurrentWindow()
|
||||
}
|
||||
|
||||
if (win === undefined) {
|
||||
console.warn("Could not get current window object for window startup animation.")
|
||||
console.warn('Could not get current window object for window startup animation.')
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============================
|
||||
// === Window Show Animation ===
|
||||
// =============================
|
||||
|
||||
function ease_in_out_quad(t) {
|
||||
return t<.5 ? 2*t*t : 1 - (-2*t+2)*(-2*t+2) / 2
|
||||
return t < 0.5 ? 2 * t * t : 1 - ((-2 * t + 2) * (-2 * t + 2)) / 2
|
||||
}
|
||||
|
||||
function animate_show(target) {
|
||||
@ -24,7 +22,9 @@ function animate_show(target) {
|
||||
let opacity = 0
|
||||
function show_step(timestamp) {
|
||||
opacity += 0.02
|
||||
if (opacity > 1) { opacity = 1 }
|
||||
if (opacity > 1) {
|
||||
opacity = 1
|
||||
}
|
||||
target.setOpacity(ease_in_out_quad(opacity))
|
||||
if (opacity < 1) {
|
||||
window.requestAnimationFrame(show_step)
|
||||
@ -40,8 +40,6 @@ if (win !== undefined) {
|
||||
window.showAnimation = animate_show(win)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ===================
|
||||
// === Debug Tools ===
|
||||
// ===================
|
||||
|
@ -1,18 +1,14 @@
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
const glob = require('glob');
|
||||
const crypto = require('crypto')
|
||||
const fs = require('fs')
|
||||
const glob = require('glob')
|
||||
const paths = require('../../../../../build/paths')
|
||||
|
||||
|
||||
|
||||
// =================
|
||||
// === Constants ===
|
||||
// =================
|
||||
|
||||
const CHECKSUM_TYPE = 'sha256'
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Checksum ===
|
||||
// ================
|
||||
@ -20,28 +16,28 @@ const CHECKSUM_TYPE = 'sha256'
|
||||
/// The `type` argument can be one of `md5`, `sha1`, or `sha256`.
|
||||
function getChecksum(path, type) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const hash = crypto.createHash(type);
|
||||
const input = fs.createReadStream(path);
|
||||
input.on('error', reject);
|
||||
const hash = crypto.createHash(type)
|
||||
const input = fs.createReadStream(path)
|
||||
input.on('error', reject)
|
||||
input.on('data', function (chunk) {
|
||||
hash.update(chunk);
|
||||
});
|
||||
hash.update(chunk)
|
||||
})
|
||||
input.on('close', function () {
|
||||
resolve(hash.digest('hex'));
|
||||
});
|
||||
});
|
||||
resolve(hash.digest('hex'))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function writeFileChecksum(path, type) {
|
||||
let checksum = await getChecksum(path, type)
|
||||
let targetPath = `${path}.${type}`
|
||||
fs.writeFile(targetPath,checksum,'utf8',(err) => {
|
||||
if (err) { throw err }
|
||||
fs.writeFile(targetPath, checksum, 'utf8', err => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Callback ===
|
||||
// ================
|
||||
|
@ -1,25 +1,25 @@
|
||||
/// This script will trigger the notarisation process for macOS and trigger our pre-processing
|
||||
/// and signing of the engine.
|
||||
require('dotenv').config();
|
||||
const { notarize } = require('electron-notarize');
|
||||
require('dotenv').config()
|
||||
const { notarize } = require('electron-notarize')
|
||||
|
||||
exports.default = async function notarizing(context) {
|
||||
const { electronPlatformName, appOutDir } = context;
|
||||
const { electronPlatformName, appOutDir } = context
|
||||
if (electronPlatformName !== 'darwin') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
// We need to manually re-sign our build artifacts before notarisation.
|
||||
// See the script for more information.
|
||||
console.log(" • Performing additional signing of dependencies.")
|
||||
await require("./signArchives").default()
|
||||
console.log(' • Performing additional signing of dependencies.')
|
||||
await require('./signArchives').default()
|
||||
|
||||
// Notarize the application.
|
||||
const appName = context.packager.appInfo.productFilename;
|
||||
console.log(" • Notarizing.")
|
||||
const appName = context.packager.appInfo.productFilename
|
||||
console.log(' • Notarizing.')
|
||||
return await notarize({
|
||||
appBundleId: 'com.enso.ide',
|
||||
appPath: `${appOutDir}/${appName}.app`,
|
||||
appleId: process.env.APPLEID,
|
||||
appleIdPassword: process.env.APPLEIDPASS,
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
const { beforeSign } = require('./signArchives')
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Callback ===
|
||||
// ================
|
||||
|
@ -26,7 +26,7 @@ const ID = '"Developer ID Application: New Byte Order Sp. z o. o. (NM77WTZJFQ)"'
|
||||
// Placeholder name for temporary archives.
|
||||
const tmpArchive = 'temporary_archive.zip'
|
||||
|
||||
const GRAALVM = 'graalvm-ce-java11-21.1.0';
|
||||
const GRAALVM = 'graalvm-ce-java11-21.1.0'
|
||||
|
||||
// Helper to execute a command in a given directory and return the output.
|
||||
const run = (cmd, cwd) => child_process.execSync(cmd, { shell: true, cwd }).toString()
|
||||
@ -36,8 +36,8 @@ function sign(targetPath, cwd) {
|
||||
console.log(`Signing ${targetPath} in ${cwd}`)
|
||||
const entitlements_path = path.resolve('./', 'entitlements.mac.plist')
|
||||
return run(
|
||||
`codesign -vvv --entitlements ${entitlements_path} --force --options=runtime `
|
||||
+ `--sign ${ID} ${targetPath}`,
|
||||
`codesign -vvv --entitlements ${entitlements_path} --force --options=runtime ` +
|
||||
`--sign ${ID} ${targetPath}`,
|
||||
cwd
|
||||
)
|
||||
}
|
||||
@ -108,8 +108,7 @@ function signArchive(archivePath, archiveName, binPaths) {
|
||||
// message provided by Apple and can then be added here.
|
||||
const toSign = [
|
||||
{
|
||||
jarDir:
|
||||
`enso/dist/${ENGINE_VERSION}/lib/Standard/Database/${ENGINE_VERSION}/polyglot/java`,
|
||||
jarDir: `enso/dist/${ENGINE_VERSION}/lib/Standard/Database/${ENGINE_VERSION}/polyglot/java`,
|
||||
jarName: 'sqlite-jdbc-3.34.0.jar',
|
||||
jarContent: [
|
||||
'org/sqlite/native/Mac/aarch64/libsqlitejdbc.jnilib',
|
||||
@ -117,8 +116,7 @@ const toSign = [
|
||||
],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/dist/${ENGINE_VERSION}/component`,
|
||||
jarDir: `enso/dist/${ENGINE_VERSION}/component`,
|
||||
jarName: 'runner.jar',
|
||||
jarContent: [
|
||||
'org/sqlite/native/Mac/x86_64/libsqlitejdbc.jnilib',
|
||||
@ -126,116 +124,97 @@ const toSign = [
|
||||
],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jartool.jmod',
|
||||
jarContent: ['bin/jarsigner', 'bin/jar'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jdeps.jmod',
|
||||
jarContent: ['bin/javap', 'bin/jdeprscan', 'bin/jdeps'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jstatd.jmod',
|
||||
jarContent: ['bin/jstatd'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.pack.jmod',
|
||||
jarContent: ['bin/unpack200', 'bin/pack200'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.hotspot.agent.jmod',
|
||||
jarContent: ['bin/jhsdb'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jfr.jmod',
|
||||
jarContent: ['bin/jfr'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.rmic.jmod',
|
||||
jarContent: ['bin/rmic'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'java.rmi.jmod',
|
||||
jarContent: ['bin/rmid', 'bin/rmiregistry'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'java.base.jmod',
|
||||
jarContent: ['bin/java', 'bin/keytool', 'lib/jspawnhelper'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jlink.jmod',
|
||||
jarContent: ['bin/jmod', 'bin/jlink', 'bin/jimage'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.scripting.nashorn.shell.jmod',
|
||||
jarContent: ['bin/jjs'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jcmd.jmod',
|
||||
jarContent: ['bin/jstack', 'bin/jcmd', 'bin/jps', 'bin/jmap', 'bin/jstat', 'bin/jinfo'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jshell.jmod',
|
||||
jarContent: ['bin/jshell'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.compiler.jmod',
|
||||
jarContent: ['bin/javac', 'bin/serialver'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'java.scripting.jmod',
|
||||
jarContent: ['bin/jrunscript'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jdi.jmod',
|
||||
jarContent: ['bin/jdb'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.javadoc.jmod',
|
||||
jarContent: ['bin/javadoc'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.jconsole.jmod',
|
||||
jarContent: ['bin/jconsole'],
|
||||
},
|
||||
{
|
||||
jarDir:
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||
jarName: 'jdk.javadoc.jmod',
|
||||
jarContent: ['bin/javadoc'],
|
||||
},
|
||||
@ -260,9 +239,7 @@ const extra = [
|
||||
]
|
||||
|
||||
// The list of readonly files in the GraalVM distribution.
|
||||
const readonly = [
|
||||
`enso/runtime/${GRAALVM}/Contents/Home/lib/server/classes.jsa`,
|
||||
]
|
||||
const readonly = [`enso/runtime/${GRAALVM}/Contents/Home/lib/server/classes.jsa`]
|
||||
|
||||
function beforeSign() {
|
||||
for (let file of readonly) {
|
||||
|
@ -10,7 +10,7 @@ module.exports = {
|
||||
index: path.resolve(thisPath, 'src', 'index.js'),
|
||||
},
|
||||
mode: 'production',
|
||||
target: "electron-main",
|
||||
target: 'electron-main',
|
||||
output: {
|
||||
path: path.resolve(distPath, 'content'),
|
||||
filename: '[name].js',
|
||||
@ -19,12 +19,12 @@ module.exports = {
|
||||
new Copy([
|
||||
{
|
||||
from: path.resolve(thisPath, 'package.json'),
|
||||
to : path.resolve(distPath,'content','package.json')
|
||||
to: path.resolve(distPath, 'content', 'package.json'),
|
||||
},
|
||||
{
|
||||
from: path.resolve(thisPath, 'src', 'preload.js'),
|
||||
to : path.resolve(distPath,'content','preload.js')
|
||||
}
|
||||
to: path.resolve(distPath, 'content', 'preload.js'),
|
||||
},
|
||||
]),
|
||||
],
|
||||
performance: {
|
||||
|
@ -1,6 +1,6 @@
|
||||
let config = {
|
||||
version: "1.0.0",
|
||||
name: "enso-studio-common",
|
||||
version: '1.0.0',
|
||||
name: 'enso-studio-common',
|
||||
}
|
||||
|
||||
module.exports = { config }
|
||||
|
@ -6,13 +6,13 @@
|
||||
// =================
|
||||
|
||||
export function ease_in_out_cubic(t) {
|
||||
return t<.5 ? 4*t*t*t : 1 - (-2*t+2) * (-2*t+2) * (-2*t+2) / 2
|
||||
return t < 0.5 ? 4 * t * t * t : 1 - ((-2 * t + 2) * (-2 * t + 2) * (-2 * t + 2)) / 2
|
||||
}
|
||||
|
||||
export function ease_in_out_quad(t) {
|
||||
return t<.5 ? 2*t*t : 1 - (-2*t+2)*(-2*t+2) / 2
|
||||
return t < 0.5 ? 2 * t * t : 1 - ((-2 * t + 2) * (-2 * t + 2)) / 2
|
||||
}
|
||||
|
||||
export function ease_out_quart(t) {
|
||||
return 1-(--t)*t*t*t
|
||||
return 1 - --t * t * t * t
|
||||
}
|
||||
|
@ -3,14 +3,12 @@ import * as html_utils from './html_utils'
|
||||
import * as math from './math'
|
||||
import * as svg from './svg'
|
||||
|
||||
|
||||
|
||||
// =========================
|
||||
// === ProgressIndicator ===
|
||||
// =========================
|
||||
|
||||
let bg_color = "rgb(249,250,251)"
|
||||
let loader_color = "#303030"
|
||||
let bg_color = 'rgb(249,250,251)'
|
||||
let loader_color = '#303030'
|
||||
let top_layer_index = 1000
|
||||
|
||||
/// Visual representation of the loader.
|
||||
@ -38,9 +36,9 @@ export class ProgressIndicator {
|
||||
progress_bar.innerHTML = progress_bar_svg
|
||||
center.appendChild(progress_bar)
|
||||
|
||||
this.progress_indicator = document.getElementById("progress_indicator")
|
||||
this.progress_indicator_mask = document.getElementById("progress_indicator_mask")
|
||||
this.progress_indicator_corner = document.getElementById("progress_indicator_corner")
|
||||
this.progress_indicator = document.getElementById('progress_indicator')
|
||||
this.progress_indicator_mask = document.getElementById('progress_indicator_mask')
|
||||
this.progress_indicator_corner = document.getElementById('progress_indicator_corner')
|
||||
|
||||
this.set(0)
|
||||
this.set_opacity(0)
|
||||
@ -48,7 +46,9 @@ export class ProgressIndicator {
|
||||
if (cfg.use_loader) {
|
||||
this.initialized = this.animate_show()
|
||||
} else {
|
||||
this.initialized = new Promise((resolve) => {resolve()})
|
||||
this.initialized = new Promise(resolve => {
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
this.animate_rotation()
|
||||
this.destroyed = false
|
||||
@ -64,14 +64,21 @@ export class ProgressIndicator {
|
||||
let mid_radius = (inner_radius + outer_radius) / 2
|
||||
let bar_width = outer_radius - inner_radius
|
||||
|
||||
return svg.new_svg(width,height,`
|
||||
return svg.new_svg(
|
||||
width,
|
||||
height,
|
||||
`
|
||||
<defs>
|
||||
<g id="progress_bar">
|
||||
<circle fill="${loader_color}" r="${outer_radius}" />
|
||||
<circle fill="${bg_color}" r="${inner_radius}" />
|
||||
<path fill="${bg_color}" opacity="${alpha}" id="progress_indicator_mask" />
|
||||
<circle fill="${loader_color}" r="${bar_width/2}" id="progress_indicator_corner" />
|
||||
<circle fill="${loader_color}" r="${bar_width/2}" cy="-${mid_radius}" />
|
||||
<circle fill="${loader_color}" r="${
|
||||
bar_width / 2
|
||||
}" id="progress_indicator_corner" />
|
||||
<circle fill="${loader_color}" r="${
|
||||
bar_width / 2
|
||||
}" cy="-${mid_radius}" />
|
||||
</g>
|
||||
</defs>
|
||||
<g transform="translate(${width / 2},${height / 2})">
|
||||
@ -79,7 +86,8 @@ export class ProgressIndicator {
|
||||
<use xlink:href="#progress_bar"></use>
|
||||
</g>
|
||||
</g>
|
||||
`)
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
/// Destroys the component. Removes it from the stage and destroys attached callbacks.
|
||||
@ -95,19 +103,19 @@ export class ProgressIndicator {
|
||||
let angle_span = max_angle - min_angle
|
||||
let mask_angle = (1 - value) * angle_span - min_angle
|
||||
let corner_pos = math.polar_to_cartesian(54, -mask_angle)
|
||||
this.progress_indicator_mask.setAttribute("d", svg.arc(128, -mask_angle))
|
||||
this.progress_indicator_corner.setAttribute("cx", corner_pos.x)
|
||||
this.progress_indicator_corner.setAttribute("cy", corner_pos.y)
|
||||
this.progress_indicator_mask.setAttribute('d', svg.arc(128, -mask_angle))
|
||||
this.progress_indicator_corner.setAttribute('cx', corner_pos.x)
|
||||
this.progress_indicator_corner.setAttribute('cy', corner_pos.y)
|
||||
}
|
||||
|
||||
/// Set the opacity of the loader.
|
||||
set_opacity(val) {
|
||||
this.progress_indicator.setAttribute("opacity",val)
|
||||
this.progress_indicator.setAttribute('opacity', val)
|
||||
}
|
||||
|
||||
/// Set the rotation of the loader (angles).
|
||||
set_rotation(val) {
|
||||
this.progress_indicator.setAttribute("transform",`rotate(${val},0,0)`)
|
||||
this.progress_indicator.setAttribute('transform', `rotate(${val},0,0)`)
|
||||
}
|
||||
|
||||
/// Start show animation. It is used after the loader is created.
|
||||
@ -116,7 +124,9 @@ export class ProgressIndicator {
|
||||
return new Promise(function (resolve, reject) {
|
||||
let alpha = 0
|
||||
function show_step() {
|
||||
if (alpha > 1) { alpha = 1 }
|
||||
if (alpha > 1) {
|
||||
alpha = 1
|
||||
}
|
||||
indicator.set_opacity(animation.ease_in_out_quad(alpha))
|
||||
alpha += 0.02
|
||||
if (alpha < 1) {
|
||||
@ -144,8 +154,6 @@ export class ProgressIndicator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Loader ===
|
||||
// ==============
|
||||
@ -163,7 +171,9 @@ export class Loader {
|
||||
|
||||
let self = this
|
||||
this.done_resolve = null
|
||||
this.done = new Promise((resolve) => {self.done_resolve = resolve})
|
||||
this.done = new Promise(resolve => {
|
||||
self.done_resolve = resolve
|
||||
})
|
||||
|
||||
for (let resource of resources) {
|
||||
this.total_bytes += parseInt(resource.headers.get('Content-Length'))
|
||||
@ -171,7 +181,9 @@ export class Loader {
|
||||
}
|
||||
|
||||
if (Number.isNaN(this.total_bytes)) {
|
||||
console.error("Loader error. Server is not configured to send the 'Content-Length' metadata.")
|
||||
console.error(
|
||||
"Loader error. Server is not configured to send the 'Content-Length' metadata."
|
||||
)
|
||||
this.total_bytes = 0
|
||||
}
|
||||
}
|
||||
@ -210,7 +222,9 @@ export class Loader {
|
||||
|
||||
let indicator_progress = this.value() * this.cap_progress_at
|
||||
this.indicator.set(indicator_progress)
|
||||
if (this.is_done()) { this.done_resolve() }
|
||||
if (this.is_done()) {
|
||||
this.done_resolve()
|
||||
}
|
||||
}
|
||||
|
||||
/// Download percentage value.
|
||||
@ -239,7 +253,7 @@ export class Loader {
|
||||
return new WritableStream({
|
||||
write(t) {
|
||||
loader.on_receive(t.length)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,19 @@
|
||||
/// This module defines a common math operations.
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Math ===
|
||||
// ============
|
||||
|
||||
/// Converts the polar coordinates to cartesian ones.
|
||||
export function polar_to_cartesian(radius, angle_degrees) {
|
||||
let angle = (angle_degrees-90) * Math.PI / 180.0
|
||||
let angle = ((angle_degrees - 90) * Math.PI) / 180.0
|
||||
return {
|
||||
x: radius * Math.cos(angle),
|
||||
y : radius * Math.sin(angle)
|
||||
y: radius * Math.sin(angle),
|
||||
}
|
||||
}
|
||||
|
||||
/// Format bytes as megabytes with a single precision number.
|
||||
export function format_mb(bytes) {
|
||||
return Math.round(10 * bytes / (1024 * 1024)) / 10
|
||||
return Math.round((10 * bytes) / (1024 * 1024)) / 10
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ import * as mime from 'mime-types'
|
||||
import * as path from 'path'
|
||||
import * as portfinder from 'portfinder'
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Port ===
|
||||
// ============
|
||||
@ -19,8 +17,6 @@ async function findPort(cfg) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Server ===
|
||||
// ==============
|
||||
@ -35,22 +31,28 @@ class Server {
|
||||
this.dir = cfg.dir
|
||||
this.port = cfg.port
|
||||
this.fallback = cfg.fallback
|
||||
this.server = createServers({
|
||||
this.server = createServers(
|
||||
{
|
||||
http: this.port,
|
||||
handler: function (request, response) {
|
||||
self.process(request.url, response)
|
||||
}
|
||||
},
|
||||
},
|
||||
function (errs) {
|
||||
if (errs) { return console.log(errs.http) }
|
||||
if (errs) {
|
||||
return console.log(errs.http)
|
||||
}
|
||||
console.log(`Server started on port ${this.port}.`)
|
||||
console.log(`Serving files from '${process.cwd()}/${this.dir}'.`)
|
||||
}.bind(this))
|
||||
}.bind(this)
|
||||
)
|
||||
}
|
||||
|
||||
process(resource, response) {
|
||||
let resource_file = `${this.dir}${resource}`
|
||||
fs.readFile(resource_file, function (err,data) {
|
||||
fs.readFile(
|
||||
resource_file,
|
||||
function (err, data) {
|
||||
if (err) {
|
||||
let fallback = this.fallback
|
||||
if (fallback) {
|
||||
@ -70,7 +72,8 @@ class Server {
|
||||
response.writeHead(200)
|
||||
response.end(data)
|
||||
}
|
||||
}.bind(this))
|
||||
}.bind(this)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
import * as math from './math'
|
||||
|
||||
|
||||
|
||||
// ===========
|
||||
// === SVG ===
|
||||
// ===========
|
||||
@ -27,6 +25,6 @@ export function arc(radius, end_angle){
|
||||
}
|
||||
let start = math.polar_to_cartesian(radius, end_angle)
|
||||
let end = math.polar_to_cartesian(radius, start_angle)
|
||||
let large_arc = end_angle - start_angle <= 180 ? "0" : "1"
|
||||
let large_arc = end_angle - start_angle <= 180 ? '0' : '1'
|
||||
return `M 0 0 L ${start.x} ${start.y} A ${radius} ${radius} 0 ${large_arc} 0 ${end.x} ${end.y}`
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
let config = {
|
||||
name: "enso-studio-content",
|
||||
version: "1.0.0",
|
||||
name: 'enso-studio-content',
|
||||
version: '1.0.0',
|
||||
scripts: {
|
||||
"build": "npx webpack",
|
||||
"watch": "npx webpack-dev-server"
|
||||
build: 'npx webpack',
|
||||
watch: 'npx webpack-dev-server',
|
||||
},
|
||||
dependencies: {
|
||||
"enso-studio-common": "1.0.0",
|
||||
"firebase": "^8.6.8",
|
||||
"firebaseui": "^4.8.0",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"html-loader": "^1.3.2",
|
||||
"mixpanel-browser": "2.40.1"
|
||||
'enso-studio-common': '1.0.0',
|
||||
firebase: '^8.6.8',
|
||||
firebaseui: '^4.8.0',
|
||||
'copy-webpack-plugin': '^5.1.1',
|
||||
'html-loader': '^1.3.2',
|
||||
'mixpanel-browser': '2.40.1',
|
||||
},
|
||||
devDependencies: {
|
||||
"compression-webpack-plugin": "^3.1.0",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"yaml-loader": "^0.6.0",
|
||||
"ts-loader": "^8.0.3",
|
||||
"typescript": "^4.0.2",
|
||||
"webpack": "^4.44.1",
|
||||
"webpack-cli": "^3.3.12"
|
||||
}
|
||||
'compression-webpack-plugin': '^3.1.0',
|
||||
'copy-webpack-plugin': '^5.1.1',
|
||||
'yaml-loader': '^0.6.0',
|
||||
'ts-loader': '^8.0.3',
|
||||
typescript: '^4.0.2',
|
||||
webpack: '^4.44.1',
|
||||
'webpack-cli': '^3.3.12',
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = { config }
|
||||
|
@ -1,37 +1,42 @@
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
font-family: "Source Code Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtlsnztA.ttf) format('truetype');
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtlsnztA.ttf)
|
||||
format("truetype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
font-family: "Source Code Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_SiYsKILxRpg3hIP6sJ7fM7PqVOg.ttf) format('truetype');
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_SiYsKILxRpg3hIP6sJ7fM7PqVOg.ttf)
|
||||
format("truetype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
font-family: "Source Code Pro";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtzsjztA.ttf) format('truetype');
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtzsjztA.ttf)
|
||||
format("truetype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
font-family: "Source Code Pro";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqt4s_ztA.ttf) format('truetype');
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqt4s_ztA.ttf)
|
||||
format("truetype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
font-family: "Source Code Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqths7ztA.ttf) format('truetype');
|
||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqths7ztA.ttf)
|
||||
format("truetype");
|
||||
}
|
||||
.enso.docs {
|
||||
font-family: Causten, DejaVuSansMonoBook, sans-serif;
|
||||
@ -60,7 +65,7 @@
|
||||
font-size: 14px;
|
||||
padding: 1px 0px 2px;
|
||||
margin-top: 10px;
|
||||
color: #4EA5FD;
|
||||
color: #4ea5fd;
|
||||
-webkit-box-decoration-break: clone;
|
||||
}
|
||||
.enso.docs .doc-copy-btn {
|
||||
@ -164,7 +169,7 @@
|
||||
line-height: 1.35;
|
||||
box-decoration-break: clone;
|
||||
-webkit-box-decoration-break: clone;
|
||||
background-color: #E7E9EB;
|
||||
background-color: #e7e9eb;
|
||||
}
|
||||
.light-theme .enso.docs .tag .details {
|
||||
font-weight: 700;
|
||||
@ -172,7 +177,7 @@
|
||||
.light-theme .enso.docs .important,
|
||||
.light-theme .enso.docs .info,
|
||||
.light-theme .enso.docs .example {
|
||||
background-color: #E7E9EB;
|
||||
background-color: #e7e9eb;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
font-size: 14px;
|
||||
padding: 1px 0px 2px;
|
||||
margin-top: 10px;
|
||||
color: #4EA5FD;
|
||||
color: #4ea5fd;
|
||||
-webkit-box-decoration-break: clone;
|
||||
}
|
||||
.doc-copy-btn {
|
||||
@ -136,7 +136,7 @@
|
||||
line-height: 1.35;
|
||||
box-decoration-break: clone;
|
||||
-webkit-box-decoration-break: clone;
|
||||
background-color: #E7E9EB;
|
||||
background-color: #e7e9eb;
|
||||
}
|
||||
.details {
|
||||
font-weight: 700;
|
||||
@ -145,7 +145,7 @@
|
||||
.important,
|
||||
.info,
|
||||
.example {
|
||||
background-color: #E7E9EB;
|
||||
background-color: #e7e9eb;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
.summary {
|
||||
|
@ -1,12 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="utf-8" />
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<!-- FIXME https://github.com/validator/validator/issues/917 -->
|
||||
<!-- FIXME Security Vulnerabilities: https://github.com/enso-org/ide/issues/226 -->
|
||||
<!-- NOTE `frame-src` section of `http-equiv` required only for authorization -->
|
||||
<meta http-equiv="Content-Security-Policy" content="
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
default-src 'self';
|
||||
frame-src 'self' data: https://accounts.google.com https://enso-org.firebaseapp.com;
|
||||
script-src 'self' 'unsafe-eval' data: https://*;
|
||||
@ -16,7 +18,9 @@
|
||||
img-src 'self' blob: data: https://*;
|
||||
font-src 'self' data: https://*"
|
||||
/>
|
||||
<meta name="viewport" content="
|
||||
<meta
|
||||
name="viewport"
|
||||
content="
|
||||
width=device-width,
|
||||
initial-scale = 1.0,
|
||||
maximum-scale = 1.0,
|
||||
@ -25,7 +29,11 @@
|
||||
<title>Enso</title>
|
||||
<link rel="stylesheet" href="/assets/style.css" />
|
||||
<link rel="stylesheet" href="/assets/docsStyle.css" />
|
||||
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.css" />
|
||||
<link
|
||||
type="text/css"
|
||||
rel="stylesheet"
|
||||
href="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.css"
|
||||
/>
|
||||
<script type="module" src="/assets/index.js" defer></script>
|
||||
<script type="module" src="/assets/run.js" defer></script>
|
||||
</head>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/// This module defines the Project Manager endpoint.
|
||||
|
||||
const PROJECT_MANAGER_ENDPOINT = "ws://127.0.0.1:30535"
|
||||
const PROJECT_MANAGER_ENDPOINT = 'ws://127.0.0.1:30535'
|
||||
|
||||
const MISSING_COMPONENT_ACTION_INSTALL = 'Install'
|
||||
|
||||
@ -8,7 +8,6 @@ const MISSING_COMPONENT_ACTION_INSTALL = 'Install'
|
||||
* A WebSocket endpoint to the project manager.
|
||||
*/
|
||||
class ProjectManager {
|
||||
|
||||
protected readonly connection_url: string
|
||||
|
||||
constructor(connection_url: string) {
|
||||
@ -23,12 +22,11 @@ class ProjectManager {
|
||||
* Get the projects list.
|
||||
*/
|
||||
listProjects(): any {
|
||||
const req =
|
||||
{
|
||||
jsonrpc: "2.0",
|
||||
const req = {
|
||||
jsonrpc: '2.0',
|
||||
id: 0,
|
||||
method: "project/list",
|
||||
params: {}
|
||||
method: 'project/list',
|
||||
params: {},
|
||||
}
|
||||
|
||||
const ws = new WebSocket(this.connection_url)
|
||||
@ -59,14 +57,13 @@ class ProjectManager {
|
||||
}
|
||||
if (template !== undefined) {
|
||||
// @ts-ignore
|
||||
params["projectTemplate"] = template
|
||||
params['projectTemplate'] = template
|
||||
}
|
||||
const req =
|
||||
{
|
||||
jsonrpc: "2.0",
|
||||
const req = {
|
||||
jsonrpc: '2.0',
|
||||
id: 0,
|
||||
method: "project/create",
|
||||
params: params
|
||||
method: 'project/create',
|
||||
params: params,
|
||||
}
|
||||
|
||||
const ws = new WebSocket(this.connection_url)
|
||||
@ -74,10 +71,10 @@ class ProjectManager {
|
||||
ws.onopen = () => {
|
||||
ws.send(JSON.stringify(req))
|
||||
}
|
||||
ws.onmessage = (event) => {
|
||||
ws.onmessage = event => {
|
||||
resolve(JSON.parse(event.data))
|
||||
}
|
||||
ws.onerror = (error) => {
|
||||
ws.onerror = error => {
|
||||
reject(error)
|
||||
}
|
||||
}).finally(() => ws.close())
|
||||
|
@ -11,10 +11,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenExtraLight/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenExtraLight/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenExtraLight/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenExtraLight/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
font-display: block;
|
||||
@ -22,10 +20,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenLight/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenLight/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenLight/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenLight/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: block;
|
||||
@ -33,10 +29,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenRegular/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenRegular/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenRegular/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenRegular/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
@ -44,10 +38,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenMedium/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenMedium/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenMedium/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenMedium/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: block;
|
||||
@ -55,10 +47,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenSemiBold/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenSemiBold/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenSemiBold/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenSemiBold/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: block;
|
||||
@ -66,10 +56,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenBold/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenBold/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenBold/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenBold/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
@ -77,10 +65,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenExtraBold/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenExtraBold/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenExtraBold/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenExtraBold/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: block;
|
||||
@ -88,10 +74,8 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Causten";
|
||||
src: url("/assets/fonts/CaustenBlack/font.woff2")
|
||||
format("woff2"),
|
||||
url("/assets/fonts/CaustenBlack/font.woff")
|
||||
format("woff");
|
||||
src: url("/assets/fonts/CaustenBlack/font.woff2") format("woff2"),
|
||||
url("/assets/fonts/CaustenBlack/font.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: block;
|
||||
@ -99,7 +83,8 @@
|
||||
|
||||
/* End of fonts */
|
||||
|
||||
html, body {
|
||||
html,
|
||||
body {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
@ -274,12 +259,12 @@ body {
|
||||
.templates-view .side-menu ul img {
|
||||
width: 14px;
|
||||
padding: 8px;
|
||||
background-color: #4180F1;
|
||||
background-color: #4180f1;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.templates-view .side-menu li#projects-list-new-project img {
|
||||
background-color: #EFEFEF;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
.templates-view .content {
|
||||
|
@ -1,5 +1,10 @@
|
||||
<div id="templates-view" class="templates-view">
|
||||
<div id="templates-status-box" style="color: DarkSalmon; text-align: center; visibility: hidden;">Hidden</div>
|
||||
<div
|
||||
id="templates-status-box"
|
||||
style="color: DarkSalmon; text-align: center; visibility: hidden"
|
||||
>
|
||||
Hidden
|
||||
</div>
|
||||
<div class="container">
|
||||
<aside class="side-menu">
|
||||
<h2>Your projects</h2>
|
||||
@ -16,26 +21,24 @@
|
||||
<div class="cards">
|
||||
<div class="row">
|
||||
<div id="card-spreadsheets" class="card card-spreadsheets">
|
||||
<img
|
||||
src="/assets/spreadsheets.png"
|
||||
/>
|
||||
<img src="/assets/spreadsheets.png" />
|
||||
<h3>Combine spreadsheets</h3>
|
||||
<p>
|
||||
Glue multiple spreadsheets together to analyse all your data at once.
|
||||
Glue multiple spreadsheets together to analyse all your data at
|
||||
once.
|
||||
</p>
|
||||
</div>
|
||||
<div id="card-geo" class="card card-geo">
|
||||
<h3>Geospatial analysis</h3>
|
||||
<p>
|
||||
Learn where to open a coffee shop to maximize your income.
|
||||
</p>
|
||||
<p>Learn where to open a coffee shop to maximize your income.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="card-visualize" class="card card-visualize">
|
||||
<h3>Analyze GitHub stars</h3>
|
||||
<p>
|
||||
Find out which of Enso's repositories are most popular over time.
|
||||
Find out which of Enso's repositories are most popular over
|
||||
time.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -11,11 +11,7 @@ const CARD_SPREADSHEETS = 'card-spreadsheets'
|
||||
const CARD_GEO = 'card-geo'
|
||||
const CARD_VISUALIZE = 'card-visualize'
|
||||
|
||||
const ALL_CARDS = [
|
||||
CARD_SPREADSHEETS,
|
||||
CARD_GEO,
|
||||
CARD_VISUALIZE,
|
||||
]
|
||||
const ALL_CARDS = [CARD_SPREADSHEETS, CARD_GEO, CARD_VISUALIZE]
|
||||
|
||||
/**
|
||||
* The sore for hidden elements.
|
||||
@ -46,7 +42,7 @@ async function loadTemplatesView(openProject: (project: string) => void): Promis
|
||||
try {
|
||||
await loadProjectsList(openProject)
|
||||
} catch (error) {
|
||||
displayStatusBox("Failed to load projects.")
|
||||
displayStatusBox('Failed to load projects.')
|
||||
}
|
||||
|
||||
setTemplateCardHandlers(openProject)
|
||||
@ -118,15 +114,14 @@ async function loadProjectsList(openProject: (project: string) => void): Promise
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error('onclick', PROJECTS_LIST_NEW_PROJECT, error)
|
||||
displayStatusBox("Failed to create a new project.")
|
||||
displayStatusBox('Failed to create a new project.')
|
||||
})
|
||||
}
|
||||
|
||||
const projectsListResult = await PM.listProjects()
|
||||
const projectsList = projectsListResult
|
||||
.result
|
||||
.projects
|
||||
.map((project: any) => buildProjectListNode(project.name, openProject))
|
||||
const projectsList = projectsListResult.result.projects.map((project: any) =>
|
||||
buildProjectListNode(project.name, openProject)
|
||||
)
|
||||
|
||||
projectsList.forEach((element: any) => {
|
||||
projectsListNode.insertBefore(element, newProjectNode)
|
||||
@ -139,7 +134,10 @@ async function loadProjectsList(openProject: (project: string) => void): Promise
|
||||
* @param projectName the name of the project
|
||||
* @param openProject the callback that opens IDE with the provided project
|
||||
*/
|
||||
function buildProjectListNode(projectName: string, openProject: (project: string) => void): HTMLLIElement {
|
||||
function buildProjectListNode(
|
||||
projectName: string,
|
||||
openProject: (project: string) => void
|
||||
): HTMLLIElement {
|
||||
const li = document.createElement('li')
|
||||
li.setAttribute('style', 'cursor: pointer;')
|
||||
li.onclick = () => {
|
||||
@ -176,7 +174,10 @@ function setTemplateCardHandlers(openProject: (project: String) => void): void {
|
||||
* @param element the HTML element of the template card
|
||||
* @param openProject the callback that opens IDE with the provided project
|
||||
*/
|
||||
function setTemplateCardHandler(element: HTMLElement, openProject: (project: string) => void): void {
|
||||
function setTemplateCardHandler(
|
||||
element: HTMLElement,
|
||||
openProject: (project: string) => void
|
||||
): void {
|
||||
element.setAttribute('style', 'cursor: pointer;')
|
||||
element.onclick = () => {
|
||||
const projectName = getProjectName(element.id)
|
||||
@ -186,7 +187,7 @@ function setTemplateCardHandler(element: HTMLElement, openProject: (project: str
|
||||
PM.createProject(projectName, templateName)
|
||||
.then((response: any) => {
|
||||
if (response.error !== undefined) {
|
||||
console.error("Project manager createProject failed", response)
|
||||
console.error('Project manager createProject failed', response)
|
||||
displayStatusBox(response.error.message)
|
||||
} else {
|
||||
restoreRootHtml()
|
||||
@ -195,7 +196,7 @@ function setTemplateCardHandler(element: HTMLElement, openProject: (project: str
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error('onclick', element.id, error)
|
||||
displayStatusBox("Failed to open a template.")
|
||||
displayStatusBox('Failed to open a template.')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as wasm_rust_glue from "wasm_rust_glue"
|
||||
import * as wasm_rust_glue from 'wasm_rust_glue'
|
||||
|
||||
/// WARNING
|
||||
/// This module is a hacky binding to wasm_pack. It works only if the wasm_pack output is
|
||||
|
@ -1,13 +1,13 @@
|
||||
let config = {
|
||||
name: "enso-studio-icons",
|
||||
version: "1.0.0",
|
||||
name: 'enso-studio-icons',
|
||||
version: '1.0.0',
|
||||
scripts: {
|
||||
"build": "node src/index.js"
|
||||
build: 'node src/index.js',
|
||||
},
|
||||
devDependencies: {
|
||||
"sharp": "^0.26.2",
|
||||
"to-ico": "^1.1.5"
|
||||
}
|
||||
sharp: '^0.26.2',
|
||||
'to-ico': '^1.1.5',
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = { config }
|
||||
|
@ -23,19 +23,29 @@ class Logo {
|
||||
this.d = 4
|
||||
let innerSize = 56
|
||||
this.scale1 = innerSize / 64
|
||||
this.scale = (this.xsize / 64)
|
||||
this.scale = this.xsize / 64
|
||||
this.tx = (64 - innerSize) / 2
|
||||
if (this.compatibleMode) { this.ref = "xlink:href" } else { this.ref = "href" }
|
||||
if (this.compatibleMode) {
|
||||
this.ref = 'xlink:href'
|
||||
} else {
|
||||
this.ref = 'href'
|
||||
}
|
||||
this.defs = ''
|
||||
}
|
||||
|
||||
generate() {
|
||||
return `
|
||||
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="${this.xsize}" width="${this.xsize}" viewBox="0 0 ${this.xsize} ${this.xsize}">
|
||||
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="${
|
||||
this.xsize
|
||||
}" width="${this.xsize}" viewBox="0 0 ${this.xsize} ${this.xsize}">
|
||||
<defs>
|
||||
<circle id="innerCircle" cx="32" cy="32" r="${this.innerRadius}"/>
|
||||
<circle id="leftAtom" cx="${this.borderWidth + this.borderOffset + this.atomRadius + this.atomDiff - this.d}" cy="32" r="${this.atomRadius + this.atomDiff + this.d}"/>
|
||||
<circle id="rightAtom" cx="${this.borderWidth + this.borderOffset + 3 * this.atomRadius + this.atomDiff}" cy="32" r="${this.atomRadius - this.atomDiff}"/>
|
||||
<circle id="leftAtom" cx="${
|
||||
this.borderWidth + this.borderOffset + this.atomRadius + this.atomDiff - this.d
|
||||
}" cy="32" r="${this.atomRadius + this.atomDiff + this.d}"/>
|
||||
<circle id="rightAtom" cx="${
|
||||
this.borderWidth + this.borderOffset + 3 * this.atomRadius + this.atomDiff
|
||||
}" cy="32" r="${this.atomRadius - this.atomDiff}"/>
|
||||
<mask id="innerCircleMask">
|
||||
<use ${this.ref}="#innerCircle" fill="white"/>
|
||||
</mask>
|
||||
@ -101,17 +111,19 @@ class AppLogo extends Logo {
|
||||
}
|
||||
}
|
||||
|
||||
fastGenerate = (cons) => (...args) => new cons(...args).generate()
|
||||
fastGenerate =
|
||||
cons =>
|
||||
(...args) =>
|
||||
new cons(...args).generate()
|
||||
|
||||
exports.generateMinimalWhiteLogo = fastGenerate(AppLogo)
|
||||
|
||||
|
||||
const fss = require('fs')
|
||||
const fs = fss.promises
|
||||
const exec = require('child_process').exec
|
||||
const spawn = require('child_process').spawn
|
||||
const toIco = require('to-ico')
|
||||
const sharp = require("sharp")
|
||||
const sharp = require('sharp')
|
||||
const path = require('path')
|
||||
|
||||
const thisPath = path.resolve(__dirname)
|
||||
@ -119,7 +131,6 @@ const root = path.resolve(thisPath,'..','..','..','..','..')
|
||||
const distPath = path.resolve(root, 'dist', 'icons')
|
||||
const donePath = path.resolve(distPath, 'init')
|
||||
|
||||
|
||||
async function genIcons() {
|
||||
let sizes = [16, 32, 64, 128, 256, 512, 1024]
|
||||
let win_sizes = [16, 32, 64, 128, 256]
|
||||
@ -129,7 +140,7 @@ async function genIcons() {
|
||||
return
|
||||
}
|
||||
|
||||
console.log("Generating SVG icons.")
|
||||
console.log('Generating SVG icons.')
|
||||
await fs.mkdir(path.resolve(distPath, 'svg'), { recursive: true })
|
||||
await fs.mkdir(path.resolve(distPath, 'png'), { recursive: true })
|
||||
for (let size of sizes) {
|
||||
@ -141,38 +152,46 @@ async function genIcons() {
|
||||
/// AND KEEPS THE METADATA INFORMATION ABOUT DPI OF 144.
|
||||
/// It is required to properly display png images on MacOS.
|
||||
/// There is currently no other way in `sharp` to do it.
|
||||
console.log("Generating PNG icons.")
|
||||
console.log('Generating PNG icons.')
|
||||
for (let size of sizes) {
|
||||
let inName = `icon_${size}x${size}.svg`
|
||||
let outName = `icon_${size}x${size}.png`
|
||||
await sharp(`${distPath}/svg/${inName}`,{density:144}).png().resize({
|
||||
await sharp(`${distPath}/svg/${inName}`, { density: 144 })
|
||||
.png()
|
||||
.resize({
|
||||
width: size,
|
||||
kernel : sharp.kernel.mitchell
|
||||
}).toFile(`${distPath}/png/${outName}`)
|
||||
kernel: sharp.kernel.mitchell,
|
||||
})
|
||||
.toFile(`${distPath}/png/${outName}`)
|
||||
}
|
||||
|
||||
for (let size of sizes.slice(1)) {
|
||||
let size2 = size / 2
|
||||
let inName = `icon_${size}x${size}.svg`
|
||||
let outName = `icon_${size2}x${size2}@2x.png`
|
||||
await sharp(`${distPath}/svg/${inName}`,{density:144}).png().resize({
|
||||
await sharp(`${distPath}/svg/${inName}`, { density: 144 })
|
||||
.png()
|
||||
.resize({
|
||||
width: size,
|
||||
kernel : sharp.kernel.mitchell
|
||||
}).toFile(`${distPath}/png/${outName}`)
|
||||
kernel: sharp.kernel.mitchell,
|
||||
})
|
||||
.toFile(`${distPath}/png/${outName}`)
|
||||
}
|
||||
|
||||
console.log("Generating ICNS.")
|
||||
console.log('Generating ICNS.')
|
||||
exec(`cp -R ${distPath}/png ${distPath}/png.iconset`)
|
||||
exec(`iconutil --convert icns --output ${distPath}/icon.icns ${distPath}/png.iconset`)
|
||||
|
||||
console.log("Generating ICO.")
|
||||
console.log('Generating ICO.')
|
||||
let files = []
|
||||
for (let size of win_sizes) {
|
||||
let inName = `icon_${size}x${size}.png`
|
||||
let data = await fs.readFile(`${distPath}/png/${inName}`)
|
||||
files.push(data)
|
||||
}
|
||||
toIco(files).then(buf => { fss.writeFileSync(`${distPath}/icon.ico`, buf) })
|
||||
toIco(files).then(buf => {
|
||||
fss.writeFileSync(`${distPath}/icon.ico`, buf)
|
||||
})
|
||||
|
||||
let handle = await fs.open(donePath, 'w')
|
||||
await handle.close()
|
||||
|
@ -29,4 +29,3 @@
|
||||
"mock-fs": "^4.13.0"
|
||||
}
|
||||
}
|
||||
|
@ -9,18 +9,14 @@ const yargs = require('yargs')
|
||||
|
||||
const defaultPort = require('../../config.js').defaultLogServerPort
|
||||
|
||||
|
||||
module.exports = {
|
||||
startServer
|
||||
startServer,
|
||||
}
|
||||
|
||||
|
||||
function main(argv) {
|
||||
startServer(parse_args(argv).port)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =================
|
||||
// === Constants ===
|
||||
// =================
|
||||
@ -32,8 +28,6 @@ const httpStatusCodes = {
|
||||
internalServerError: 500,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ========================
|
||||
// === Argument Parsing ===
|
||||
// ========================
|
||||
@ -46,15 +40,12 @@ function parse_args(argv) {
|
||||
'The number of the port that this server will listen on. ' +
|
||||
'If the the number is 0 then an arbitrary free port will be chosen.',
|
||||
type: 'number',
|
||||
default: defaultPort
|
||||
default: defaultPort,
|
||||
})
|
||||
.help()
|
||||
.alias('help', 'h')
|
||||
.argv
|
||||
.alias('help', 'h').argv
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Server ===
|
||||
// ==============
|
||||
@ -63,9 +54,11 @@ function startServer(port) {
|
||||
const app = express()
|
||||
app.use(express.text())
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
if (typeof req.headers.origin === 'undefined' ||
|
||||
(new URL(req.headers.origin).hostname) !== 'localhost') {
|
||||
app.post('/', async (req, res) => {
|
||||
if (
|
||||
typeof req.headers.origin === 'undefined' ||
|
||||
new URL(req.headers.origin).hostname !== 'localhost'
|
||||
) {
|
||||
res.sendStatus(httpStatusCodes.forbidden)
|
||||
} else if (typeof req.body !== 'string') {
|
||||
res.sendStatus(httpStatusCodes.badRequest)
|
||||
@ -75,9 +68,7 @@ function startServer(port) {
|
||||
console.log(`Saved log from origin ${req.headers.origin}`)
|
||||
res.sendStatus(httpStatusCodes.noContent)
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'Could not write log file:\n' +
|
||||
e.message)
|
||||
console.error('Could not write log file:\n' + e.message)
|
||||
res.sendStatus(httpStatusCodes.internalServerError)
|
||||
}
|
||||
}
|
||||
@ -90,8 +81,6 @@ function startServer(port) {
|
||||
return server
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==================
|
||||
// === File Utils ===
|
||||
// ==================
|
||||
@ -107,7 +96,6 @@ async function writeLog(message) {
|
||||
await fs.promises.writeFile(`${dir}/${file}`, message)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current UTC date and time in the format "yyy-MM-dd_HH:mm:ss.".
|
||||
*/
|
||||
@ -115,19 +103,16 @@ function timestamp() {
|
||||
const d = new Date()
|
||||
|
||||
const year = d.getUTCFullYear().toString()
|
||||
const month = d.getUTCMonth().toString().padStart(2, "0")
|
||||
const day = d.getUTCDate().toString().padStart(2, "0")
|
||||
const month = d.getUTCMonth().toString().padStart(2, '0')
|
||||
const day = d.getUTCDate().toString().padStart(2, '0')
|
||||
|
||||
const hour = d.getUTCHours().toString().padStart(2, "0")
|
||||
const minute = d.getUTCMinutes().toString().padStart(2, "0")
|
||||
const second = d.getUTCSeconds().toString().padStart(2, "0")
|
||||
const hour = d.getUTCHours().toString().padStart(2, '0')
|
||||
const minute = d.getUTCMinutes().toString().padStart(2, '0')
|
||||
const second = d.getUTCSeconds().toString().padStart(2, '0')
|
||||
|
||||
return `${year}-${month}-${day}_${hour}:${minute}:${second}`
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (require.main === module) {
|
||||
const command_line_args = process.argv.slice(2)
|
||||
main(command_line_args)
|
||||
|
@ -6,11 +6,7 @@ const path = require('path')
|
||||
|
||||
const { startServer } = require('../server')
|
||||
|
||||
|
||||
|
||||
|
||||
describe('Logging Server', function () {
|
||||
|
||||
let server
|
||||
let serverUrl
|
||||
|
||||
@ -18,20 +14,20 @@ describe('Logging Server', function () {
|
||||
const goodConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
'Origin': 'http://localhost/'
|
||||
}
|
||||
Origin: 'http://localhost/',
|
||||
},
|
||||
}
|
||||
const wrongOriginConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
'Origin': 'http://attacker/'
|
||||
}
|
||||
Origin: 'http://attacker/',
|
||||
},
|
||||
}
|
||||
const wrongContentTypeConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'image/jpeg',
|
||||
'Origin': 'http://localhost/'
|
||||
}
|
||||
Origin: 'http://localhost/',
|
||||
},
|
||||
}
|
||||
|
||||
beforeEach(function (done) {
|
||||
@ -41,7 +37,7 @@ describe('Logging Server', function () {
|
||||
|
||||
// We mock the file system so the server does not actually write logs to disk.
|
||||
mockFs({
|
||||
[rawBodyDir]: mockFs.load(rawBodyDir)
|
||||
[rawBodyDir]: mockFs.load(rawBodyDir),
|
||||
})
|
||||
|
||||
const port = 0 // Choose an arbitrary available port
|
||||
@ -74,12 +70,11 @@ describe('Logging Server', function () {
|
||||
await Promise.allSettled([
|
||||
axios.post(serverUrl, '', goodConfig),
|
||||
axios.post(serverUrl, '', wrongOriginConfig),
|
||||
axios.post(serverUrl, '', wrongContentTypeConfig)
|
||||
axios.post(serverUrl, '', wrongContentTypeConfig),
|
||||
])
|
||||
|
||||
await axios.post(serverUrl, dummyMessage, goodConfig)
|
||||
const log_files = fs.readdirSync('log/')
|
||||
assert(log_files.some(file =>
|
||||
fs.readFileSync(`log/${file}`).toString() === dummyMessage))
|
||||
assert(log_files.some(file => fs.readFileSync(`log/${file}`).toString() === dummyMessage))
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
let config = {
|
||||
name: 'enso-studio-project-manager',
|
||||
version: "1.0.0",
|
||||
version: '1.0.0',
|
||||
scripts: {
|
||||
build: 'npx ts-node src/build.ts',
|
||||
},
|
||||
|
@ -39,7 +39,10 @@ async function get_build_config() {
|
||||
// === Project Manager ===
|
||||
// =======================
|
||||
|
||||
interface BuildInfo { version: string, target: string }
|
||||
interface BuildInfo {
|
||||
version: string
|
||||
target: string
|
||||
}
|
||||
|
||||
function get_project_manager_url({ version, target }: BuildInfo): string {
|
||||
console.log('webpack target ' + target)
|
||||
@ -145,7 +148,8 @@ async function download_project_manager(file_url: string, overwrite: boolean): P
|
||||
const target_file = fss.createWriteStream(file_path)
|
||||
const progress_indicator = new DownloadProgressIndicator()
|
||||
await new Promise((resolve, reject) =>
|
||||
http.get(options, (res: IncomingMessage) => {
|
||||
http
|
||||
.get(options, (res: IncomingMessage) => {
|
||||
res.on('data', (data: string) => {
|
||||
target_file.write(data)
|
||||
progress_indicator.add_progress_bytes(data.length)
|
||||
@ -154,7 +158,8 @@ async function download_project_manager(file_url: string, overwrite: boolean): P
|
||||
console.log(`${file_url} downloaded to "${file_path}".`)
|
||||
resolve(undefined)
|
||||
})
|
||||
}).on('error', async (e: http.ClientRequest) => {
|
||||
})
|
||||
.on('error', async (e: http.ClientRequest) => {
|
||||
target_file.end()
|
||||
await fs.rm(file_path)
|
||||
reject('Error: The download of the project manager was interrupted:\n' + e)
|
||||
@ -193,9 +198,10 @@ async function main() {
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
if (buildInfo.version !== existing_build_info?.version ||
|
||||
buildInfo.target !== existing_build_info?.target) {
|
||||
|
||||
if (
|
||||
buildInfo.version !== existing_build_info?.version ||
|
||||
buildInfo.target !== existing_build_info?.target
|
||||
) {
|
||||
// We remove the build info file to avoid misinformation if the build is interrupted during
|
||||
// the call to `download_project_manager`.
|
||||
// We use `force: true` because the file might not exist.
|
||||
|
@ -2,8 +2,7 @@
|
||||
/// which scans the GLSL code and mangles all names of primitive functions. This way we can define
|
||||
/// overloaded functions the same way as we did in GLSL 100.
|
||||
|
||||
let builtins =
|
||||
`float radians(float degrees)
|
||||
let builtins = `float radians(float degrees)
|
||||
vec2 radians(vec2 degrees)
|
||||
vec3 radians(vec3 degrees)
|
||||
vec4 radians(vec4 degrees)
|
||||
@ -223,8 +222,9 @@ function redirect_builtins() {
|
||||
let argsStr = match[3]
|
||||
let args = argsStr.split(', ').map(v => v.split(' '))
|
||||
let argNames = args.map(a => a[1])
|
||||
let redirection =
|
||||
`${outType} overloaded_${fname} (${argsStr}) {return ${fname}(${argNames.join(',')});}`
|
||||
let redirection = `${outType} overloaded_${fname} (${argsStr}) {return ${fname}(${argNames.join(
|
||||
','
|
||||
)});}`
|
||||
names.push(fname)
|
||||
redirections.push(redirection)
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ export class TextInputHandlers {
|
||||
this.text_area.focus()
|
||||
this.bind_text_area_events()
|
||||
this.bind_window_events()
|
||||
|
||||
}
|
||||
|
||||
// Set event handler. The name can be 'keyup' or 'keydown'.
|
||||
@ -46,11 +45,15 @@ export class TextInputHandlers {
|
||||
bind_text_area_events() {
|
||||
this.text_area.addEventListener('cut', e => {
|
||||
// Clear textarea in next frame (after cutting).
|
||||
setTimeout(_ => {this.text_area.value = "";}, 0)
|
||||
setTimeout(_ => {
|
||||
this.text_area.value = ''
|
||||
}, 0)
|
||||
})
|
||||
this.text_area.addEventListener('copy', e => {
|
||||
// Clear textarea in next frame (after copying).
|
||||
setTimeout(_ => {this.text_area.value = "";}, 0)
|
||||
setTimeout(_ => {
|
||||
this.text_area.value = ''
|
||||
}, 0)
|
||||
})
|
||||
this.text_area.addEventListener('paste', e => {
|
||||
if (typeof this.paste_handler !== 'undefined') {
|
||||
@ -67,7 +70,7 @@ export class TextInputHandlers {
|
||||
this.text_area.focus()
|
||||
})
|
||||
this.text_area.addEventListener('keydown', e => {
|
||||
let code = e.keyCode;
|
||||
let code = e.keyCode
|
||||
|
||||
let is_cut = code === 88 && (e.metaKey || e.ctrlKey)
|
||||
let is_copy = code === 67 && (e.metaKey || e.ctrlKey)
|
||||
@ -75,8 +78,8 @@ export class TextInputHandlers {
|
||||
if (is_copy || is_cut) {
|
||||
if (typeof this.copy_handler !== 'undefined') {
|
||||
this.text_area.value = this.copy_handler(is_cut)
|
||||
this.text_area.selectionStart = 0;
|
||||
this.text_area.selectionEnd = this.text_area.value.length;
|
||||
this.text_area.selectionStart = 0
|
||||
this.text_area.selectionEnd = this.text_area.value.length
|
||||
} else {
|
||||
e.preventDefault()
|
||||
}
|
||||
@ -107,7 +110,7 @@ export class TextInputHandlers {
|
||||
|
||||
// Creates invisible textarea.
|
||||
function create_invisible_text_area() {
|
||||
const css_class_name = "enso";
|
||||
const css_class_name = 'enso'
|
||||
|
||||
let text_area = document.createElement('textarea')
|
||||
text_area.className = css_class_name
|
||||
|
@ -1,8 +1,5 @@
|
||||
{
|
||||
"goog:chromeOptions": {
|
||||
"args": [
|
||||
"--no-proxy-server",
|
||||
"--no-sandbox"
|
||||
]
|
||||
"args": ["--no-proxy-server", "--no-sandbox"]
|
||||
}
|
||||
}
|
@ -25,10 +25,13 @@
|
||||
}
|
||||
|
||||
@keyframes sk-bouncedelay {
|
||||
0%, 80%, 100% {
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
transform: scale(0);
|
||||
} 40% {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
40% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
function fallbackWriteText(text) {
|
||||
let successful = false
|
||||
let textArea = document.createElement("textarea")
|
||||
let textArea = document.createElement('textarea')
|
||||
|
||||
// *** This styling is an extra step which is likely not required. ***
|
||||
//
|
||||
@ -44,14 +44,15 @@ function fallbackWriteText(text) {
|
||||
textArea.style.background = 'transparent'
|
||||
|
||||
textArea.value = text
|
||||
textArea.style.top = "0"
|
||||
textArea.style.left = "0"
|
||||
textArea.style.position = "fixed"
|
||||
textArea.style.top = '0'
|
||||
textArea.style.left = '0'
|
||||
textArea.style.position = 'fixed'
|
||||
document.body.appendChild(textArea)
|
||||
textArea.focus()
|
||||
textArea.select()
|
||||
try { successful = document.execCommand('copy') == 1 }
|
||||
catch (err) {}
|
||||
try {
|
||||
successful = document.execCommand('copy') == 1
|
||||
} catch (err) {}
|
||||
document.body.removeChild(textArea)
|
||||
if (!successful) {
|
||||
console.error('Could not write to clipboard.')
|
||||
@ -62,18 +63,21 @@ export function writeText(text) {
|
||||
if (!navigator.clipboard) {
|
||||
fallbackWriteText(text)
|
||||
} else {
|
||||
navigator.clipboard.writeText(text).then(() => {}, (err) => {
|
||||
navigator.clipboard.writeText(text).then(
|
||||
() => {},
|
||||
err => {
|
||||
fallbackWriteText(text)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Firefox only supports reading the clipboard in browser extensions, so it will
|
||||
/// only work with `cmd + v` shortcut. To learn more, see the
|
||||
/// [MSDN compatibility note](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText).
|
||||
let lastPaste = ""
|
||||
let lastPaste = ''
|
||||
function init_firefox_fallback() {
|
||||
window.addEventListener('paste', (event) => {
|
||||
window.addEventListener('paste', event => {
|
||||
lastPaste = (event.clipboardData || window.clipboardData).getData('text')
|
||||
})
|
||||
}
|
||||
@ -82,16 +86,17 @@ export function readText(callback) {
|
||||
if (!navigator.clipboard) {
|
||||
callback(lastPaste)
|
||||
} else {
|
||||
navigator.clipboard.readText().then(function(text) {
|
||||
navigator.clipboard.readText().then(
|
||||
function (text) {
|
||||
callback(text)
|
||||
}, function(err) {
|
||||
},
|
||||
function (err) {
|
||||
callback(lastPaste)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ======================
|
||||
// === Initialization ===
|
||||
// ======================
|
||||
|
@ -32,7 +32,6 @@ class IxPool {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ============
|
||||
// === Pool ===
|
||||
// ============
|
||||
@ -40,7 +39,7 @@ class IxPool {
|
||||
class Pool {
|
||||
constructor(cons) {
|
||||
this.cons = cons
|
||||
this.ixs = new IxPool
|
||||
this.ixs = new IxPool()
|
||||
}
|
||||
|
||||
reserve(...args) {
|
||||
@ -55,13 +54,11 @@ class Pool {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ============================
|
||||
// === IntersectionObserver ===
|
||||
// ============================
|
||||
|
||||
let intersectionObserverPool =
|
||||
new Pool((...args) => new IntersectionObserver(...args))
|
||||
let intersectionObserverPool = new Pool((...args) => new IntersectionObserver(...args))
|
||||
|
||||
export function intersection_observe(target, f) {
|
||||
let id = intersectionObserverPool.reserve(intersection_observer_update(f))
|
||||
@ -76,7 +73,7 @@ export function intersection_unobserve(id) {
|
||||
|
||||
function intersection_observer_update(f) {
|
||||
return entries => {
|
||||
let rect = entries[0].boundingClientRect;
|
||||
f(rect.x, rect.y, rect.width, rect.height);
|
||||
let rect = entries[0].boundingClientRect
|
||||
f(rect.x, rect.y, rect.width, rect.height)
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ class IxPool {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ============
|
||||
// === Pool ===
|
||||
// ============
|
||||
@ -32,7 +31,7 @@ class IxPool {
|
||||
class Pool {
|
||||
constructor(cons) {
|
||||
this.cons = cons
|
||||
this.ixs = new IxPool
|
||||
this.ixs = new IxPool()
|
||||
}
|
||||
|
||||
reserve(...args) {
|
||||
@ -47,7 +46,6 @@ class Pool {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ======================
|
||||
// === ResizeObserver ===
|
||||
// ======================
|
||||
@ -67,7 +65,7 @@ export function resize_unobserve(id) {
|
||||
|
||||
function resize_observer_update(f) {
|
||||
return entries => {
|
||||
let rect = entries[0].contentRect;
|
||||
f(rect.width, rect.height);
|
||||
let rect = entries[0].contentRect
|
||||
f(rect.width, rect.height)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user