Handle CustomTextEditor after opening - visual-studio-code

I want to open a file with my custom text editor and after opening, the editor should scroll to a position given by an element id.
I use the vscode command
vscode.commands.executeCommand('vscode.openWith', fileURI, EditorProvider.viewType); to open the file, but the command does not return the opened editor like showTextDocument.
Is there a way to open the file like the following example but with my custom editor?
vscode.workspace
.openTextDocument(path)
.then((textDocument) => {
vscode.window.showTextDocument(textDocument, 2, false)
.then((editor) => {
//scroll to element
});
Or alternatively: Is there a possibility to pass on the element id and to handle the parameter after opening the file?
Like this:
vscode.commands.executeCommand('vscode.openWith', fileURI, EditorProvider.viewType, scrollToElement);

Related

TinyMCE - open code view inside editor - range error

like I mentions in the topic I want to open code view inside my editor, not on separate modal window. I found similar topic and use some of the code from it:
TinyMCE Code Plugin - don't want to open code view in a modal dialog
I managed to do something like this:
const tinyDomUtils = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
const editorBody = editor.getBody();
const toggleCodeView = (isCodeView: string) => {
editorContent = editor.getContent({ source_view: !0 });
editorBody.setAttribute(codeViewAttribute, isCodeView);
if (editorBody.getAttribute(codeViewAttribute) === 'true') {
editor.setContent(tinyDomUtils.DOM.encode(editorContent));
editorBody.blur();
} else {
editor.setContent(tinyDomUtils.DOM.decode(editorContent));
}
};
And it works pretty good, I am able to switch between modes. The problem I have is that currently when I am on the code view, the user can hit "save" and then the content is display with all the html markup. I am trying to fix it just by some event listener to "Save" button and when user click it I am running my function again
toggleCodeView("false");
but then I get console error:
react-dom.development.js:22738 Uncaught TypeError: Cannot read properties of undefined (reading 'createRange')
at c.getRng (tinymce.min.js?5.0.0:6:15446)
at c.getNode (tinymce.min.js?5.0.0:6:16732)
at a.getBookmark (tinymce.min.js?5.0.0:6:8198)
at c.getBookmark (tinymce.min.js?5.0.0:6:13908)
at Object.add (tinymce.min.js?5.0.0:7:12595)
at A.i (tinymce.min.js?5.0.0:7:10860)
at t.i [as fire] (tinymce.min.js?5.0.0:8:4752)
at A.fire (tinymce.min.js?5.0.0:8:6637)
at A.save (tinymce.min.js?5.0.0:11:11915)
at A.remove (tinymce.min.js?5.0.0:11:15152)
I can't find any solution for this. Can anyone help?

Open text document in custom editor from vscode extension

I'm developing a Visual Studio Code extension that opens a webview custom editor.
Part of this is a command that prompts the user for a filename, creates the file, and then opens it.
It looks something like this:
window
.showInputBox({
prompt: "Enter name for file",
})
.then((title) => {
if (!title) {
return;
}
const fileContent = generateDefaultFileContent();
const filePath = path.join(folder.uri.path, `${title}.custom_file_format`);
workspace.fs
.writeFile(
folder.uri.with({
path: filePath,
}),
Buffer.from(fileContent, "utf8")
)
.then(() => {
workspace.openTextDocument(filePath).then((doc) =>
window.showTextDocument(doc, {
viewColumn: ViewColumn.Active,
})
);
});
});
The file gets properly created, however the call to window.showTextDocument opens the editor in the text editor and not my registered custom editor (in the example above, the custom editor will open .custom_file_format files). If you click on the newly created file in the file explorer, it will open in the custom editor.
Is there a way to get it to open the new file in the custom editor?
Turns out this can be done with...
commands.executeCommand(
"vscode.openWith",
folder.uri.with({
path: filePath,
}),
MyCustomEditor.viewType
);

Make Upload tab the default in Insert/Edit Image dialog

Using TinyMCE 5.7.0
Is there a way to make the "Upload" tab the default tab displayed in the Insert/Edit Image dialog?
I'm looking for a configuration option or programmatic way to do this so we can continue to easily update TinyMCE when new versions come out.
In TinyMCE (5.7.0 in my case, not the minified version), open plugins/image/plugin.js.
Search for these lines (1462 to 1466):
tabs: flatten([
[MainTab.makeTab(info)],
info.hasAdvTab ? [AdvTab.makeTab(info)] : [],
info.hasUploadTab && (info.hasUploadUrl || info.hasUploadHandler) ? [UploadTab.makeTab(info)] : []
])
Reorder the lines like this:
tabs: flatten([
info.hasUploadTab && (info.hasUploadUrl || info.hasUploadHandler) ? [UploadTab.makeTab(info)] : [],
[MainTab.makeTab(info)],
info.hasAdvTab ? [AdvTab.makeTab(info)] : []
])
We had the same requirement and this is how we did it.
Instead of adding the "Upload Image" option to toolbar, create a keyboard shortcut for opening the image upload modal using addShortcut method. Something like this in reactjs:
editor.addShortcut('ctrl+shift+i', 'Open image upload window', function () {
editor.execCommand('mceImage')
});
Now that we have a code block that runs when pressing the shortcut keys, we can add logic inside that block to initiate a click action on the "Upload" button within the modal like this:
setTimeout(() => {
let element = document.querySelectorAll('.tox-dialog__body-nav-item')[1];
if (element) { element.click() }
}, 0)
The setTimeout is added to make sure that the modal is added to DOM before run the querySelectorAll method on the document object is executed. Timeout even with 0 will make sure the code block only executes after all the synchronous tasks are done, which includes the DOM update.
In the end, the final codeblock will look like this:
editor.addShortcut('ctrl+shift+i', 'Open image upload window', function () {
editor.execCommand('mceImage')
setTimeout(() => {
let element = document.querySelectorAll('.tox-dialog__body-nav-item')[1];
if (element) { element.click() }
}, 0)
});
Edit:
If you notice other elements in the DOM with the same class as "tox-dialog__body-nav-item", you can change the querySelectorAll method to make it more well defined and make sure it only selects the class within image upload modal if found. I haven't yet ran into this issue, so this was enough for my case.

How to create a custom dialog in VSCode?

I'm developing an extension for VSCode, and I want to display a custom dialog to help the user configure an ini file.
Is it possible to create a custom dialog with labels and inputs?
You cannot create new UI elements, but if you want to get inputs from the user you can use code like below:
let options: InputBoxOptions = {
prompt: "Label: ",
placeHolder: "(placeholder)"
}
window.showInputBox(options).then(value => {
if (!value) return;
answer1 = value;
// show the next dialog, etc.
});
This will use the same UI as the command palette (when you press Ctrl+P, or any of the other commands that open the input box at the top).

Change content before preview in TinyMCE 4

In TinyMCE 4, I want to change displayed contents before they are showed on preview popup windows. This change must not affect current contents in editor. Can we do that?
If it can't, I want to catch close event of preview windows. How to do that?
TinyMCE allows us to register callbacks via the property init_instance_callback
By using the BeforeExecCommand event, oddly not in current documentation, you can make changes prior to a command being executed. We can similarly use the ExecCommand event to make changes after the command is executed. The Preview Plugin triggers the mcePreview command. You can view the Editor command Identifiers here.
Putting that together you can add the following when initializing your TinyMCE. This will show "changed content" in the preview without making visible changes to the content within TinyMCE.
var preProssesInnerHtml;
tinymce.init({
//other things...
init_instance_callback: function (editor) {
editor.on('BeforeExecCommand', function (e) {
if (e.command == "mcePreview") {
//store content prior to changing.
preProssesInnerHtml = editor.getContent();
editor.setContent("changed content");
}
});
editor.on("ExecCommand", function (e) {
if (e.command == "mcePreview") {
//Restore initial content.
editor.setContent(preProssesInnerHtml);
}
});
}
}