Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1425865
ve.ui.MWLatexDialog.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
ve.ui.MWLatexDialog.js
View Options
/*!
* VisualEditor user interface MWLatexDialog class.
*
* @copyright See AUTHORS.txt
* @license MIT
*/
/**
* Abstract dialog for inserting and editing different formulas
* provided by the Math extension.
*
* @abstract
* @class
* @extends ve.ui.MWExtensionPreviewDialog
*
* @constructor
* @param {Object} [config] Configuration options
*/
ve
.
ui
.
MWLatexDialog
=
function
VeUiMWLatexDialog
(
config
)
{
// Parent constructor
ve
.
ui
.
MWLatexDialog
.
super
.
call
(
this
,
config
);
};
/* Inheritance */
OO
.
inheritClass
(
ve
.
ui
.
MWLatexDialog
,
ve
.
ui
.
MWExtensionPreviewDialog
);
/* Static properties */
ve
.
ui
.
MWLatexDialog
.
static
.
size
=
'larger'
;
ve
.
ui
.
MWLatexDialog
.
static
.
dir
=
'ltr'
;
ve
.
ui
.
MWLatexDialog
.
static
.
symbolsModule
=
null
;
/* Methods */
/**
* @inheritdoc
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
initialize
=
function
()
{
// Parent method
ve
.
ui
.
MWLatexDialog
.
super
.
prototype
.
initialize
.
call
(
this
);
// Layout for the formula inserter (formula tab panel) and options form (options tab panel)
this
.
indexLayout
=
new
OO
.
ui
.
IndexLayout
();
const
formulaTabPanel
=
new
OO
.
ui
.
TabPanelLayout
(
'formula'
,
{
label
:
ve
.
msg
(
'math-visualeditor-mwlatexdialog-card-formula'
),
padded
:
true
,
classes
:
[
'latex-dialog-formula-panel'
]
}
);
const
optionsTabPanel
=
new
OO
.
ui
.
TabPanelLayout
(
'options'
,
{
label
:
ve
.
msg
(
'math-visualeditor-mwlatexdialog-card-options'
),
padded
:
true
,
classes
:
[
'latex-dialog-options-panel'
]
}
);
this
.
indexLayout
.
addTabPanels
(
[
formulaTabPanel
,
optionsTabPanel
]
);
// Layout for symbol picker (menu) and input and preview (content)
this
.
menuLayout
=
new
OO
.
ui
.
MenuLayout
(
{
menuPosition
:
'bottom'
,
classes
:
[
've-ui-mwLatexDialog-menuLayout'
]
}
);
this
.
previewElement
.
$element
.
addClass
(
've-ui-mwLatexDialog-preview'
);
this
.
input
=
new
ve
.
ui
.
MWAceEditorWidget
(
{
rows
:
1
,
// This will be recalculated later in onWindowManagerResize
autocomplete
:
'live'
,
autocompleteWordList
:
this
.
constructor
.
static
.
autocompleteWordList
}
).
setLanguage
(
'latex'
);
this
.
input
.
togglePrintMargin
(
false
);
this
.
displaySelect
=
new
OO
.
ui
.
ButtonSelectWidget
(
{
items
:
[
new
OO
.
ui
.
ButtonOptionWidget
(
{
data
:
'default'
,
icon
:
'mathematicsDisplayDefault'
,
label
:
ve
.
msg
(
'math-visualeditor-mwlatexinspector-display-default'
)
}
),
new
OO
.
ui
.
ButtonOptionWidget
(
{
data
:
'inline'
,
icon
:
'mathematicsDisplayInline'
,
label
:
ve
.
msg
(
'math-visualeditor-mwlatexinspector-display-inline'
)
}
),
new
OO
.
ui
.
ButtonOptionWidget
(
{
data
:
'block'
,
icon
:
'mathematicsDisplayBlock'
,
label
:
ve
.
msg
(
'math-visualeditor-mwlatexinspector-display-block'
)
}
)
]
}
);
this
.
idInput
=
new
OO
.
ui
.
TextInputWidget
();
this
.
qidInput
=
new
mw
.
widgets
.
MathWbEntitySelector
();
const
inputField
=
new
OO
.
ui
.
FieldLayout
(
this
.
input
,
{
align
:
'top'
,
classes
:
[
'latex-dialog-formula-field'
],
label
:
ve
.
msg
(
'math-visualeditor-mwlatexdialog-card-formula'
)
}
);
const
displayField
=
new
OO
.
ui
.
FieldLayout
(
this
.
displaySelect
,
{
align
:
'top'
,
classes
:
[
'latex-dialog-display-field'
],
label
:
ve
.
msg
(
'math-visualeditor-mwlatexinspector-display'
)
}
);
const
idField
=
new
OO
.
ui
.
FieldLayout
(
this
.
idInput
,
{
align
:
'top'
,
classes
:
[
'latex-dialog-id-field'
],
label
:
ve
.
msg
(
'math-visualeditor-mwlatexinspector-id'
)
}
);
const
qidField
=
new
OO
.
ui
.
FieldLayout
(
this
.
qidInput
,
{
align
:
'top'
,
classes
:
[
'latex-dialog-qid-field'
],
label
:
ve
.
msg
(
'math-visualeditor-mwlatexinspector-qid'
)
}
);
const
formulaPanel
=
new
OO
.
ui
.
PanelLayout
(
{
scrollable
:
true
,
padded
:
true
}
);
// Layout for the symbol picker
this
.
bookletLayout
=
new
ve
.
ui
.
SymbolListBookletLayout
(
{
classes
:
[
've-ui-mwLatexDialog-symbols'
]
}
);
this
.
pages
=
[];
this
.
symbolsPromise
=
mw
.
loader
.
using
(
this
.
constructor
.
static
.
symbolsModule
).
done
(
(
require
)
=>
{
// eslint-disable-next-line security/detect-non-literal-require
const
symbols
=
require
(
this
.
constructor
.
static
.
symbolsModule
);
const
symbolData
=
{};
for
(
const
category
in
symbols
)
{
const
symbolList
=
symbols
[
category
].
filter
(
(
symbol
)
=>
{
if
(
symbol
.
notWorking
||
symbol
.
duplicate
)
{
return
false
;
}
const
tex
=
symbol
.
tex
||
symbol
.
insert
;
const
classes
=
[
've-ui-mwLatexDialog-symbol'
];
classes
.
push
(
've-ui-mwLatexSymbol-'
+
tex
.
replace
(
/[^\w]/g
,
(
c
)
=>
'_'
+
c
.
charCodeAt
(
0
)
+
'_'
)
);
if
(
symbol
.
width
)
{
// The following classes are used here:
// * ve-ui-mwLatexDialog-symbol-wide
// * ve-ui-mwLatexDialog-symbol-wider
// * ve-ui-mwLatexDialog-symbol-widest
classes
.
push
(
've-ui-mwLatexDialog-symbol-'
+
symbol
.
width
);
}
if
(
symbol
.
contain
)
{
classes
.
push
(
've-ui-mwLatexDialog-symbol-contain'
);
}
if
(
symbol
.
largeLayout
)
{
classes
.
push
(
've-ui-mwLatexDialog-symbol-largeLayout'
);
}
// T366737 - make sure the symbols appear in night mode
classes
.
push
(
'skin-invert'
);
symbol
.
label
=
''
;
symbol
.
classes
=
classes
;
return
true
;
}
);
symbolData
[
category
]
=
{
// eslint-disable-next-line mediawiki/msg-doc
label
:
ve
.
msg
(
category
),
symbols
:
symbolList
};
}
this
.
bookletLayout
.
setSymbolData
(
symbolData
);
this
.
bookletLayout
.
connect
(
this
,
{
choose
:
'onSymbolChoose'
}
);
// Append everything
formulaPanel
.
$element
.
append
(
this
.
previewElement
.
$element
,
inputField
.
$element
);
this
.
menuLayout
.
setMenuPanel
(
this
.
bookletLayout
);
this
.
menuLayout
.
setContentPanel
(
formulaPanel
);
formulaTabPanel
.
$element
.
append
(
this
.
menuLayout
.
$element
);
optionsTabPanel
.
$element
.
append
(
displayField
.
$element
,
idField
.
$element
,
qidField
.
$element
);
this
.
$body
.
addClass
(
've-ui-mwLatexDialog-content'
)
.
append
(
this
.
indexLayout
.
$element
);
}
);
};
/**
* @inheritdoc
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
getSetupProcess
=
function
(
data
)
{
return
ve
.
ui
.
MWLatexDialog
.
super
.
prototype
.
getSetupProcess
.
call
(
this
,
data
)
.
next
(
()
=>
{
const
attributes
=
this
.
selectedNode
&&
this
.
selectedNode
.
getAttribute
(
'mw'
).
attrs
,
display
=
attributes
&&
attributes
.
display
||
'default'
,
id
=
attributes
&&
attributes
.
id
||
''
,
qid
=
attributes
&&
attributes
.
qid
||
''
,
isReadOnly
=
this
.
isReadOnly
();
// Populate form
// TODO: This widget is not readable when disabled
this
.
displaySelect
.
selectItemByData
(
display
).
setDisabled
(
isReadOnly
);
this
.
idInput
.
setValue
(
id
).
setReadOnly
(
isReadOnly
);
this
.
qidInput
.
setValue
(
qid
).
setReadOnly
(
isReadOnly
);
// Add event handlers
this
.
input
.
on
(
'change'
,
this
.
onChangeHandler
);
this
.
displaySelect
.
on
(
'choose'
,
this
.
onChangeHandler
);
this
.
idInput
.
on
(
'change'
,
this
.
onChangeHandler
);
this
.
qidInput
.
on
(
'change'
,
this
.
onChangeHandler
);
}
);
};
/**
* @inheritdoc
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
getReadyProcess
=
function
(
data
)
{
mw
.
hook
(
've.ui.MwLatexDialogReadyProcess'
).
fire
();
return
ve
.
ui
.
MWLatexDialog
.
super
.
prototype
.
getReadyProcess
.
call
(
this
,
data
)
.
next
(
()
=>
this
.
symbolsPromise
)
.
next
(
()
=>
{
// Resize the input once the dialog has been appended
this
.
input
.
adjustSize
(
true
).
focus
().
moveCursorToEnd
();
this
.
getManager
().
connect
(
this
,
{
resize
:
'onWindowManagerResize'
}
);
this
.
onWindowManagerResize
();
}
);
};
/**
* @inheritdoc
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
getTeardownProcess
=
function
(
data
)
{
return
ve
.
ui
.
MWLatexDialog
.
super
.
prototype
.
getTeardownProcess
.
call
(
this
,
data
)
.
first
(
()
=>
{
this
.
input
.
off
(
'change'
,
this
.
onChangeHandler
);
this
.
displaySelect
.
off
(
'choose'
,
this
.
onChangeHandler
);
this
.
idInput
.
off
(
'change'
,
this
.
onChangeHandler
);
this
.
qidInput
.
off
(
'change'
,
this
.
onChangeHandler
);
this
.
getManager
().
disconnect
(
this
);
this
.
indexLayout
.
setTabPanel
(
'formula'
);
this
.
indexLayout
.
resetScroll
();
this
.
menuLayout
.
resetScroll
();
this
.
bookletLayout
.
resetScroll
();
}
);
};
/**
* @inheritdoc
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
updateMwData
=
function
(
mwData
)
{
// Parent method
ve
.
ui
.
MWLatexDialog
.
super
.
prototype
.
updateMwData
.
call
(
this
,
mwData
);
// Get data from dialog
const
display
=
this
.
displaySelect
.
findSelectedItem
().
getData
();
const
id
=
this
.
idInput
.
getValue
();
const
qid
=
this
.
qidInput
.
getValue
();
// Update attributes
mwData
.
attrs
.
display
=
display
!==
'default'
?
display
:
undefined
;
mwData
.
attrs
.
id
=
id
||
undefined
;
mwData
.
attrs
.
qid
=
qid
||
undefined
;
};
/**
* @inheritdoc
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
getBodyHeight
=
function
()
{
return
600
;
};
/**
* Handle the window resize event
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
onWindowManagerResize
=
function
()
{
this
.
input
.
loadingPromise
.
always
(
()
=>
{
// Toggle short mode as necessary
// NB a change of mode triggers a transition...
this
.
menuLayout
.
$element
.
toggleClass
(
've-ui-mwLatexDialog-menuLayout-short'
,
this
.
menuLayout
.
$element
.
height
()
<
450
);
// ...So wait for the possible menuLayout transition to finish
setTimeout
(
()
=>
{
// Give the input the right number of rows to fit the space
const
availableSpace
=
this
.
menuLayout
.
$content
.
height
()
-
this
.
input
.
$element
.
position
().
top
;
// TODO: Compute this line height from the skin
const
singleLineHeight
=
21
;
const
border
=
1
;
const
padding
=
3
;
const
borderAndPadding
=
2
*
(
border
+
padding
);
const
maxInputHeight
=
availableSpace
-
borderAndPadding
;
const
minRows
=
Math
.
floor
(
maxInputHeight
/
singleLineHeight
);
this
.
input
.
loadingPromise
.
done
(
()
=>
{
this
.
input
.
setMinRows
(
minRows
);
}
).
fail
(
()
=>
{
this
.
input
.
$input
.
attr
(
'rows'
,
minRows
);
}
);
},
OO
.
ui
.
theme
.
getDialogTransitionDuration
()
);
}
);
};
/**
* Handle a symbol being chosen from the list
*
* @param {Object} symbol
*/
ve
.
ui
.
MWLatexDialog
.
prototype
.
onSymbolChoose
=
function
(
symbol
)
{
if
(
this
.
isReadOnly
()
)
{
return
;
}
const
encapsulate
=
symbol
.
encapsulate
;
if
(
encapsulate
)
{
const
range
=
this
.
input
.
getRange
();
if
(
range
.
from
===
range
.
to
)
{
this
.
input
.
insertContent
(
encapsulate
.
placeholder
);
this
.
input
.
selectRange
(
range
.
from
,
range
.
from
+
encapsulate
.
placeholder
.
length
);
}
this
.
input
.
encapsulateContent
(
encapsulate
.
pre
,
encapsulate
.
post
);
}
else
{
const
insert
=
symbol
.
insert
;
this
.
input
.
insertContent
(
insert
);
}
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, May 16, 12:08 (16 h, 59 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
b1/d9/0051f2925e4868ebea5912097af9
Default Alt Text
ve.ui.MWLatexDialog.js (10 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment