Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1431461
ext.scribunto.edit.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
ext.scribunto.edit.js
View Options
(
()
=>
{
/**
* Debug console
* Based on JavaScript Shell 1.4 by Jesse Ruderman (GPL/LGPL/MPL tri-license)
*
* TODO:
* * Refactor, more jQuery, etc.
* * Spinner?
* * A prompt in front of input lines and the textarea
* * Collapsible backtrace display
*/
const
histList
=
[
''
];
let
histPos
=
0
,
question
,
input
,
output
,
$spinner
,
sessionContent
=
null
,
sessionKey
=
null
,
pending
=
false
,
clearNextRequest
=
false
;
function
refocus
()
{
// Needed for Mozilla to scroll correctly
input
.
blur
();
input
.
focus
();
}
function
initConsole
()
{
input
=
document
.
getElementById
(
'mw-scribunto-input'
);
output
=
document
.
getElementById
(
'mw-scribunto-output'
);
$spinner
=
$
.
createSpinner
(
{
size
:
'small'
,
type
:
'block'
}
);
recalculateInputHeight
();
println
(
mw
.
msg
(
'scribunto-console-intro'
),
'mw-scribunto-message'
);
}
/**
* Use onkeydown because IE doesn't support onkeypress for arrow keys
*
* @param {jQuery.Event} e
*/
function
inputKeydown
(
e
)
{
if
(
e
.
shiftKey
&&
e
.
keyCode
===
13
)
{
// shift-enter
// don't do anything; allow the shift-enter to insert a line break as normal
}
else
if
(
e
.
keyCode
===
13
)
{
// enter
// execute the input on enter
go
();
}
else
if
(
e
.
keyCode
===
38
)
{
// up
// go up in history if at top or ctrl-up
if
(
e
.
ctrlKey
||
caretInFirstLine
(
input
)
)
{
hist
(
'up'
);
}
}
else
if
(
e
.
keyCode
===
40
)
{
// down
// go down in history if at end or ctrl-down
if
(
e
.
ctrlKey
||
caretInLastLine
(
input
)
)
{
hist
(
'down'
);
}
}
setTimeout
(
recalculateInputHeight
,
0
);
}
function
inputFocus
()
{
if
(
sessionContent
===
null
)
{
// No previous state to clear
return
;
}
if
(
clearNextRequest
)
{
// User already knows
return
;
}
if
(
getContent
()
!==
sessionContent
)
{
printClearBar
(
'scribunto-console-cleared'
);
clearNextRequest
=
true
;
}
}
function
caretInFirstLine
(
textbox
)
{
// IE doesn't support selectionStart/selectionEnd
if
(
textbox
.
selectionStart
===
undefined
)
{
return
true
;
}
const
firstLineBreak
=
textbox
.
value
.
indexOf
(
'\n'
);
return
(
(
firstLineBreak
===
-
1
)
||
(
textbox
.
selectionStart
<=
firstLineBreak
)
);
}
function
caretInLastLine
(
textbox
)
{
// IE doesn't support selectionStart/selectionEnd
if
(
textbox
.
selectionEnd
===
undefined
)
{
return
true
;
}
const
lastLineBreak
=
textbox
.
value
.
lastIndexOf
(
'\n'
);
return
(
textbox
.
selectionEnd
>
lastLineBreak
);
}
function
recalculateInputHeight
()
{
const
rows
=
input
.
value
.
split
(
/\n/
).
length
+
// prevent scrollbar flickering in Mozilla
1
+
// leave room for scrollbar in Opera
(
window
.
opera
?
1
:
0
);
// without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.
if
(
input
.
rows
!==
rows
)
{
input
.
rows
=
rows
;
}
}
function
println
(
s
,
type
)
{
if
(
(
s
=
String
(
s
)
)
)
{
const
newdiv
=
document
.
createElement
(
'div'
);
newdiv
.
appendChild
(
document
.
createTextNode
(
s
)
);
newdiv
.
className
=
type
;
output
.
appendChild
(
newdiv
);
return
newdiv
;
}
}
function
printClearBar
(
msg
)
{
$
(
'<div>'
)
.
attr
(
'class'
,
'mw-scribunto-clear'
)
.
text
(
mw
.
msg
(
msg
)
)
.
appendTo
(
output
);
}
function
hist
(
direction
)
{
// histList[0] = first command entered, [1] = second, etc.
// type something, press up --> thing typed is now in "limbo"
// (last item in histList) and should be reachable by pressing
// down again.
const
L
=
histList
.
length
;
if
(
L
===
1
)
{
return
;
}
if
(
direction
===
'up'
)
{
if
(
histPos
===
L
-
1
)
{
// Save this entry in case the user hits the down key.
histList
[
histPos
]
=
input
.
value
;
}
if
(
histPos
>
0
)
{
histPos
--
;
// Use a timeout to prevent up from moving cursor within new text
// Set to nothing first for the same reason
setTimeout
(
()
=>
{
input
.
value
=
''
;
input
.
value
=
histList
[
histPos
];
const
caretPos
=
input
.
value
.
length
;
if
(
input
.
setSelectionRange
)
{
input
.
setSelectionRange
(
caretPos
,
caretPos
);
}
},
0
);
}
}
else
{
// direction down
if
(
histPos
<
L
-
1
)
{
histPos
++
;
input
.
value
=
histList
[
histPos
];
}
else
if
(
histPos
===
L
-
1
)
{
// Already on the current entry: clear but save
if
(
input
.
value
)
{
histList
[
histPos
]
=
input
.
value
;
++
histPos
;
input
.
value
=
''
;
}
}
}
}
function
printQuestion
(
q
)
{
println
(
q
,
'mw-scribunto-input'
);
}
function
printError
(
er
)
{
if
(
er
.
name
)
{
// lineNumberString should not be '', to avoid a very wacky bug in IE 6.
const
lineNumberString
=
(
er
.
lineNumber
!==
undefined
)
?
(
' on line '
+
er
.
lineNumber
+
': '
)
:
': '
;
// Because IE doesn't have error.toString.
println
(
er
.
name
+
lineNumberString
+
er
.
message
,
'mw-scribunto-error'
);
}
else
{
// Because security errors in Moz /only/ have toString.
println
(
er
,
'mw-scribunto-error'
);
}
}
function
setPending
()
{
pending
=
true
;
input
.
readOnly
=
true
;
$spinner
.
insertBefore
(
input
);
}
function
clearPending
()
{
$spinner
.
remove
();
pending
=
false
;
input
.
readOnly
=
false
;
}
function
go
()
{
if
(
pending
)
{
// If there is an XHR request pending, don't send another one
// We set readOnly on the textarea to give a UI indication, this is
// just for paranoia.
return
;
}
question
=
input
.
value
;
if
(
question
===
''
)
{
return
;
}
histList
[
histList
.
length
-
1
]
=
question
;
histList
[
histList
.
length
]
=
''
;
histPos
=
histList
.
length
-
1
;
// Unfortunately, this has to happen *before* the script is run, so that
// print() output will go in the right place.
input
.
value
=
''
;
// can't preventDefault on input, so also clear it later
setTimeout
(
()
=>
{
input
.
value
=
''
;
},
0
);
recalculateInputHeight
();
printQuestion
(
question
);
const
params
=
{
action
:
'scribunto-console'
,
title
:
mw
.
config
.
get
(
'wgPageName'
),
question
:
question
};
const
content
=
getContent
();
let
sentContent
=
false
;
if
(
!
sessionKey
||
sessionContent
!==
content
)
{
params
.
clear
=
true
;
params
.
content
=
content
;
sentContent
=
true
;
}
if
(
sessionKey
)
{
params
.
session
=
sessionKey
;
}
if
(
clearNextRequest
)
{
params
.
clear
=
true
;
clearNextRequest
=
false
;
}
const
api
=
new
mw
.
Api
();
setPending
();
api
.
postWithToken
(
'csrf'
,
params
)
.
done
(
(
result
)
=>
{
if
(
result
.
sessionIsNew
===
''
&&
!
sentContent
)
{
// Session was lost. Resend query, with content
printClearBar
(
'scribunto-console-cleared-session-lost'
);
sessionContent
=
null
;
clearPending
();
input
.
value
=
params
.
question
;
go
();
return
;
}
sessionKey
=
result
.
session
;
sessionContent
=
content
;
if
(
result
.
type
===
'error'
)
{
$
(
'<div>'
).
addClass
(
'mw-scribunto-error'
).
html
(
result
.
html
).
appendTo
(
output
);
}
else
{
if
(
result
.
print
!==
''
)
{
println
(
result
.
print
,
'mw-scribunto-print'
);
}
if
(
result
.
return
!==
''
)
{
println
(
result
.
return
,
'mw-scribunto-normalOutput'
);
}
}
clearPending
();
setTimeout
(
refocus
,
0
);
}
)
.
fail
(
(
code
,
result
)
=>
{
if
(
result
.
error
&&
result
.
error
.
info
)
{
printError
(
result
.
error
.
info
);
}
else
if
(
result
.
exception
)
{
printError
(
'Error sending API request: '
+
result
.
exception
);
}
else
{
mw
.
log
(
result
);
printError
(
'error'
);
}
clearPending
();
setTimeout
(
refocus
,
0
);
}
);
}
function
getContent
()
{
const
$textarea
=
$
(
'#wpTextbox1'
),
context
=
$textarea
.
data
(
'wikiEditor-context'
);
if
(
context
===
undefined
||
context
.
codeEditor
===
undefined
)
{
return
$textarea
.
val
();
}
else
{
return
$textarea
.
textSelection
(
'getContents'
);
}
}
function
onClearClick
()
{
$
(
'#mw-scribunto-output'
).
empty
();
clearNextRequest
=
true
;
refocus
();
}
function
initEditPage
()
{
let
$console
=
$
(
'#mw-scribunto-console'
);
if
(
!
$console
.
length
)
{
// There is no console in the DOM; on read-only (protected) pages,
// we need to add it here, because the hook does not insert
// it server-side.
const
$wpTextbox1
=
$
(
'#wpTextbox1'
);
if
(
!
$wpTextbox1
.
length
||
!
$wpTextbox1
.
prop
(
'readonly'
)
)
{
return
;
}
$console
=
$
(
'<div>'
).
attr
(
{
id
:
'mw-scribunto-console'
}
);
$wpTextbox1
.
after
(
$console
);
}
$
(
'<fieldset>'
)
.
attr
(
'class'
,
'mw-scribunto-console-fieldset'
)
.
append
(
$
(
'<legend>'
).
text
(
mw
.
msg
(
'scribunto-console-title'
)
)
)
.
append
(
$
(
'<div id="mw-scribunto-output"></div>'
)
)
.
append
(
$
(
'<div>'
).
append
(
$
(
'<textarea>'
)
.
attr
(
{
id
:
'mw-scribunto-input'
,
class
:
'mw-scribunto-input'
,
wrap
:
'off'
,
rows
:
1
,
dir
:
'ltr'
,
lang
:
'en'
}
)
.
on
(
'keydown'
,
inputKeydown
)
.
on
(
'focus'
,
inputFocus
)
)
)
.
append
(
$
(
'<div>'
).
append
(
$
(
'<input>'
)
.
attr
(
{
type
:
'button'
,
value
:
mw
.
msg
(
'scribunto-console-clear'
)
}
)
.
on
(
'click'
,
onClearClick
)
)
)
.
wrap
(
'<form>'
)
.
appendTo
(
$console
);
initConsole
();
}
$
(
()
=>
{
const
action
=
mw
.
config
.
get
(
'wgAction'
);
if
(
action
===
'edit'
||
action
===
'submit'
||
action
===
'editredlink'
)
{
initEditPage
();
}
}
);
}
)();
File Metadata
Details
Attached
Mime Type
text/x-asm
Expires
Sat, May 16, 20:30 (1 d, 5 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
34/c8/b425fd0a2eeec251baf6bbdf6fc5
Default Alt Text
ext.scribunto.edit.js (9 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment