diff --git a/cli/buildengine.ts b/cli/buildengine.ts index f189f69e0eb0..42ba3d8aab93 100644 --- a/cli/buildengine.ts +++ b/cli/buildengine.ts @@ -762,12 +762,12 @@ export async function compileWithLocalCompileService(extinfo: pxtc.ExtensionInfo const resp = await runDockerCompileAsync(extinfo.compileData); if (resp.hexfile) { - console.log("Compile successful"); + pxt.log("Compile successful"); } else { - console.log("Compile failed"); - console.log(resp.stderr) - console.log(resp.stdout) + pxt.log("Compile failed"); + pxt.log(resp.stderr) + pxt.log(resp.stdout) } return resp.hexfile && { diff --git a/cli/cli.ts b/cli/cli.ts index c338e1902382..3e6142fc6ed5 100644 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -7521,7 +7521,7 @@ export function mainCli(targetDir: string, args: string[] = process.argv.slice(2 if (process.env["PXT_DEBUG"]) { pxt.options.debug = true; - pxt.debug = pxt.log; + pxt.setLogLevel(pxt.LogLevel.Debug); } if (process.env["PXT_ASMDEBUG"]) { diff --git a/cli/commandparser.ts b/cli/commandparser.ts index 9c7632a2d44a..f14deab1344c 100644 --- a/cli/commandparser.ts +++ b/cli/commandparser.ts @@ -109,7 +109,9 @@ export class CommandParser { const debugFlag = flagName || match[2]; if (debugFlag == "debug" || debugFlag == "d" || debugFlag == "dbg") { pxt.options.debug = true; - pxt.debug = console.log; + if (pxt.options.debug) { + pxt.setLogLevel(pxt.LogLevel.Debug); + } pxt.log(`debug mode`); if (!flagName) continue; diff --git a/kiosk/src/index.tsx b/kiosk/src/index.tsx index 5556b2ab33cc..b0b06be9d0cf 100644 --- a/kiosk/src/index.tsx +++ b/kiosk/src/index.tsx @@ -37,7 +37,9 @@ window.addEventListener("DOMContentLoaded", () => { const bundle = (window as any).pxtTargetBundle as pxt.TargetBundle; pxt.options.debug = /dbg=1/i.test(window.location.href); - if (pxt.options.debug) pxt.debug = console.debug; + if (pxt.options.debug) { + pxt.setLogLevel(pxt.LogLevel.Debug) + } pxt.setupWebConfig((window as any).pxtConfig || pxt.webConfig); pxt.setAppTarget(bundle); diff --git a/localtypings/pxteditor.d.ts b/localtypings/pxteditor.d.ts index d174cd25a3a5..26dd274455a3 100644 --- a/localtypings/pxteditor.d.ts +++ b/localtypings/pxteditor.d.ts @@ -1120,6 +1120,7 @@ declare namespace pxt.editor { blocklyToolbox: ToolboxDefinition; monacoToolbox: ToolboxDefinition; projectView: IProjectView; + showNotification: (msg: string) => void; } export interface IToolboxOptions { @@ -1152,6 +1153,17 @@ declare namespace pxt.editor { // Used with @codeStart, @codeStop metadata (MINECRAFT HOC ONLY) onCodeStart?: () => void; onCodeStop?: () => void; + + experiments?: Experiment[]; + } + + export interface Experiment { + id: string; // == field in apptheme also assumes image at /static/experiments/ID.png + name: string; + description: string; + feedbackUrl?: string; // allows user to put feedback + enableOnline?: boolean; // requires internet connection, disable in offline app + onClick?: () => void; // code to run when the experiment is clicked } export interface FieldExtensionOptions { diff --git a/multiplayer/src/index.tsx b/multiplayer/src/index.tsx index b4d3d02a58e5..74966e894be3 100644 --- a/multiplayer/src/index.tsx +++ b/multiplayer/src/index.tsx @@ -37,8 +37,9 @@ window.addEventListener("DOMContentLoaded", () => { const bundle = (window as any).pxtTargetBundle as pxt.TargetBundle; pxt.options.debug = /dbg=1/i.test(window.location.href); - if (pxt.options.debug) - pxt.debug = console.debug; + if (pxt.options.debug) { + pxt.setLogLevel(pxt.LogLevel.Debug); + } pxt.setupWebConfig((window as any).pxtConfig || pxt.webConfig); pxt.setAppTarget(bundle); diff --git a/pxteditor/experiments.ts b/pxteditor/experiments.ts index 7c236ad92eea..a9724f2dd874 100644 --- a/pxteditor/experiments.ts +++ b/pxteditor/experiments.ts @@ -1,16 +1,16 @@ -export interface Experiment { - id: string; // == field in apptheme also assumes image at /static/experiments/ID.png - name: string; - description: string; - feedbackUrl?: string; // allows user to put feedback - enableOnline?: boolean; // requires internet connection, disable in offline app -} +import Experiment = pxt.editor.Experiment; function key(experiment: Experiment | string): string { const id = (typeof experiment === "object") ? experiment.id : experiment; return `experiments-${id}` } +let editorExtensionExperiments: Experiment[]; + +export function setEditorExtensionExperiments(experiments: Experiment[]) { + editorExtensionExperiments = experiments; +} + export function syncTheme() { const theme: pxt.Map = >pxt.savedAppTheme(); const r: pxt.Map = {}; @@ -31,7 +31,7 @@ export function syncTheme() { export function all(): Experiment[] { const ids = pxt.appTarget.appTheme.experiments; if (!ids) return []; - return [ + const exps: Experiment[] = [ { id: "print", name: lf("Print Code"), @@ -182,7 +182,11 @@ export function all(): Experiment[] { name: lf("Time Machine"), description: lf("Save and restore past versions of a project") }, - ].filter(experiment => ids.indexOf(experiment.id) > -1 && !(pxt.BrowserUtils.isPxtElectron() && experiment.enableOnline)); + ]; + + return exps.filter(experiment => ids.indexOf(experiment.id) > -1) + .concat(editorExtensionExperiments || []) + .filter(experiment => !(pxt.BrowserUtils.isPxtElectron() && experiment.enableOnline)); } export function clear() { @@ -199,7 +203,12 @@ export function isEnabled(experiment: Experiment | string): boolean { } export function toggle(experiment: Experiment) { - setState(experiment, !isEnabled(experiment)); + if (experiment.onClick) { + experiment.onClick(); + } + else { + setState(experiment, !isEnabled(experiment)); + } } export function state(): string { diff --git a/pxtlib/logger.ts b/pxtlib/logger.ts index 70ca85abdfad..aab44955e238 100644 --- a/pxtlib/logger.ts +++ b/pxtlib/logger.ts @@ -5,38 +5,77 @@ namespace pxt { debug(...args: any[]): void; error(...args: any[]): void; warn(...args: any[]): void; + + setLogLevel(level: LogLevel): void; + getLogLevel(): LogLevel; + } + + export enum LogLevel { + Debug = 0, + Info = 1, + Log = 1, + Warning = 2, + Error = 3 } - class ConsoleLogger implements Logger { + export class ConsoleLogger implements Logger { + protected logLevel: LogLevel; + + constructor() { + this.setLogLevel(LogLevel.Info); + } + + setLogLevel(level: LogLevel): void { + this.logLevel = level; + } + + getLogLevel(): LogLevel { + return this.logLevel; + } + info(...args: any[]): void { + if (!this.shouldLog(LogLevel.Info)) return; + if (console?.info) { console.info.call(null, ...args); } } log(...args: any[]): void { + if (!this.shouldLog(LogLevel.Log)) return; + if (console?.log) { console.log.call(null, ...args); } } debug(...args: any[]): void { + if (!this.shouldLog(LogLevel.Debug)) return; + if (console?.debug) { console.debug.call(null, ...args); } } error(...args: any[]): void { + if (!this.shouldLog(LogLevel.Error)) return; + if (console?.error) { console.error.call(null, ...args); } } warn(...args: any[]): void { + if (!this.shouldLog(LogLevel.Warning)) return; + if (console?.warn) { console.warn.call(null, ...args); } } + + protected shouldLog(level: LogLevel) { + return level >= this.logLevel; + } } let logger: Logger = new ConsoleLogger(); @@ -62,6 +101,14 @@ namespace pxt { } export function setLogger(impl: Logger) { + const level = logger?.getLogLevel(); logger = impl; + if (level !== undefined) { + logger.setLogLevel(level); + } + } + + export function setLogLevel(level: LogLevel) { + logger.setLogLevel(level); } } \ No newline at end of file diff --git a/pxtsim/allocator.ts b/pxtsim/allocator.ts index df3beeacdaf0..3148630910e0 100644 --- a/pxtsim/allocator.ts +++ b/pxtsim/allocator.ts @@ -234,7 +234,7 @@ namespace pxsim { } else { let instIdx = (pinDef.target).pinInstantiationIdx; if (!(!!instPins && instPins[instIdx] !== undefined)) { - pxt.log(`error: parts no pin found for PinInstantiationIdx: ${instIdx}. (Is the part missing an ArgumentRole or "trackArgs=" annotations?)`); + pxsim.log(`error: parts no pin found for PinInstantiationIdx: ${instIdx}. (Is the part missing an ArgumentRole or "trackArgs=" annotations?)`); return undefined; } pinTarget = instPins[instIdx]; @@ -282,13 +282,13 @@ namespace pxsim { fnNms.forEach(fnNm => { if (this.opts.fnArgs[fnNm]) this.opts.fnArgs[fnNm].forEach((targetArg: string) => { callsitesTrackedArgsHash[targetArg] = 1 }); }); let callsitesTrackedArgs: string[] = Object.keys(callsitesTrackedArgsHash); if (!(!!callsitesTrackedArgs && !!callsitesTrackedArgs.length)) { - pxt.log(`error: parts failed to read pin(s) from callsite for: ${fnNms}`); + pxsim.log(`error: parts failed to read pin(s) from callsite for: ${fnNms}`); return undefined; } callsitesTrackedArgs.forEach(fnArgsStr => { const fnArgsSplit = fnArgsStr.split(","); if (fnArgsSplit.length != fnAlloc.argumentRoles.length) { - pxt.log(`error: parts mismatch between number of arguments at callsite (function name: ${fnNms}) vs number of argument roles in part definition (part: ${name}).`); + pxsim.log(`error: parts mismatch between number of arguments at callsite (function name: ${fnNms}) vs number of argument roles in part definition (part: ${name}).`); return; } let instPins: PinTarget[] = []; @@ -352,7 +352,7 @@ namespace pxsim { let totalSpaceNeeded = colCounts.map(d => d.colCount).reduce((p, n) => p + n, 0); let extraSpace = totalColumnsCount - totalSpaceNeeded; if (extraSpace <= 0) { - pxt.log("Not enough breadboard space!"); + pxsim.log("Not enough breadboard space!"); //TODO } let padding = Math.floor(extraSpace / (partsCount - 1 + 2)); @@ -474,7 +474,7 @@ namespace pxsim { return this.opts.getBBCoord(loc); }); if (!firstTopAndBot[0] || !firstTopAndBot[1]) { - pxt.debug(`No more available "${location}" locations!`); + pxsim.debug(`No more available "${location}" locations!`); //TODO } let nearTop = visuals.findClosestCoordIdx(nearestCoord, firstTopAndBot) == 0; @@ -513,12 +513,12 @@ namespace pxsim { return location; } else if (location === "MOSI" || location === "MISO" || location === "SCK") { if (!this.opts.boardDef.spiPins) - pxt.debug("No SPI pin mappings found!"); + pxsim.debug("No SPI pin mappings found!"); let pin = (this.opts.boardDef.spiPins)[location as string] as string; return { type: "dalboard", pin: pin }; } else if (location === "SDA" || location === "SCL") { if (!this.opts.boardDef.i2cPins) - pxt.debug("No I2C pin mappings found!"); + pxsim.debug("No I2C pin mappings found!"); let pin = (this.opts.boardDef.i2cPins)[location as string] as string; return { type: "dalboard", pin: pin }; } else { @@ -527,7 +527,7 @@ namespace pxsim { let mbPin = location; let boardPin = this.opts.boardDef.gpioPinMap[mbPin] || mbPin; if (!boardPin) { // this pin is internal - pxt.debug(`unknown pin location for ${mbPin}`) + pxsim.debug(`unknown pin location for ${mbPin}`) return undefined; } return { type: "dalboard", pin: boardPin }; @@ -536,7 +536,7 @@ namespace pxsim { private getBoardGroundPin(): string { let pin = this.opts.boardDef.groundPins && this.opts.boardDef.groundPins[0] || null; if (!pin) { - pxt.debug("No available ground pin on board!"); + pxsim.debug("No available ground pin on board!"); //TODO } return pin; @@ -544,7 +544,7 @@ namespace pxsim { private getBoardThreeVoltPin(): string { let pin = this.opts.boardDef.threeVoltPins && this.opts.boardDef.threeVoltPins[0] || null; if (!pin) { - pxt.debug("No available 3.3V pin on board!"); + pxsim.debug("No available 3.3V pin on board!"); //TODO } return pin; @@ -552,7 +552,7 @@ namespace pxsim { private getBoardFiveVoltPin(): string { let pin = this.opts.boardDef.fiveVoltPins && this.opts.boardDef.fiveVoltPins[0] || null; if (!pin) { - pxt.debug("No available 5V pin on board!"); + pxsim.debug("No available 5V pin on board!"); //TODO } return pin; diff --git a/pxtsim/debugProtocol.ts b/pxtsim/debugProtocol.ts index 60ebd47804f0..de35ca7038c4 100644 --- a/pxtsim/debugProtocol.ts +++ b/pxtsim/debugProtocol.ts @@ -330,7 +330,7 @@ namespace pxsim.protocol { public sendResponse(response: DebugProtocol.Response): void { if (response.seq > 0) { - pxt.error(`attempt to send more than one response for command ${response.command}`); + pxsim.error(`attempt to send more than one response for command ${response.command}`); } else { this.send('response', response); } diff --git a/pxtsim/embed.ts b/pxtsim/embed.ts index 274daa644a9f..ccba38e3415e 100644 --- a/pxtsim/embed.ts +++ b/pxtsim/embed.ts @@ -523,9 +523,9 @@ namespace pxsim { const serviceWorkerUrl = window.location.href.replace(/---simulator.*$/, "---simserviceworker"); navigator.serviceWorker.register(serviceWorkerUrl).then(function (registration) { - pxt.log("Simulator ServiceWorker registration successful with scope: ", registration.scope); + pxsim.log("Simulator ServiceWorker registration successful with scope: ", registration.scope); }, function (err) { - pxt.log("Simulator ServiceWorker registration failed: ", err); + pxsim.log("Simulator ServiceWorker registration failed: ", err); }); } } diff --git a/pxtsim/langsupport.ts b/pxtsim/langsupport.ts index f87e0a3ee32d..9c826c10bafc 100644 --- a/pxtsim/langsupport.ts +++ b/pxtsim/langsupport.ts @@ -79,7 +79,7 @@ namespace pxsim { print() { if (runtime && runtime.refCountingDebug) - pxt.log(`RefObject id:${this.id}`) + pxsim.log(`RefObject id:${this.id}`) } // render a debug preview string @@ -144,7 +144,7 @@ namespace pxsim { print() { if (runtime && runtime.refCountingDebug) - pxt.log(`RefRecord id:${this.id} (${this.vtable.name})`) + pxsim.log(`RefRecord id:${this.id} (${this.vtable.name})`) } } @@ -179,7 +179,7 @@ namespace pxsim { print() { if (runtime && runtime.refCountingDebug) - pxt.log(`RefAction id:${this.id} len:${this.fields.length}`) + pxsim.log(`RefAction id:${this.id} len:${this.fields.length}`) } } @@ -269,7 +269,7 @@ namespace pxsim { r += "\n" } - pxt.log(r) + pxsim.log(r) } @@ -283,7 +283,7 @@ namespace pxsim { csv += `${p.numstops},${p.value},${p.name},${median}\n` } processPerfCounters(csv) - // pxt.log(csv) + // pxsim.log(csv) } } @@ -302,7 +302,7 @@ namespace pxsim { print() { if (runtime && runtime.refCountingDebug) - pxt.log(`RefRefLocal id:${this.id} v:${this.v}`) + pxsim.log(`RefRefLocal id:${this.id} v:${this.v}`) } } @@ -342,7 +342,7 @@ namespace pxsim { print() { if (runtime && runtime.refCountingDebug) - pxt.log(`RefMap id:${this.id} size:${this.data.length}`) + pxsim.log(`RefMap id:${this.id} size:${this.data.length}`) } toAny(): any { @@ -507,7 +507,7 @@ namespace pxsim { export function stclo(a: RefAction, idx: number, v: any) { check(0 <= idx && idx < a.fields.length) check(a.fields[idx] === null) - //pxt.log(`STCLO [${idx}] = ${v}`) + //pxsim.log(`STCLO [${idx}] = ${v}`) a.fields[idx] = v; return a; } diff --git a/pxtsim/libgeneric.ts b/pxtsim/libgeneric.ts index 512a4423a212..f9c493f8716c 100644 --- a/pxtsim/libgeneric.ts +++ b/pxtsim/libgeneric.ts @@ -93,7 +93,7 @@ namespace pxsim { } print() { - //pxt.log(`RefCollection id:${this.id} refs:${this.refcnt} len:${this.data.length} d0:${this.data[0]}`) + //pxsim.log(`RefCollection id:${this.id} refs:${this.refcnt} len:${this.data.length} d0:${this.data[0]}`) } } @@ -417,7 +417,7 @@ namespace pxsim { gcIsStatic() { return this.isStatic } print() { - // pxt.log(`RefBuffer id:${this.id} refs:${this.refcnt} len:${this.data.length} d0:${this.data[0]}`) + // pxsim.log(`RefBuffer id:${this.id} refs:${this.refcnt} len:${this.data.length} d0:${this.data[0]}`) } toDebugString(): string { diff --git a/pxtsim/logger.ts b/pxtsim/logger.ts index 70ca85abdfad..691d7403171c 100644 --- a/pxtsim/logger.ts +++ b/pxtsim/logger.ts @@ -1,45 +1,84 @@ -namespace pxt { +namespace pxsim { export interface Logger { info(...args: any[]): void; log(...args: any[]): void; debug(...args: any[]): void; error(...args: any[]): void; warn(...args: any[]): void; + + setLogLevel(level: LogLevel): void; + getLogLevel(): LogLevel; + } + + export enum LogLevel { + Debug = 0, + Info = 1, + Log = 1, + Warning = 2, + Error = 3 } - class ConsoleLogger implements Logger { + export class ConsoleLogger implements Logger { + protected logLevel: LogLevel; + + constructor() { + this.setLogLevel(LogLevel.Info); + } + + setLogLevel(level: LogLevel): void { + this.logLevel = level; + } + + getLogLevel(): LogLevel { + return this.logLevel; + } + info(...args: any[]): void { + if (!this.shouldLog(LogLevel.Info)) return; + if (console?.info) { console.info.call(null, ...args); } } log(...args: any[]): void { + if (!this.shouldLog(LogLevel.Log)) return; + if (console?.log) { console.log.call(null, ...args); } } debug(...args: any[]): void { + if (!this.shouldLog(LogLevel.Debug)) return; + if (console?.debug) { console.debug.call(null, ...args); } } error(...args: any[]): void { + if (!this.shouldLog(LogLevel.Error)) return; + if (console?.error) { console.error.call(null, ...args); } } warn(...args: any[]): void { + if (!this.shouldLog(LogLevel.Warning)) return; + if (console?.warn) { console.warn.call(null, ...args); } } + + protected shouldLog(level: LogLevel) { + return level >= this.logLevel; + } } - let logger: Logger = new ConsoleLogger(); + let logger: pxsim.Logger = new pxsim.ConsoleLogger(); export function info(...args: any[]): void { logger.info(...args); @@ -61,7 +100,15 @@ namespace pxt { logger.warn(...args); } - export function setLogger(impl: Logger) { + export function setLogger(impl: pxsim.Logger) { + const level = logger?.getLogLevel(); logger = impl; + if (level !== undefined) { + logger.setLogLevel(level); + } + } + + export function setLogLevel(level: pxsim.LogLevel) { + logger.setLogLevel(level); } } \ No newline at end of file diff --git a/pxtsim/runtime.ts b/pxtsim/runtime.ts index 5db83870b68e..791c453526ab 100644 --- a/pxtsim/runtime.ts +++ b/pxtsim/runtime.ts @@ -554,7 +554,7 @@ namespace pxsim { pause: thread.pause, showNumber: (n: number) => { let cb = getResume(); - pxt.log("SHOW NUMBER:", n) + pxsim.log("SHOW NUMBER:", n) U.nextTick(cb) } } @@ -567,9 +567,9 @@ namespace pxsim { myRT.control = { inBackground: thread.runInBackground, createBuffer: BufferMethods.createBuffer, - dmesg: (s: string) => pxt.log("DMESG: " + s), + dmesg: (s: string) => pxsim.log("DMESG: " + s), deviceDalVersion: () => "sim", - __log: (pri: number, s: string) => pxt.log("LOG: " + s.trim()), + __log: (pri: number, s: string) => pxsim.log("LOG: " + s.trim()), } } @@ -1435,7 +1435,7 @@ namespace pxsim { function loop(p: StackFrame) { if (__this.dead) { - pxt.log("Runtime terminated") + pxsim.log("Runtime terminated") return } U.assert(!__this.loopLock) @@ -1462,7 +1462,7 @@ namespace pxsim { if (__this.errorHandler) __this.errorHandler(e) else { - pxt.error("Simulator crashed, no error handler", e.stack) + pxsim.error("Simulator crashed, no error handler", e.stack) const { msg, heap } = getBreakpointMsg(p, p.lastBrkId, userGlobals) injectEnvironmentGlobals(msg, heap); msg.exceptionMessage = e.message diff --git a/pxtsim/simdriver.ts b/pxtsim/simdriver.ts index 0dd614599c9b..7d7ea1d17a9d 100644 --- a/pxtsim/simdriver.ts +++ b/pxtsim/simdriver.ts @@ -962,7 +962,7 @@ namespace pxsim { msg = 'pause'; break; default: - pxt.debug('unknown command') + pxsim.debug('unknown command') return; } @@ -1006,7 +1006,7 @@ namespace pxsim { private handleDebuggerMessage(msg: pxsim.DebuggerMessage) { if (msg.subtype !== "trace") { - pxt.log("DBG-MSG", msg.subtype, msg) + pxsim.log("DBG-MSG", msg.subtype, msg) } // resolve any request @@ -1043,9 +1043,9 @@ namespace pxsim { let fi = s.funcInfo stackTrace += ` at ${fi.functionName} (${fi.fileName}:${fi.line + 1}:${fi.column + 1})\n` } - if (brk.exceptionMessage) pxt.error(stackTrace); + if (brk.exceptionMessage) pxsim.error(stackTrace); } else { - pxt.error("debugger: trying to pause from " + this.state); + pxsim.error("debugger: trying to pause from " + this.state); } break; } diff --git a/pxtsim/simlib.ts b/pxtsim/simlib.ts index 888b4a0e461b..038b23285be8 100644 --- a/pxtsim/simlib.ts +++ b/pxtsim/simlib.ts @@ -849,7 +849,7 @@ namespace pxsim { const noteNumber = data[1] || 0; const noteFrequency = frequencyFromMidiNoteNumber(noteNumber); const velocity = data[2] || 0; - //pxt.log(`midi: cmd ${cmd} channel (-1) ${channel} note ${noteNumber} f ${noteFrequency} v ${velocity}`) + //pxsim.log(`midi: cmd ${cmd} channel (-1) ${channel} note ${noteNumber} f ${noteFrequency} v ${velocity}`) // play drums regardless if (cmd == 8 || ((cmd == 9) && (velocity == 0))) { // with MIDI, note on with velocity zero is the same as note off diff --git a/pxtsim/visuals/boardhost.ts b/pxtsim/visuals/boardhost.ts index 0547904f8bab..b1d540fb3334 100644 --- a/pxtsim/visuals/boardhost.ts +++ b/pxtsim/visuals/boardhost.ts @@ -193,7 +193,7 @@ namespace pxsim.visuals { resolve(ctx.getImageData(0, 0, cvs.width, cvs.height)); }; img.onerror = e => { - pxt.log(e); + pxsim.log(e); resolve(undefined); } img.src = data; @@ -211,7 +211,7 @@ namespace pxsim.visuals { private getPinCoord(pin: string) { let boardCoord = this.boardView.getCoord(pin); if (!boardCoord) { - pxt.error(`Unable to find coord for pin: ${pin}`); + pxsim.error(`Unable to find coord for pin: ${pin}`); return undefined; } return this.fromMBCoord(boardCoord); @@ -226,7 +226,7 @@ namespace pxsim.visuals { coord = this.getPinCoord(pinNm); } if (!coord) - pxt.debug("Unknown location: " + name) + pxsim.debug("Unknown location: " + name) return coord; } public getPinStyle(loc: Loc): PinStyle { diff --git a/pxtsim/visuals/wiring.ts b/pxtsim/visuals/wiring.ts index 6187431651dc..8ee693fe29cd 100644 --- a/pxtsim/visuals/wiring.ts +++ b/pxtsim/visuals/wiring.ts @@ -467,7 +467,7 @@ namespace pxsim.visuals { let startLoc = this.getLocCoord(start); let endLoc = this.getLocCoord(end); if (!startLoc || !endLoc) { - pxt.debug(`unable to allocate wire for ${start} or ${end}`); + pxsim.debug(`unable to allocate wire for ${start} or ${end}`); return undefined; } //let startStyle = this.getPinStyle(start); diff --git a/teachertool/src/index.tsx b/teachertool/src/index.tsx index 6b9db3bc64ca..dac0629658f6 100644 --- a/teachertool/src/index.tsx +++ b/teachertool/src/index.tsx @@ -39,7 +39,9 @@ window.addEventListener("DOMContentLoaded", () => { const optsQuery = pxt.Util.parseQueryString(window.location.href.toLowerCase()); pxt.options.debug = optsQuery["dbg"] == "1"; - if (pxt.options.debug) pxt.debug = console.debug; + if (pxt.options.debug) { + pxt.setLogLevel(pxt.LogLevel.Debug); + } if (optsQuery["consoleticks"] == "1" || optsQuery["consoleticks"] == "verbose") { pxt.analytics.consoleTicks = pxt.analytics.ConsoleTickOptions.Verbose; diff --git a/tutorialtool/src/index.tsx b/tutorialtool/src/index.tsx index 53bffdb9fc87..48da1bdd1d65 100644 --- a/tutorialtool/src/index.tsx +++ b/tutorialtool/src/index.tsx @@ -36,7 +36,9 @@ window.addEventListener("DOMContentLoaded", () => { const bundle = (window as any).pxtTargetBundle as pxt.TargetBundle; pxt.options.debug = /dbg=1/i.test(window.location.href); - if (pxt.options.debug) pxt.debug = console.debug; + if (pxt.options.debug) { + pxt.setLogLevel(pxt.LogLevel.Debug); + } pxt.setupWebConfig((window as any).pxtConfig || pxt.webConfig); pxt.setAppTarget(bundle); diff --git a/webapp/src/app.tsx b/webapp/src/app.tsx index fbd47b242eb6..4b89c3d099b8 100644 --- a/webapp/src/app.tsx +++ b/webapp/src/app.tsx @@ -5858,7 +5858,8 @@ function initExtensionsAsync(): Promise { const opts: pxt.editor.ExtensionOptions = { blocklyToolbox: blocklyToolbox.getToolboxDefinition(), monacoToolbox: monacoToolbox.getToolboxDefinition(), - projectView: theEditor + projectView: theEditor, + showNotification: (msg) => core.infoNotification(msg) }; return pxt.BrowserUtils.loadScriptAsync("editor.js") .then(() => pxt.editor.initExtensionsAsync(opts)) @@ -5935,8 +5936,9 @@ document.addEventListener("DOMContentLoaded", async () => { const config = pxt.webConfig const optsQuery = Util.parseQueryString(window.location.href.toLowerCase()); - if (optsQuery["dbg"] == "1") - pxt.debug = pxt.debug; + if (optsQuery["dbg"] == "1") { + pxt.setLogLevel(pxt.LogLevel.Debug); + } pxt.options.light = optsQuery["light"] == "1" || pxt.BrowserUtils.isARM() || pxt.BrowserUtils.isIE(); if (pxt.options.light) { pxsim.U.addClass(document.body, 'light'); diff --git a/webapp/src/cmds.ts b/webapp/src/cmds.ts index 08936037bf4a..273c714b031b 100644 --- a/webapp/src/cmds.ts +++ b/webapp/src/cmds.ts @@ -12,6 +12,7 @@ import * as pxtblockly from "../../pxtblocks"; import ExtensionResult = pxt.editor.ExtensionResult; import NativeHostMessage = pxt.editor.NativeHostMessage; +import { setEditorExtensionExperiments } from "../../pxteditor/experiments"; function log(msg: string) { @@ -397,6 +398,9 @@ function applyExtensionResult() { log(`extension onMarkdownActivityLoad`); pxt.commands.onMarkdownActivityLoad = res.onMarkdownActivityLoad; } + if (res.experiments) { + setEditorExtensionExperiments(res.experiments); + } } export async function initAsync() { diff --git a/webapp/src/scriptsearch.tsx b/webapp/src/scriptsearch.tsx index 13d6c5c1e401..9fa9330ba652 100644 --- a/webapp/src/scriptsearch.tsx +++ b/webapp/src/scriptsearch.tsx @@ -204,7 +204,7 @@ export class ScriptSearch extends data.Component