share ace related script (#3936)

This commit is contained in:
Yasumichi Akahoshi
2026-01-30 13:56:35 +09:00
committed by GitHub
parent 6cce445dcb
commit 17b3587263
3 changed files with 254 additions and 230 deletions

View File

@@ -21,12 +21,12 @@
<div class="head">
<a href="@helpers.url(repository)/tree/@helpers.encodeRefName(branch)">@repository.name</a> /
@pathList.zipWithIndex.map { case (section, i) =>
<a href="@helpers.url(repository)/tree/@helpers.encodeRefName((branch :: pathList.take(i + 1)).mkString("/"))">@section</a> /
<a href='@helpers.url(repository)/tree/@helpers.encodeRefName((branch :: pathList.take(i + 1)).mkString("/"))'>@section</a> /
}
<input type="text" name="newFileName" id="newFileName" class="form-control" placeholder="Name your file..." value="@fileName" style="display: inline; width: 300px;" aria-label="New file name"/>
<input type="hidden" name="oldFileName" id="oldFileName" value="@fileName"/>
<input type="hidden" name="branch" id="branch" value="@branch"/>
<input type="hidden" name="path" id="path" value="@pathList.mkString("/")"/>
<input type="hidden" name="path" id="path" value='@pathList.mkString("/")'/>
</div>
@gitbucket.core.helper.html.acenavbar()
<table class="table table-bordered">
@@ -57,9 +57,9 @@
</div>
<div style="text-align: right;">
@if(fileName.isEmpty){
<a href="@helpers.url(repository)/tree/@helpers.encodeRefName((branch :: pathList).mkString("/"))" class="btn btn-default">Cancel</a>
<a href='@helpers.url(repository)/tree/@helpers.encodeRefName((branch :: pathList).mkString("/"))' class="btn btn-default">Cancel</a>
} else {
<a href="@helpers.url(repository)/blob/@helpers.encodeRefName((branch :: pathList ++ Seq(fileName.get)).mkString("/"))" class="btn btn-default">Cancel</a>
<a href='@helpers.url(repository)/blob/@helpers.encodeRefName((branch :: pathList ++ Seq(fileName.get)).mkString("/"))' class="btn btn-default">Cancel</a>
}
<input type="submit" id="commitButton" class="btn btn-success" value="Commit changes" disabled="true"/>
<input type="hidden" id="charset" name="charset" value="@content.charset"/>
@@ -71,122 +71,32 @@
</div>
</div>
</form>
<script src='@helpers.assets("/vendors/ace/ace.js")' type="text/javascript" charset="utf-8"></script>
<script src='@helpers.assets("/vendors/ace/ext-modelist.js")' type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src='@helpers.assets("/vendors/jsdifflib/difflib.js")'></script>
<link href='@helpers.assets("/vendors/jsdifflib/diffview.css")' type="text/css" rel="stylesheet" />
<script>
const gitbucket = {
editor: null,
enableWikiLink: false,
protected: @protectedBranch,
previewTemplate: '<img src="@helpers.assets("/common/images/indicator.gif")"> Previewing...',
previewUrl: '@helpers.url(repository)/_preview',
uploadUrl: '@context.path/upload/wiki/@repository.owner/@repository.name',
maxFilesize: @{ context.settings.upload.maxFileSize / 1024 / 1024 },
timeout: @{ context.settings.upload.timeout },
isRenderableUrl: "@context.baseUrl/_is_renderable?filename=",
tabSize: @tabSize,
newLineMode: "@newLineMode",
useSoftTabs: @useSoftTabs,
getFileName: function () {
return $('#newFileName').val();
},
getFilePath: function () {
return $('#path').val() + '/' + $('#newFileName').val();
},
};
</script>
<script src="@helpers.assets("/common/js/editor.js")" type="text/javascript" charset="utf-8"></script>
}
}
<script src="@helpers.assets("/vendors/ace/ace.js")" type="text/javascript" charset="utf-8"></script>
<script src="@helpers.assets("/vendors/ace/ext-modelist.js")" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="@helpers.assets("/vendors/jsdifflib/difflib.js")"></script>
<link href="@helpers.assets("/vendors/jsdifflib/diffview.css")" type="text/css" rel="stylesheet" />
<script>
$(function(){
$('#editor').text($('#initial').val());
var editor = ace.edit("editor");
var aceKeyboard = localStorage.getItem("gitbucket:editor:keyboard") || "";
editor.setKeyboardHandler(aceKeyboard == "" ? null : aceKeyboard);
var aceKeyboardSelect = document.getElementById("aceKeyboardSelect");
aceKeyboardSelect.value = aceKeyboard;
aceKeyboardSelect.addEventListener('change', () => {
editor.setKeyboardHandler(aceKeyboardSelect.value == "" ? null : aceKeyboardSelect.value);
localStorage.setItem("gitbucket:editor:keyboard", aceKeyboardSelect.value);
},true)
if(typeof localStorage.getItem('gitbucket:editor:theme') == "string"){
$('#theme').val(localStorage.getItem('gitbucket:editor:theme'));
}
editor.setTheme("ace/theme/" + $('#theme').val());
$('#theme').change(function(){
editor.setTheme("ace/theme/" + $('#theme').val());
localStorage.setItem('gitbucket:editor:theme', $('#theme').val());
});
if(localStorage.getItem('gitbucket:editor:wrap') == 'true'){
editor.getSession().setUseWrapMode(true);
$('#wrap').val('true');
}
@if(fileName.isDefined){
var modelist = ace.require("ace/ext/modelist");
var mode = modelist.getModeForPath("@fileName.get");
editor.getSession().setMode(mode.mode);
}
@if(protectedBranch){
editor.setReadOnly(true);
}
editor.getSession().setOption("tabSize", @tabSize);
editor.getSession().setOption("newLineMode", "@newLineMode");
editor.getSession().setOption("useSoftTabs", @useSoftTabs);
editor.on('change', function(){
updateCommitButtonStatus();
});
function updateCommitButtonStatus(){
if(editor.getValue() == $('#initial').val() && $('#newFileName').val() == $('#oldFileName').val()){
$('#commitButton').attr('disabled', true);
} else {
$('#commitButton').attr('disabled', false);
}
}
$('#wrap').change(function(){
if($('#wrap option:selected').val() == 'true'){
editor.getSession().setUseWrapMode(true);
localStorage.setItem('gitbucket:editor:wrap', 'true');
} else {
editor.getSession().setUseWrapMode(false);
localStorage.setItem('gitbucket:editor:wrap', 'false');
}
});
$('#newFileName').watch(function(){
updateCommitButtonStatus();
});
$('#commitButton').click(function(){
$('#content').val(editor.getValue());
});
$('#btn-code').click(function(){
$('#editor').show();
$('#preview').hide();
$('#btn-preview').removeClass('active');
});
$('#btn-preview').click(function(){
$('#editor').hide();
$('#preview').show();
$('#btn-code').removeClass('active');
$.get("@context.baseUrl/_is_renderable?filename=" + encodeURIComponent($('#newFileName').val()), function(data) {
if (data === 'true') {
// update preview
$('#preview').html('<img src="@helpers.assets("/common/images/indicator.gif")"> Previewing...');
$.post('@helpers.url(repository)/_preview', {
content : editor.getValue(),
enableWikiLink : false,
filename : $('#path').val() + '/' + $('#newFileName').val(),
enableRefsLink : false,
enableLineBreaks : false,
enableTaskList : false
}, function(data){
$('#preview').empty().append(
$('<div class="markdown-body" style="padding-left: 20px; padding-right: 20px;">').html(data));
prettyPrint();
});
} else {
// Show diff
$('#preview').empty()
.append($('<div id="diffText">'))
.append($('<textarea id="newText" style="display: none;">').data('file-name',$("#newFileName").val()).data('val', editor.getValue()))
.append($('<textarea id="oldText" style="display: none;">').data('file-name',$("#oldFileName").val()).data('val', $('#initial').val()));
diffUsingJS('oldText', 'newText', 'diffText', 1);
}
});
});
});
</script>

View File

@@ -28,117 +28,37 @@
<div class="form-group pull-right">
<input type="hidden" name="currentPageName" value="@pageName"/>
<input type="hidden" name="id" value="@page.map(_.id)"/>
<input type="submit" id="saveButton" value="Save" class="btn btn-success">
<input type="submit" id="commitButton" value="Save" class="btn btn-success">
<input type="hidden" id="content" name="content" value=""/>
<input type="hidden" id="initial" value='@page.map(_.content)'/>
</div>
</form>
<script src="@helpers.assets("/vendors/ace/ace.js")" type="text/javascript" charset="utf-8"></script>
<script src="@helpers.assets("/vendors/ace/ext-modelist.js")" type="text/javascript" charset="utf-8"></script>
<script src='@helpers.assets("/vendors/ace/ace.js")' type="text/javascript" charset="utf-8"></script>
<script src='@helpers.assets("/vendors/ace/ext-modelist.js")' type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src='@helpers.assets("/vendors/jsdifflib/difflib.js")'></script>
<link href='@helpers.assets("/vendors/jsdifflib/diffview.css")' type="text/css" rel="stylesheet" />
<script>
const gitbucket = {
editor: null,
enableWikiLink: true,
protected: false,
previewTemplate: '<img src="@helpers.assets("/common/images/indicator.gif")"> Previewing...',
previewUrl: '@helpers.url(repository)/_preview',
uploadUrl: '@context.path/upload/wiki/@repository.owner/@repository.name',
maxFilesize: @{ context.settings.upload.maxFileSize / 1024 / 1024 },
timeout: @{ context.settings.upload.timeout },
isRenderableUrl: "@context.baseUrl/_is_renderable?filename=",
tabSize: 8,
newLineMode: "auto",
useSoftTabs: false,
getFileName: function () {
return '@page.map(_.name).getOrElse("temporary.md")';
},
getFilePath: function () {
return '@page.map(_.name).getOrElse("temporary.md")';
},
};
</script>
<script src='@helpers.assets("/common/js/editor.js")' type="text/javascript" charset="utf-8"></script>
}
}
<script>
$(function(){
$('#editor').text($('#initial').val());
var editor = ace.edit("editor");
var aceKeyboard = localStorage.getItem("gitbucket:editor:keyboard") || "";
editor.setKeyboardHandler(aceKeyboard == "" ? null : aceKeyboard);
var aceKeyboardSelect = document.getElementById("aceKeyboardSelect");
aceKeyboardSelect.value = aceKeyboard;
aceKeyboardSelect.addEventListener('change', () => {
editor.setKeyboardHandler(aceKeyboardSelect.value == "" ? null : aceKeyboardSelect.value);
localStorage.setItem("gitbucket:editor:keyboard", aceKeyboardSelect.value);
},true)
if(typeof localStorage.getItem('gitbucket:editor:theme') == "string"){
$('#theme').val(localStorage.getItem('gitbucket:editor:theme'));
}
editor.setTheme("ace/theme/" + $('#theme').val());
$('#theme').change(function(){
editor.setTheme("ace/theme/" + $('#theme').val());
localStorage.setItem('gitbucket:editor:theme', $('#theme').val());
});
if(localStorage.getItem('gitbucket:editor:wrap') == 'true'){
editor.getSession().setUseWrapMode(true);
$('#wrap').val('true');
}
var modelist = ace.require("ace/ext/modelist");
var mode = modelist.getModeForPath('@page.map(_.name).getOrElse("temporary.md")');
editor.getSession().setMode(mode.mode);
$('#saveButton').click(function(){
$('#content').val(editor.getValue());
});
$('#btn-code').click(function(){
$('#editor').show();
$('.clickable').show();
$('#preview').hide();
$('#btn-preview').removeClass('active');
});
$('#btn-preview').click(function(){
$('#editor').hide();
$('.clickable').hide();
$('#preview').show();
$('#btn-code').removeClass('active');
// update preview
$('#preview').html('<img src="@helpers.assets("/common/images/indicator.gif")"> Previewing...');
$.post('@helpers.url(repository)/_preview', {
content : editor.getValue(),
enableWikiLink : true,
filename : '@page.map(_.name).getOrElse("temporary.md")',
enableRefsLink : false,
enableLineBreaks : false,
enableTaskList : false
}, function(data){
$('#preview').empty().append(
$('<div class="markdown-body" style="padding-left: 20px; padding-right: 20px;">').html(data));
prettyPrint();
});
});
try {
$('#editor').dropzone({
url: '@context.path/upload/wiki/@repository.owner/@repository.name',
maxFilesize: @{context.settings.upload.maxFileSize / 1024 / 1024},
timeout: @{context.settings.upload.timeout},
clickable: false,
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
success: function(file, id) {
var attachFile = (file.type.match(/image\/.*/) ? '\n![' + file.name.split('.')[0] : '\n[' + file.name) + '](' + file.name + ')';
editor.session.insert(editor.selection.getCursor(), attachFile);
$(file.previewElement).prevAll('div.dz-preview').addBack().remove();
}
});
$('.clickable').dropzone({
url: '@context.path/upload/wiki/@repository.owner/@repository.name',
maxFilesize: @{context.settings.upload.maxFileSize / 1024 / 1024},
timeout: @{context.settings.upload.timeout},
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
success: function(file, id) {
var attachFile = (file.type.match(/image\/.*/) ? '\n![' + file.name.split('.')[0] : '\n[' + file.name) + '](' + file.name + ')';
editor.session.insert(editor.selection.getCursor(), attachFile);
$(file.previewElement).prevAll('div.dz-preview').addBack().remove();
}
});
} catch(e) {
if (e.message !== "Dropzone already attached.") {
throw e;
}
}
$('#delete').click(function(){
return confirm('Are you sure you want to delete this page?');
});
});
</script>
}

View File

@@ -0,0 +1,194 @@
(function () {
document.addEventListener('DOMContentLoaded', () => {
/**
* element to attach images or documents by dragging & dropping, or selecting them.
* @type {Element}
*/
const clickable = document.querySelector(".clickable");
/**
* A function to update the file mode of the Ace editor
*/
const updateFileMode = function () {
if (gitbucket.getFileName() != "") {
var modelist = ace.require("ace/ext/modelist");
var mode = modelist.getModeForPath(gitbucket.getFileName());
gitbucket.editor.getSession().setMode(mode.mode);
}
};
/**
* A function to update status of commit button
*/
const updateCommitButtonStatus = function () {
if (gitbucket.editor.getValue() == $('#initial').val() && $('#newFileName').val() == $('#oldFileName').val()) {
$('#commitButton').attr('disabled', true);
} else {
$('#commitButton').attr('disabled', false);
}
}
// Initialize the editor contents
$('#editor').text($('#initial').val());
// Initializing Ace editor
gitbucket.editor = ace.edit("editor");
// Initialize Ace editor keyboard handler
var aceKeyboard = localStorage.getItem("gitbucket:editor:keyboard") || "";
gitbucket.editor.setKeyboardHandler(aceKeyboard == "" ? null : aceKeyboard);
var aceKeyboardSelect = document.getElementById("aceKeyboardSelect");
aceKeyboardSelect.value = aceKeyboard;
// Event handler to change the keyboard handler for the Ace editor
aceKeyboardSelect.addEventListener('change', () => {
gitbucket.editor.setKeyboardHandler(aceKeyboardSelect.value == "" ? null : aceKeyboardSelect.value);
localStorage.setItem("gitbucket:editor:keyboard", aceKeyboardSelect.value);
}, true)
// Initialize the Ace editor theme
if (typeof localStorage.getItem('gitbucket:editor:theme') == "string") {
$('#theme').val(localStorage.getItem('gitbucket:editor:theme'));
}
gitbucket.editor.setTheme("ace/theme/" + $('#theme').val());
// Event handler to change the Ace editor theme
$('#theme').change(function () {
gitbucket.editor.setTheme("ace/theme/" + $('#theme').val());
localStorage.setItem('gitbucket:editor:theme', $('#theme').val());
});
// Initialize text wrapping for Ace editor
if (localStorage.getItem('gitbucket:editor:wrap') == 'true') {
gitbucket.editor.getSession().setUseWrapMode(true);
$('#wrap').val('true');
}
// Event handler to change text wrapping for Ace editor
$('#wrap').change(function () {
if ($('#wrap option:selected').val() == 'true') {
gitbucket.editor.getSession().setUseWrapMode(true);
localStorage.setItem('gitbucket:editor:wrap', 'true');
} else {
gitbucket.editor.getSession().setUseWrapMode(false);
localStorage.setItem('gitbucket:editor:wrap', 'false');
}
});
// Initialize file mode for Ace editor
updateFileMode();
// Determine whether Ace Editor can be edited
if (gitbucket.protected) {
gitbucket.editor.setReadOnly(true);
}
// Initialize tabSize, newLineMode, and useSoftTabs for the Ace editor.
gitbucket.editor.getSession().setOption("tabSize", gitbucket.tabSize);
gitbucket.editor.getSession().setOption("newLineMode", gitbucket.newLineMode);
gitbucket.editor.getSession().setOption("useSoftTabs", gitbucket.useSoftTabs);
// Controls the activation of the commit button when using the repository file editor.
if (!document.location.href.endsWith("/_edit")) {
gitbucket.editor.on('change', function () {
updateCommitButtonStatus();
});
$('#newFileName').watch(function () {
updateCommitButtonStatus();
updateFileMode();
});
}
// When the Commit button is clicked, the form content will be overwritten with the editor content.
$('#commitButton').click(function () {
$('#content').val(gitbucket.editor.getValue());
});
// An event handler that defines what happens when the code button is clicked.
$('#btn-code').click(function () {
$('#editor').show();
$('#preview').hide();
$('#btn-preview').removeClass('active');
if (clickable) clickable.style.display = "block";
});
// An event handler that defines what happens when the preview button is clicked.
$('#btn-preview').click(function () {
$('#editor').hide();
$('#preview').show();
$('#btn-code').removeClass('active');
if (clickable) clickable.style.display = "none";
// Determine if rendering is possible
$.get(gitbucket.isRenderableUrl + gitbucket.getFileName(), function (data) {
if (data === 'true') {
// update preview
$('#preview').html(gitbucket.previewTemplate);
$.post(gitbucket.previewUrl, {
content: gitbucket.editor.getValue(),
enableWikiLink: gitbucket.enableWikiLink,
filename: gitbucket.getFilePath(),
enableRefsLink: false,
enableLineBreaks: false,
enableTaskList: false
}, function (data) {
$('#preview').empty().append(
$('<div class="markdown-body" style="padding-left: 20px; padding-right: 20px;">').html(data));
prettyPrint();
});
} else {
// Show diff
$('#preview').empty()
.append($('<div id="diffText">'))
.append($('<textarea id="newText" style="display: none;">').data('file-name', $("#newFileName").val()).data('val', gitbucket.editor.getValue()))
.append($('<textarea id="oldText" style="display: none;">').data('file-name', $("#oldFileName").val()).data('val', $('#initial').val()));
diffUsingJS('oldText', 'newText', 'diffText', 1);
}
});
});
// In the case of a Wiki editor, it controls the parts for attachments and delete button.
if (document.location.href.endsWith("/_edit")) {
try {
// Event handler to capture drag and drop into the editor
$('#editor').dropzone({
url: gitbucket.uploadUrl,
maxFilesize: gitbucket.maxFilesize,
timeout: gitbucket.timeout,
clickable: false,
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
success: function (file, id) {
var attachFile = (file.type.match(/image\/.*/) ? '\n![' + file.name.split('.')[0] : '\n[' + file.name) + '](' + file.name + ')';
gitbucket.editor.session.insert(gitbucket.editor.selection.getCursor(), attachFile);
$(file.previewElement).prevAll('div.dz-preview').addBack().remove();
}
});
// Event handler to capture drag and drop into the clickable
$('.clickable').dropzone({
url: gitbucket.uploadUrl,
maxFilesize: gitbucket.maxFilesize,
timeout: gitbucket.timeout,
previewTemplate: "<div class=\"dz-preview\">\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress>Uploading your files...</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
success: function (file, id) {
var attachFile = (file.type.match(/image\/.*/) ? '\n![' + file.name.split('.')[0] : '\n[' + file.name) + '](' + file.name + ')';
gitbucket.editor.session.insert(gitbucket.editor.selection.getCursor(), attachFile);
$(file.previewElement).prevAll('div.dz-preview').addBack().remove();
}
});
} catch (e) {
if (e.message !== "Dropzone already attached.") {
throw e;
}
}
// An event handler to capture clicks on the Delete button
$('#delete').click(function () {
return confirm('Are you sure you want to delete this page?');
});
}
});
})();