mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-07 01:18:33 +00:00
Compare commits
1 Commits
remove-don
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a55a5c560 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -340,7 +340,7 @@ jobs:
|
||||
|
||||
- name: Install Python 3.x
|
||||
if: fromJSON(matrix.config.container) == null && runner.name != 'WINDOWS-SIGN-PC'
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11.x'
|
||||
|
||||
|
||||
2
.github/workflows/test-javascript.yml
vendored
2
.github/workflows/test-javascript.yml
vendored
@@ -92,7 +92,7 @@ jobs:
|
||||
|
||||
# See: https://github.com/eclipse-theia/theia/blob/master/doc/Developing.md#prerequisites
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11.x'
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ See [**the contributor guide**](docs/CONTRIBUTING.md#contributor-guide) for more
|
||||
|
||||
See the [**development guide**](docs/development.md) for a technical overview of the application and instructions for building the code.
|
||||
|
||||
### Support the project
|
||||
## Donations
|
||||
|
||||
This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [buying original Arduino boards](https://store.arduino.cc/) to support our work on the project.
|
||||
This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [donating](https://www.arduino.cc/en/donate/) or [sponsoring](https://github.com/sponsors/arduino) to support our work, as well as [buying original Arduino boards](https://store.arduino.cc/) which is the best way to make sure our effort can continue in the long term.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
"cross-fetch": "^3.1.5",
|
||||
"dateformat": "^3.0.3",
|
||||
"deepmerge": "^4.2.2",
|
||||
"dompurify": "^2.4.7",
|
||||
"drivelist": "^9.2.4",
|
||||
"electron-updater": "^4.6.5",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
|
||||
@@ -368,6 +368,10 @@ import { DebugConfigurationWidget } from './theia/debug/debug-configuration-widg
|
||||
import { DebugConfigurationWidget as TheiaDebugConfigurationWidget } from '@theia/debug/lib/browser/view/debug-configuration-widget';
|
||||
import { DebugToolBar } from '@theia/debug/lib/browser/view/debug-toolbar-widget';
|
||||
|
||||
import {
|
||||
VersionWelcomeDialog,
|
||||
VersionWelcomeDialogProps,
|
||||
} from './dialogs/version-welcome-dialog';
|
||||
import { TestViewContribution as TheiaTestViewContribution } from '@theia/test/lib/browser/view/test-view-contribution';
|
||||
import { TestViewContribution } from './theia/test/test-view-contribution';
|
||||
|
||||
@@ -983,6 +987,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
title: 'IDEUpdater',
|
||||
});
|
||||
|
||||
bind(VersionWelcomeDialog).toSelf().inSingletonScope();
|
||||
bind(VersionWelcomeDialogProps).toConstantValue({
|
||||
title: 'VersionWelcomeDialog',
|
||||
});
|
||||
|
||||
bind(UserFieldsDialog).toSelf().inSingletonScope();
|
||||
bind(UserFieldsDialogProps).toConstantValue({
|
||||
title: 'UserFields',
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '../../common/protocol/ide-updater';
|
||||
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
||||
import { Contribution } from './contribution';
|
||||
import { VersionWelcomeDialog } from '../dialogs/version-welcome-dialog';
|
||||
import { AppService } from '../app-service';
|
||||
import { SemVer } from 'semver';
|
||||
|
||||
@@ -19,6 +20,9 @@ export class CheckForIDEUpdates extends Contribution {
|
||||
@inject(IDEUpdaterDialog)
|
||||
private readonly updaterDialog: IDEUpdaterDialog;
|
||||
|
||||
@inject(VersionWelcomeDialog)
|
||||
private readonly versionWelcomeDialog: VersionWelcomeDialog;
|
||||
|
||||
@inject(LocalStorageService)
|
||||
private readonly localStorage: LocalStorageService;
|
||||
|
||||
@@ -55,8 +59,13 @@ export class CheckForIDEUpdates extends Contribution {
|
||||
return this.updater.checkForUpdates(true);
|
||||
})
|
||||
.then(async (updateInfo) => {
|
||||
if (!updateInfo) return;
|
||||
|
||||
if (!updateInfo) {
|
||||
const isNewVersion = await this.isNewStableVersion();
|
||||
if (isNewVersion) {
|
||||
this.versionWelcomeDialog.open();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const versionToSkip = await this.localStorage.getData<string>(
|
||||
SKIP_IDE_VERSION
|
||||
);
|
||||
@@ -77,11 +86,6 @@ export class CheckForIDEUpdates extends Contribution {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This value is set in localStorage but currently not used.
|
||||
* We keep this logic running anyway for eventual future needs
|
||||
* (eg. show a new version welcome dialog)
|
||||
*/
|
||||
private async setCurrentIDEVersion(): Promise<void> {
|
||||
try {
|
||||
const { appVersion } = await this.appService.info();
|
||||
@@ -91,4 +95,29 @@ export class CheckForIDEUpdates extends Contribution {
|
||||
// ignore invalid versions
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is running a new IDE version for the first time.
|
||||
* @returns true if the current IDE version is greater than the last used version
|
||||
* and both are non-prerelease versions.
|
||||
*/
|
||||
private async isNewStableVersion(): Promise<boolean> {
|
||||
try {
|
||||
const { appVersion } = await this.appService.info();
|
||||
const prevVersion = await this.localStorage.getData<string>(
|
||||
LAST_USED_IDE_VERSION
|
||||
);
|
||||
|
||||
const prevSemVer = new SemVer(prevVersion ?? '');
|
||||
const currSemVer = new SemVer(appVersion ?? '');
|
||||
|
||||
if (prevSemVer.prerelease.length || currSemVer.prerelease.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return currSemVer.compare(prevSemVer) === 1;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from '../../../common/protocol/ide-updater';
|
||||
import { LocalStorageService } from '@theia/core/lib/browser';
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
import { sanitize } from 'dompurify';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialogProps extends DialogProps {}
|
||||
@@ -165,6 +166,51 @@ export class IDEUpdaterDialog extends ReactDialog<UpdateInfo | undefined> {
|
||||
goToDownloadPageButton.focus();
|
||||
}
|
||||
|
||||
private appendDonateFooter() {
|
||||
const footer = document.createElement('div');
|
||||
footer.classList.add('ide-updater-dialog--footer');
|
||||
const footerContent = document.createElement('div');
|
||||
footerContent.classList.add('ide-updater-dialog--footer-content');
|
||||
footer.appendChild(footerContent);
|
||||
|
||||
const footerLink = document.createElement('a');
|
||||
footerLink.innerText = sanitize(
|
||||
nls.localize('arduino/ide-updater/donateLinkText', 'donate to support us')
|
||||
);
|
||||
footerLink.classList.add('ide-updater-dialog--footer-link');
|
||||
footerLink.onclick = () =>
|
||||
this.openExternal('https://www.arduino.cc/en/donate');
|
||||
|
||||
const footerLinkIcon = document.createElement('span');
|
||||
footerLinkIcon.title = nls.localize(
|
||||
'arduino/ide-updater/donateLinkIconTitle',
|
||||
'open donation page'
|
||||
);
|
||||
footerLinkIcon.classList.add('ide-updater-dialog--footer-link-icon');
|
||||
footerLink.appendChild(footerLinkIcon);
|
||||
|
||||
const placeholderKey = '%%link%%';
|
||||
const footerText = sanitize(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/donateText',
|
||||
'Open source is love, {0}',
|
||||
placeholderKey
|
||||
)
|
||||
);
|
||||
const placeholder = footerText.indexOf(placeholderKey);
|
||||
if (placeholder !== -1) {
|
||||
const parts = footerText.split(placeholderKey);
|
||||
footerContent.appendChild(document.createTextNode(parts[0]));
|
||||
footerContent.appendChild(footerLink);
|
||||
footerContent.appendChild(document.createTextNode(parts[1]));
|
||||
} else {
|
||||
footerContent.appendChild(document.createTextNode(footerText));
|
||||
footerContent.appendChild(footerLink);
|
||||
}
|
||||
|
||||
this.controlPanel.insertAdjacentElement('afterend', footer);
|
||||
}
|
||||
|
||||
private openDownloadPage(): void {
|
||||
this.openExternal('https://www.arduino.cc/en/software');
|
||||
this.close();
|
||||
@@ -187,6 +233,7 @@ export class IDEUpdaterDialog extends ReactDialog<UpdateInfo | undefined> {
|
||||
downloadStarted: true,
|
||||
});
|
||||
this.clearButtons();
|
||||
this.appendDonateFooter();
|
||||
this.updater.downloadUpdate();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
import React from '@theia/core/shared/react';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { ReactDialog } from '../theia/dialogs/dialogs';
|
||||
import { nls } from '@theia/core';
|
||||
import { DialogProps } from '@theia/core/lib/browser';
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
import { AppService } from '../app-service';
|
||||
import { sanitize } from 'dompurify';
|
||||
|
||||
@injectable()
|
||||
export class VersionWelcomeDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class VersionWelcomeDialog extends ReactDialog<void> {
|
||||
@inject(AppService)
|
||||
private readonly appService: AppService;
|
||||
|
||||
@inject(WindowService)
|
||||
private readonly windowService: WindowService;
|
||||
|
||||
constructor(
|
||||
@inject(VersionWelcomeDialogProps)
|
||||
protected override readonly props: VersionWelcomeDialogProps
|
||||
) {
|
||||
super({
|
||||
title: nls.localize(
|
||||
'arduino/versionWelcome/title',
|
||||
'Welcome to a new version of the Arduino IDE!'
|
||||
),
|
||||
});
|
||||
this.node.id = 'version-welcome-dialog-container';
|
||||
this.contentNode.classList.add('version-welcome-dialog');
|
||||
}
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
{nls.localize(
|
||||
'arduino/versionWelcome/donateMessage',
|
||||
'Arduino is committed to keeping software free and open-source for everyone. Your donation helps us develop new features, improve libraries, and support millions of users worldwide.'
|
||||
)}
|
||||
</p>
|
||||
<p className="bold">
|
||||
{nls.localize(
|
||||
'arduino/versionWelcome/donateMessage2',
|
||||
'Please consider supporting our work on the free open source Arduino IDE.'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
override get value(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
private appendButtons(): void {
|
||||
const cancelButton = this.createButton(
|
||||
nls.localize('arduino/versionWelcome/cancelButton', 'Maybe later')
|
||||
);
|
||||
cancelButton.classList.add('secondary');
|
||||
cancelButton.classList.add('cancel-button');
|
||||
this.addAction(cancelButton, this.close.bind(this), 'click');
|
||||
this.controlPanel.appendChild(cancelButton);
|
||||
|
||||
const donateButton = this.createButton(
|
||||
nls.localize('arduino/versionWelcome/donateButton', 'Donate now')
|
||||
);
|
||||
this.addAction(donateButton, this.onDonateButtonClick.bind(this), 'click');
|
||||
this.controlPanel.appendChild(donateButton);
|
||||
donateButton.focus();
|
||||
}
|
||||
|
||||
private onDonateButtonClick(): void {
|
||||
this.openDonationPage();
|
||||
this.close();
|
||||
}
|
||||
|
||||
private readonly openDonationPage = () => {
|
||||
const url = 'https://www.arduino.cc/en/donate';
|
||||
this.windowService.openNewWindow(url, { external: true });
|
||||
};
|
||||
|
||||
private async updateTitleVersion(): Promise<void> {
|
||||
const appInfo = await this.appService.info();
|
||||
const { appVersion } = appInfo;
|
||||
|
||||
if (appVersion) {
|
||||
this.titleNode.innerText = sanitize(
|
||||
nls.localize(
|
||||
'arduino/versionWelcome/titleWithVersion',
|
||||
'Welcome to the new Arduino IDE {0}!',
|
||||
appVersion
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected override onAfterAttach(msg: Message): void {
|
||||
this.update();
|
||||
this.appendButtons();
|
||||
this.updateTitleVersion();
|
||||
super.onAfterAttach(msg);
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,3 @@ export function truncateLines(
|
||||
}
|
||||
return [lines, charCount];
|
||||
}
|
||||
|
||||
export function joinLines(lines: Line[]): string {
|
||||
return lines.map((line: Line) => line.message).join('');
|
||||
}
|
||||
@@ -52,9 +52,6 @@ export namespace SerialMonitor {
|
||||
},
|
||||
'vscode/output.contribution/clearOutput.label'
|
||||
);
|
||||
export const COPY_OUTPUT = {
|
||||
id: 'serial-monitor-copy-output',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,12 +149,6 @@ export class MonitorViewContribution
|
||||
'Clear Output'
|
||||
),
|
||||
});
|
||||
registry.registerItem({
|
||||
id: SerialMonitor.Commands.COPY_OUTPUT.id,
|
||||
command: SerialMonitor.Commands.COPY_OUTPUT.id,
|
||||
icon: codicon('copy'),
|
||||
tooltip: nls.localize('arduino/serial/copyOutput', 'Copy Output'),
|
||||
});
|
||||
}
|
||||
|
||||
override registerCommands(commands: CommandRegistry): void {
|
||||
@@ -170,15 +161,6 @@ export class MonitorViewContribution
|
||||
}
|
||||
},
|
||||
});
|
||||
commands.registerCommand(SerialMonitor.Commands.COPY_OUTPUT, {
|
||||
isEnabled: (widget) => widget instanceof MonitorWidget,
|
||||
isVisible: (widget) => widget instanceof MonitorWidget,
|
||||
execute: (widget) => {
|
||||
if (widget instanceof MonitorWidget) {
|
||||
widget.copyOutput();
|
||||
}
|
||||
},
|
||||
});
|
||||
if (this.toggleCommand) {
|
||||
commands.registerCommand(this.toggleCommand, {
|
||||
execute: () => this.toggle(),
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
import { MonitorModel } from '../../monitor-model';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import { serialMonitorWidgetLabel } from '../../../common/nls';
|
||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
||||
|
||||
@injectable()
|
||||
export class MonitorWidget extends ReactWidget {
|
||||
@@ -48,7 +47,6 @@ export class MonitorWidget extends ReactWidget {
|
||||
*/
|
||||
protected closing = false;
|
||||
protected readonly clearOutputEmitter = new Emitter<void>();
|
||||
protected readonly copyOutputEmitter = new Emitter<void>();
|
||||
|
||||
@inject(MonitorModel)
|
||||
private readonly monitorModel: MonitorModel;
|
||||
@@ -58,8 +56,6 @@ export class MonitorWidget extends ReactWidget {
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
@inject(FrontendApplicationStateService)
|
||||
private readonly appStateService: FrontendApplicationStateService;
|
||||
@inject(ClipboardService)
|
||||
private readonly clipboardService: ClipboardService;
|
||||
|
||||
private readonly toDisposeOnReset: DisposableCollection;
|
||||
|
||||
@@ -106,10 +102,6 @@ export class MonitorWidget extends ReactWidget {
|
||||
this.clearOutputEmitter.fire(undefined);
|
||||
this.update();
|
||||
}
|
||||
|
||||
copyOutput(): void {
|
||||
this.copyOutputEmitter.fire();
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
this.toDisposeOnReset.dispose();
|
||||
@@ -255,8 +247,6 @@ export class MonitorWidget extends ReactWidget {
|
||||
monitorModel={this.monitorModel}
|
||||
monitorManagerProxy={this.monitorManagerProxy}
|
||||
clearConsoleEvent={this.clearOutputEmitter.event}
|
||||
copyOutputEvent={this.copyOutputEmitter.event}
|
||||
clipboardService={this.clipboardService}
|
||||
height={Math.floor(this.widgetHeight - 50)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -3,10 +3,9 @@ import { Event } from '@theia/core/lib/common/event';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { areEqual, FixedSizeList as List } from 'react-window';
|
||||
import dateFormat from 'dateformat';
|
||||
import { messagesToLines, truncateLines, joinLines } from './monitor-utils';
|
||||
import { messagesToLines, truncateLines } from './monitor-utils';
|
||||
import { MonitorManagerProxyClient } from '../../../common/protocol';
|
||||
import { MonitorModel } from '../../monitor-model';
|
||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
||||
|
||||
export type Line = { message: string; timestamp?: Date; lineLen: number };
|
||||
|
||||
@@ -75,9 +74,6 @@ export class SerialMonitorOutput extends React.Component<
|
||||
this.props.clearConsoleEvent(() =>
|
||||
this.setState({ lines: [], charCount: 0 })
|
||||
),
|
||||
this.props.copyOutputEvent(() =>
|
||||
this.props.clipboardService.writeText(joinLines(this.state.lines))
|
||||
),
|
||||
this.props.monitorModel.onChange(({ property }) => {
|
||||
if (property === 'timestamp') {
|
||||
const { timestamp } = this.props.monitorModel;
|
||||
@@ -134,8 +130,6 @@ export namespace SerialMonitorOutput {
|
||||
readonly monitorModel: MonitorModel;
|
||||
readonly monitorManagerProxy: MonitorManagerProxyClient;
|
||||
readonly clearConsoleEvent: Event<void>;
|
||||
readonly copyOutputEvent: Event<void>;
|
||||
readonly clipboardService: ClipboardService;
|
||||
readonly height: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,37 @@
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--footer {
|
||||
display: inline-block;
|
||||
margin-top: -16px;
|
||||
padding: 12px 0 24px 0;
|
||||
border-top: 1px solid var(--theia-editorWidget-border);
|
||||
}
|
||||
.ide-updater-dialog--footer-content {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--footer-link {
|
||||
display: inline-block;
|
||||
color: var(--theia-textLink-foreground);
|
||||
font-weight: 500;
|
||||
line-height: 13px;
|
||||
}
|
||||
.ide-updater-dialog--footer-link:hover {
|
||||
color: var(--theia-textLink-foreground);
|
||||
cursor: pointer;
|
||||
}
|
||||
.ide-updater-dialog--footer-link-icon {
|
||||
display: inline-block;
|
||||
-webkit-mask: url(../icons/link-open-icon.svg) center no-repeat;
|
||||
background-color: var(--theia-textLink-foreground);
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
cursor: pointer;
|
||||
transform: translateY(2px);
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog {
|
||||
color: var(--theia-editor-foreground);
|
||||
background-color: var(--theia-editor-background);
|
||||
@@ -109,6 +140,7 @@
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
|
||||
#ide-updater-dialog-container .skip-version-button {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
@import "./settings-dialog.css";
|
||||
@import "./firmware-uploader-dialog.css";
|
||||
@import "./ide-updater-dialog.css";
|
||||
@import "./version-welcome-dialog.css";
|
||||
@import "./certificate-uploader-dialog.css";
|
||||
@import "./user-fields-dialog.css";
|
||||
@import "./debug.css";
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#version-welcome-dialog-container > .dialogBlock {
|
||||
width: 546px;
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ import { expect } from 'chai';
|
||||
import {
|
||||
messagesToLines,
|
||||
truncateLines,
|
||||
joinLines,
|
||||
} from '../../browser/serial/monitor/monitor-utils';
|
||||
import { Line } from '../../browser/serial/monitor/serial-monitor-send-output';
|
||||
import { set, reset } from 'mockdate';
|
||||
@@ -16,7 +15,6 @@ type TestLine = {
|
||||
charCount: number;
|
||||
maxCharacters?: number;
|
||||
};
|
||||
expectedJoined?: string;
|
||||
};
|
||||
|
||||
const date = new Date();
|
||||
@@ -24,7 +22,6 @@ const testLines: TestLine[] = [
|
||||
{
|
||||
messages: ['Hello'],
|
||||
expected: { lines: [{ message: 'Hello', lineLen: 5 }], charCount: 5 },
|
||||
expectedJoined: 'Hello',
|
||||
},
|
||||
{
|
||||
messages: ['Hello', 'Dog!'],
|
||||
@@ -39,7 +36,6 @@ const testLines: TestLine[] = [
|
||||
],
|
||||
charCount: 10,
|
||||
},
|
||||
expectedJoined: 'Hello\nDog!'
|
||||
},
|
||||
{
|
||||
messages: ['Dog!'],
|
||||
@@ -71,7 +67,6 @@ const testLines: TestLine[] = [
|
||||
{ message: "You're a good boy!", lineLen: 8 },
|
||||
],
|
||||
},
|
||||
expectedJoined: "Hello Dog!\n Who's a good boy?\nYou're a good boy!",
|
||||
},
|
||||
{
|
||||
messages: ['boy?\n', "You're a good boy!"],
|
||||
@@ -121,7 +116,6 @@ const testLines: TestLine[] = [
|
||||
{ message: 'Yo', lineLen: 2 },
|
||||
],
|
||||
},
|
||||
expectedJoined: "Hello Dog!\nWho's a good boy?\nYo",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -171,10 +165,6 @@ describe('Monitor Utils', () => {
|
||||
});
|
||||
expect(totalCharCount).to.equal(charCount);
|
||||
}
|
||||
if (testLine.expectedJoined) {
|
||||
const joined_str = joinLines(testLine.expected.lines);
|
||||
expect(joined_str).to.equal(testLine.expectedJoined);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,20 +6,22 @@ Thanks for your interest in contributing to this project!
|
||||
|
||||
There are several ways you can get involved:
|
||||
|
||||
| Type of contribution | Contribution method |
|
||||
| ----------------------------------------- | ---------------------------------------------------------------- |
|
||||
| - Support<br/>- Question<br/>- Discussion | Post on the [**Arduino Forum**][forum] |
|
||||
| - Bug report<br/>- Feature request | Issue report (see the guide [**here**][issues]) |
|
||||
| Testing | Beta testing, PR review (see the guide [**here**][beta-testing]) |
|
||||
| Translation | See the guide [**here**][translate] |
|
||||
| - Bug fix<br/>- Enhancement | Pull request (see the guide [**here**][prs]) |
|
||||
| Monetary | [Buy official products][store] |
|
||||
| Type of contribution | Contribution method |
|
||||
| ----------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| - Support<br/>- Question<br/>- Discussion | Post on the [**Arduino Forum**][forum] |
|
||||
| - Bug report<br/>- Feature request | Issue report (see the guide [**here**][issues]) |
|
||||
| Testing | Beta testing, PR review (see the guide [**here**][beta-testing]) |
|
||||
| Translation | See the guide [**here**][translate] |
|
||||
| - Bug fix<br/>- Enhancement | Pull request (see the guide [**here**][prs]) |
|
||||
| Monetary | - [Donate][donate]<br/>- [Sponsor][sponsor]<br/>- [Buy official products][store] |
|
||||
|
||||
[forum]: https://forum.arduino.cc
|
||||
[issues]: contributor-guide/issues.md#issue-report-guide
|
||||
[beta-testing]: contributor-guide/beta-testing.md#beta-testing-guide
|
||||
[translate]: contributor-guide/translation.md#translator-guide
|
||||
[prs]: contributor-guide/pull-requests.md#pull-request-guide
|
||||
[donate]: https://www.arduino.cc/en/donate/
|
||||
[sponsor]: https://github.com/sponsors/arduino
|
||||
[store]: https://store.arduino.cc
|
||||
|
||||
## Resources
|
||||
|
||||
12
i18n/en.json
12
i18n/en.json
@@ -275,6 +275,9 @@
|
||||
"checkForUpdates": "Check for Arduino IDE Updates",
|
||||
"closeAndInstallButton": "Close and Install",
|
||||
"closeToInstallNotice": "Close the software and install the update on your machine.",
|
||||
"donateLinkIconTitle": "open donation page",
|
||||
"donateLinkText": "donate to support us",
|
||||
"donateText": "Open source is love, {0}",
|
||||
"downloadButton": "Download",
|
||||
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
|
||||
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
|
||||
@@ -432,7 +435,6 @@
|
||||
"autoscroll": "Autoscroll",
|
||||
"carriageReturn": "Carriage Return",
|
||||
"connecting": "Connecting to '{0}' on '{1}'...",
|
||||
"copyOutput": "Copy Output",
|
||||
"message": "Message (Enter to send message to '{0}' on '{1}')",
|
||||
"newLine": "New Line",
|
||||
"newLineCarriageReturn": "Both NL & CR",
|
||||
@@ -520,6 +522,14 @@
|
||||
"renameSketchFolderMessage": "The sketch '{0}' cannot be used. {1} To get rid of this message, rename the sketch. Do you want to rename the sketch now?",
|
||||
"renameSketchFolderTitle": "Invalid sketch name"
|
||||
},
|
||||
"versionWelcome": {
|
||||
"cancelButton": "Maybe later",
|
||||
"donateButton": "Donate now",
|
||||
"donateMessage": "Arduino is committed to keeping software free and open-source for everyone. Your donation helps us develop new features, improve libraries, and support millions of users worldwide.",
|
||||
"donateMessage2": "Please consider supporting our work on the free open source Arduino IDE.",
|
||||
"title": "Welcome to a new version of the Arduino IDE!",
|
||||
"titleWithVersion": "Welcome to the new Arduino IDE {0}!"
|
||||
},
|
||||
"workspace": {
|
||||
"alreadyExists": "'{0}' already exists."
|
||||
}
|
||||
|
||||
@@ -5912,7 +5912,7 @@ domexception@^4.0.0:
|
||||
dependencies:
|
||||
webidl-conversions "^7.0.0"
|
||||
|
||||
dompurify@^2.2.9:
|
||||
dompurify@^2.2.9, dompurify@^2.4.7:
|
||||
version "2.5.8"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.5.8.tgz#2809d89d7e528dc7a071dea440d7376df676f824"
|
||||
integrity sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==
|
||||
|
||||
Reference in New Issue
Block a user