parent
d2ee68f22a
commit
8ea85ac16b
4 changed files with 907 additions and 0 deletions
@ -0,0 +1 @@ |
||||
/.idea/ |
||||
@ -0,0 +1,263 @@ |
||||
function bindCodeEditorShortcutKeys(textarea) { |
||||
|
||||
// applying shortcut keys
|
||||
textarea.addEventListener('keydown', function (e) { |
||||
|
||||
// [Enter] key pressed detected
|
||||
if (e.key === 'Enter') { |
||||
|
||||
// Prevent the default behavior (new line)
|
||||
e.preventDefault(); |
||||
|
||||
// Get the cursor position
|
||||
var cursorPos = textarea.selectionStart; |
||||
|
||||
// Get the previous line
|
||||
var prevLine = textarea.value.substring(0, cursorPos).split('\n').slice(-1)[0]; |
||||
|
||||
// Get the indentation of the previous line
|
||||
var indent = prevLine.match(/^\s*/)[0]; |
||||
|
||||
// Add a new line with the same indentation
|
||||
textarea.setRangeText('\n' + indent, cursorPos, cursorPos, 'end'); |
||||
|
||||
// remove focus
|
||||
textarea.blur(); |
||||
|
||||
// regain focus (this is force the textarea scroll to caret position in case the caret falls out the textarea visible area)
|
||||
textarea.focus(); |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Tab] pressed, but no [Shift]
|
||||
if (e.key === "Tab" && !e.shiftKey && |
||||
|
||||
// and no highlight detected
|
||||
textarea.selectionStart == textarea.selectionEnd) { |
||||
|
||||
// suspend default behaviour
|
||||
e.preventDefault(); |
||||
|
||||
// Get the current cursor position
|
||||
let cursorPosition = textarea.selectionStart; |
||||
|
||||
// Insert 4 white spaces at the cursor position
|
||||
let newValue = textarea.value.substring(0, cursorPosition) + " " + |
||||
textarea.value.substring(cursorPosition); |
||||
|
||||
// Update the textarea value and cursor position
|
||||
textarea.value = newValue; |
||||
textarea.selectionStart = textarea.selectionEnd = cursorPosition + 4; |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Tab] and [Shift] keypress presence
|
||||
if (e.key === "Tab" && e.shiftKey && |
||||
|
||||
// no highlight detected
|
||||
textarea.selectionStart == textarea.selectionEnd) { |
||||
|
||||
// suspend default behaviour
|
||||
e.preventDefault(); |
||||
|
||||
// Get the current cursor position
|
||||
let cursorPosition = textarea.selectionStart; |
||||
|
||||
// Check the previous characters for spaces
|
||||
let leadingSpaces = 0; |
||||
for (let i = 0; i < 4; i++) { |
||||
if (textarea.value[cursorPosition - i - 1] === " ") { |
||||
leadingSpaces++; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (leadingSpaces > 0) { |
||||
// Remove the spaces
|
||||
let newValue = textarea.value.substring(0, cursorPosition - leadingSpaces) + |
||||
textarea.value.substring(cursorPosition); |
||||
|
||||
// Update the textarea value and cursor position
|
||||
textarea.value = newValue; |
||||
textarea.selectionStart = textarea.selectionEnd = cursorPosition - leadingSpaces; |
||||
} |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Tab] key pressed and range selection detected
|
||||
if (e.key == 'Tab' & textarea.selectionStart != textarea.selectionEnd) { |
||||
e.preventDefault(); |
||||
|
||||
// split the textarea content into lines
|
||||
let lines = textarea.value.split('\n'); |
||||
|
||||
// find the start/end lines
|
||||
let startPos = textarea.value.substring(0, textarea.selectionStart).split('\n').length - 1; |
||||
let endPos = textarea.value.substring(0, textarea.selectionEnd).split('\n').length - 1; |
||||
|
||||
// calculating total removed white spaces
|
||||
// these values will be used for adjusting new cursor position
|
||||
let spacesRemovedFirstLine = 0; |
||||
let spacesRemoved = 0; |
||||
|
||||
// [Shift] key was pressed (this means we're un-indenting)
|
||||
if (e.shiftKey) { |
||||
|
||||
// iterate over all lines
|
||||
for (let i = startPos; i <= endPos; i++) { |
||||
|
||||
// /^ = from the start of the line,
|
||||
// {1,4} = remove in between 1 to 4 white spaces that may existed
|
||||
lines[i] = lines[i].replace(/^ {1,4}/, function (match) { |
||||
|
||||
// "match" is a string (white space) extracted
|
||||
|
||||
// obtaining total white spaces removed
|
||||
|
||||
// total white space removed at first line
|
||||
if (i == startPos) |
||||
spacesRemovedFirstLine = match.length; |
||||
|
||||
// total white space removed overall
|
||||
spacesRemoved += match.length; |
||||
|
||||
return ''; |
||||
}); |
||||
} |
||||
} |
||||
|
||||
// no shift key, so we're indenting
|
||||
else { |
||||
// iterate over all lines
|
||||
for (let i = startPos; i <= endPos; i++) { |
||||
// add a tab to the start of the line
|
||||
lines[i] = ' ' + lines[i]; // four spaces
|
||||
} |
||||
} |
||||
|
||||
// remember the cursor position
|
||||
let start = textarea.selectionStart; |
||||
let end = textarea.selectionEnd; |
||||
|
||||
// put the modified lines back into the textarea
|
||||
textarea.value = lines.join('\n'); |
||||
|
||||
// adjust the position of cursor start selection
|
||||
textarea.selectionStart = e.shiftKey ? |
||||
start - spacesRemovedFirstLine : start + 4; |
||||
|
||||
// adjust the position of cursor end selection
|
||||
textarea.selectionEnd = e.shiftKey ? |
||||
end - spacesRemoved : end + 4 * (endPos - startPos + 1); |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
return; |
||||
} |
||||
|
||||
// [Shift] + [Del]/[Backspace] = Delete entire line(s)
|
||||
if (e.shiftKey && (e.key === "Delete" || e.key === "Backspace")) { |
||||
|
||||
e.preventDefault(); |
||||
|
||||
// find the start/end lines
|
||||
let startPos = textarea.value.substring(0, textarea.selectionStart).split('\n').length - 1; |
||||
let endPos = textarea.value.substring(0, textarea.selectionEnd).split('\n').length - 1; |
||||
|
||||
// get the line and the position in that line where the cursor is
|
||||
// pop() = take out the last line (which is the cursor selection start located)
|
||||
let cursorLine = textarea.value.substring(0, textarea.selectionStart).split('\n').pop(); |
||||
|
||||
// get the position of cursor within the last line
|
||||
let cursorPosInLine = cursorLine.length; |
||||
|
||||
// calculating total lines to be removed
|
||||
let totalLinesRemove = endPos - startPos + 1; |
||||
|
||||
// split the textarea content into lines
|
||||
let lines = textarea.value.split('\n'); |
||||
|
||||
// calculate new cursor position
|
||||
let newStart = lines.slice(0, startPos).join('\n').length + (startPos > 0 ? 1 : 0); |
||||
// add 1 if startPos > 0 to account for '\n' character
|
||||
|
||||
// remove the selected lines
|
||||
lines.splice(startPos, totalLinesRemove); |
||||
|
||||
// get the new line where the cursor will be after deleting lines
|
||||
// if lines[startPos] is not existed, then the new line will be an empty string
|
||||
let newLine = lines[startPos] || ''; |
||||
|
||||
// if the new line is shorter than the cursor position, put the cursor at the end of the line
|
||||
if (newLine.length < cursorPosInLine) { |
||||
cursorPosInLine = newLine.length; |
||||
} |
||||
|
||||
// adjuct the cursor's position in the line to the new cursor position
|
||||
newStart += cursorPosInLine; |
||||
|
||||
// put the modified lines back into the textarea
|
||||
textarea.value = lines.join('\n'); |
||||
|
||||
// set the new cursor position
|
||||
// both cursor selection start and end will be at the same position
|
||||
textarea.selectionStart = textarea.selectionEnd = newStart; |
||||
|
||||
// copy the code from textarea to code block
|
||||
updateCode(); |
||||
|
||||
return; |
||||
} |
||||
|
||||
// Move cursor to the first non-white space character
|
||||
if (e.key === "Home") { |
||||
|
||||
// get the line and the position in that line where the cursor is
|
||||
// pop() = take out the last line (which is the cursor selection start located)
|
||||
let line = textarea.value.substring(0, textarea.selectionStart).split('\n').pop(); |
||||
|
||||
// get the position of cursor within the last line
|
||||
let cursorPosInLine = line.length; |
||||
|
||||
// Find the start of the current line
|
||||
let lineStartPos = textarea.value.substring(0, textarea.selectionStart).lastIndexOf('\n') + 1; |
||||
|
||||
// Find the first non-whitespace character on the line
|
||||
let firstNonWhitespacePos = line.search(/\S/); |
||||
|
||||
// the cursor's position is already in front of first non-whitespace character,
|
||||
// or it's position is before first none-whitespace character,
|
||||
// move the cursor to the start of line
|
||||
if (firstNonWhitespacePos >= cursorPosInLine) { |
||||
// do nothing, perform default behaviour, which is moving the cursor to beginning of the line
|
||||
return true; |
||||
} |
||||
// If there's no non-whitespace character, this is an empty or whitespace-only line
|
||||
else if (firstNonWhitespacePos === -1) { |
||||
// do nothing, perform default behaviour, which is moving the cursor to beginning of the line
|
||||
return true; |
||||
} |
||||
|
||||
// Prevent the default Home key behavior
|
||||
e.preventDefault(); |
||||
|
||||
// Move the cursor to the position of the first non-whitespace character
|
||||
textarea.selectionStart = textarea.selectionEnd = lineStartPos + firstNonWhitespacePos; |
||||
|
||||
return; |
||||
} |
||||
|
||||
|
||||
}); |
||||
|
||||
} |
||||
@ -0,0 +1,114 @@ |
||||
<head> |
||||
<meta charSet="UTF-8"/> |
||||
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script> |
||||
<link href="https://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> |
||||
<link href="https://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet"> |
||||
<script src="https://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script> |
||||
<script src="https://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script> |
||||
<link href="https://cdn.bootcdn.net/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.css" rel="stylesheet"> |
||||
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap-select/1.13.18/js/bootstrap-select.js"></script> |
||||
|
||||
<style type="text/css"> |
||||
#divCodeWrapper { |
||||
height: calc(100vh - 200px); |
||||
max-height: 600px; |
||||
width: 1200px; |
||||
overflow: hidden; |
||||
border: 1px solid #a5a5a5; |
||||
position: relative; |
||||
} |
||||
|
||||
#preCode { |
||||
height: 100%; |
||||
width: calc(100% - 50px); |
||||
position: absolute; |
||||
top: 0; |
||||
left: 50px; |
||||
overflow: hidden; |
||||
padding: 0; |
||||
margin: 0; |
||||
background: #1b1b1b; |
||||
border: none; |
||||
} |
||||
|
||||
#preCode code { |
||||
padding: 15px; |
||||
height: calc(100% - 30px); |
||||
width: calc(100% - 30px); |
||||
overflow-y: scroll; |
||||
overflow-x: auto; |
||||
} |
||||
|
||||
textarea { |
||||
position: absolute; |
||||
top: 0; |
||||
padding: 15px; |
||||
z-index: 2; |
||||
overflow-x: auto; |
||||
overflow-y: scroll; |
||||
white-space: nowrap; |
||||
background-color: rgba(0, 0, 0, 0); |
||||
color: rgba(0, 0, 0, 0); |
||||
caret-color: white; |
||||
border: none; |
||||
outline: none; |
||||
border-left: 1px solid #383838; |
||||
} |
||||
|
||||
#lineNumbers { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
text-align: right; |
||||
height: calc(100% - 50px); |
||||
width: 100px; |
||||
overflow: hidden; |
||||
} |
||||
</style> |
||||
|
||||
<link id="theme1" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/vs2015.min.css" |
||||
rel="stylesheet"/> |
||||
|
||||
<script src="codeEditorShortcutKeys.js" type="text/javascript"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js" |
||||
type="text/javascript"></script> |
||||
</head> |
||||
|
||||
|
||||
<body> |
||||
<div style="width: 600px; margin: 0 auto; padding-top: 50px"> |
||||
<script> |
||||
function postForm(form) { |
||||
axios.post('/py2php.php', { |
||||
code: form.code.value, |
||||
}, { |
||||
headers: { |
||||
'Content-Type': 'application/json' |
||||
} |
||||
}).then(response => { |
||||
if (response.data.data.result == undefined) { |
||||
form.result.value = 'ERROR' |
||||
} else { |
||||
form.result.value = response.data.data.result |
||||
} |
||||
}).catch(error => { |
||||
console.log(error); |
||||
}); |
||||
|
||||
return false; |
||||
} |
||||
</script> |
||||
<h1>phpy 工具集</h1> |
||||
<ul class="nav nav-tabs"> |
||||
<li role="presentation" class="active"><a href="#">Python 转 PHP</a></li> |
||||
</ul> |
||||
<form style="margin-top: 30px" onsubmit="return postForm(this)"> |
||||
<div class="form-group"> |
||||
<label>Python 代码</label> |
||||
<textarea class="form-control" rows="32" name="code"></textarea> |
||||
</div> |
||||
<button type="submit" class="btn btn-primary">提交</button> |
||||
</form> |
||||
</div> |
||||
|
||||
</body> |
||||
Loading…
Reference in new issue