Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Kevin Morris
aurweb
Commits
96bc86d1
Commit
96bc86d1
authored
Jun 29, 2021
by
Kevin Morris
Browse files
Merge branch 'typeahead'
parents
c8d88464
42bd0027
Changes
7
Hide whitespace changes
Inline
Side-by-side
web/html/home.php
View file @
96bc86d1
...
...
@@ -185,7 +185,7 @@ if (isset($_COOKIE["AURSID"])) {
<fieldset>
<label
for=
"pkgsearch-field"
>
<?=
__
(
'Package Search'
)
?>
:
</label>
<input
type=
"hidden"
name=
"O"
value=
"0"
/>
<input
id=
"pkgsearch-field"
type=
"text"
name=
"K"
size=
"30"
value=
"
<?php
if
(
isset
(
$_REQUEST
[
"K"
]))
{
print
stripslashes
(
trim
(
htmlspecialchars
(
$_REQUEST
[
"K"
],
ENT_QUOTES
)));
}
?>
"
maxlength=
"35"
/>
<input
id=
"pkgsearch-field"
type=
"text"
name=
"K"
size=
"30"
value=
"
<?php
if
(
isset
(
$_REQUEST
[
"K"
]))
{
print
stripslashes
(
trim
(
htmlspecialchars
(
$_REQUEST
[
"K"
],
ENT_QUOTES
)));
}
?>
"
maxlength=
"35"
autocomplete=
"off"
/>
</fieldset>
</form>
</div>
...
...
@@ -202,34 +202,13 @@ if (isset($_COOKIE["AURSID"])) {
<?php
endif
;
?>
</div>
<script
type=
"text/javascript"
src=
"https://cdn.jsdelivr.net/npm/jquery@1.9.1/jquery.min.js"
></script>
<script
type=
"text/javascript"
src=
"/js/bootstrap-typeahead.min.js"
></script>
<script
type=
"text/javascript"
>
$
(
document
).
ready
(
function
()
{
$
(
'
#pkgsearch-field
'
).
typeahead
({
source
:
function
(
query
,
callback
)
{
$
.
getJSON
(
'
<?=
get_uri
(
'/rpc'
);
?>
'
,
{
type
:
"
suggest
"
,
arg
:
query
},
function
(
data
)
{
callback
(
data
);
});
},
matcher
:
function
(
item
)
{
return
true
;
},
sorter
:
function
(
items
)
{
return
items
;
},
menu
:
'
<ul class="pkgsearch-typeahead"></ul>
'
,
items
:
20
,
updater
:
function
(
item
)
{
document
.
location
=
'
/packages/
'
+
item
;
return
item
;
}
}).
attr
(
'
autocomplete
'
,
'
off
'
);
$
(
'
#pkgsearch-field
'
).
keydown
(
function
(
e
)
{
if
(
e
.
keyCode
==
13
)
{
var
selectedItem
=
$
(
'
ul.pkgsearch-typeahead li.active
'
);
if
(
selectedItem
.
length
==
0
)
{
$
(
'
#pkgsearch-form
'
).
submit
();
}
}
});
<script
type=
"text/javascript"
src=
"/js/typeahead.js"
></script>
<script>
document
.
addEventListener
(
'
DOMContentLoaded
'
,
function
()
{
const
input
=
document
.
getElementById
(
'
pkgsearch-field
'
);
const
form
=
document
.
getElementById
(
'
pkgsearch-form
'
);
const
type
=
"
suggest
"
;
typeahead
.
init
(
type
,
input
,
form
);
});
</script>
<?php
...
...
web/html/index.php
View file @
96bc86d1
...
...
@@ -184,7 +184,7 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) {
header
(
"Content-Type: image/svg+xml"
);
readfile
(
"./
$path
"
);
break
;
case
"/js/
bootstrap-
typeahead.
min.
js"
:
case
"/js/typeahead.js"
:
header
(
"Content-Type: application/javascript"
);
readfile
(
"./
$path
"
);
break
;
...
...
web/html/js/bootstrap-typeahead.min.js
deleted
100644 → 0
View file @
c8d88464
!
function
(
e
){
"
use strict
"
;
var
t
=
function
(
t
,
n
){
this
.
$element
=
e
(
t
),
this
.
options
=
e
.
extend
({},
e
.
fn
.
typeahead
.
defaults
,
n
),
this
.
matcher
=
this
.
options
.
matcher
||
this
.
matcher
,
this
.
sorter
=
this
.
options
.
sorter
||
this
.
sorter
,
this
.
highlighter
=
this
.
options
.
highlighter
||
this
.
highlighter
,
this
.
updater
=
this
.
options
.
updater
||
this
.
updater
,
this
.
$menu
=
e
(
this
.
options
.
menu
).
appendTo
(
"
body
"
),
this
.
source
=
this
.
options
.
source
,
this
.
shown
=!
1
,
this
.
listen
()};
t
.
prototype
=
{
constructor
:
t
,
select
:
function
(){
var
e
=
this
.
$menu
.
find
(
"
.active
"
).
attr
(
"
data-value
"
);
return
e
&&
this
.
$element
.
val
(
this
.
updater
(
e
)).
change
(),
this
.
hide
()},
updater
:
function
(
e
){
return
e
},
show
:
function
(){
var
t
=
e
.
extend
({},
this
.
$element
.
offset
(),{
height
:
this
.
$element
[
0
].
offsetHeight
});
return
this
.
$menu
.
css
({
top
:
t
.
top
+
t
.
height
,
left
:
t
.
left
}),
this
.
$menu
.
show
(),
this
.
shown
=!
0
,
this
},
hide
:
function
(){
return
this
.
$menu
.
hide
(),
this
.
shown
=!
1
,
this
},
lookup
:
function
(
t
){
var
n
;
return
this
.
query
=
this
.
$element
.
val
(),
!
this
.
query
||
this
.
query
.
length
<
this
.
options
.
minLength
?
this
.
shown
?
this
.
hide
():
this
:(
n
=
e
.
isFunction
(
this
.
source
)?
this
.
source
(
this
.
query
,
e
.
proxy
(
this
.
process
,
this
)):
this
.
source
,
n
?
this
.
process
(
n
):
this
)},
process
:
function
(
t
){
var
n
=
this
;
return
t
=
e
.
grep
(
t
,
function
(
e
){
return
n
.
matcher
(
e
)}),
t
=
this
.
sorter
(
t
),
t
.
length
?
this
.
render
(
t
.
slice
(
0
,
this
.
options
.
items
)).
show
():
this
.
shown
?
this
.
hide
():
this
},
matcher
:
function
(
e
){
return
~
e
.
toLowerCase
().
indexOf
(
this
.
query
.
toLowerCase
())},
sorter
:
function
(
e
){
var
t
=
[],
n
=
[],
r
=
[],
i
;
while
(
i
=
e
.
shift
())
i
.
toLowerCase
().
indexOf
(
this
.
query
.
toLowerCase
())?
~
i
.
indexOf
(
this
.
query
)?
n
.
push
(
i
):
r
.
push
(
i
):
t
.
push
(
i
);
return
t
.
concat
(
n
,
r
)},
highlighter
:
function
(
e
){
var
t
=
this
.
query
.
replace
(
/
[\-\[\]
{}()*+?.,
\\\^
$|#
\s]
/g
,
"
\\
$&
"
);
return
e
.
replace
(
new
RegExp
(
"
(
"
+
t
+
"
)
"
,
"
ig
"
),
function
(
e
,
t
){
return
"
<strong>
"
+
t
+
"
</strong>
"
})},
render
:
function
(
t
){
var
n
=
this
;
return
t
=
e
(
t
).
map
(
function
(
t
,
r
){
return
t
=
e
(
n
.
options
.
item
).
attr
(
"
data-value
"
,
r
),
t
.
find
(
"
a
"
).
html
(
n
.
highlighter
(
r
)),
t
[
0
]}),
this
.
$menu
.
html
(
t
),
this
},
next
:
function
(
t
){
var
n
=
this
.
$menu
.
find
(
"
.active
"
).
removeClass
(
"
active
"
),
r
=
n
.
next
();
r
.
length
||
(
r
=
e
(
this
.
$menu
.
find
(
"
li
"
)[
0
])),
r
.
addClass
(
"
active
"
)},
prev
:
function
(
e
){
var
t
=
this
.
$menu
.
find
(
"
.active
"
).
removeClass
(
"
active
"
),
n
=
t
.
prev
();
n
.
length
||
(
n
=
this
.
$menu
.
find
(
"
li
"
).
last
()),
n
.
addClass
(
"
active
"
)},
listen
:
function
(){
this
.
$element
.
on
(
"
blur
"
,
e
.
proxy
(
this
.
blur
,
this
)).
on
(
"
keypress
"
,
e
.
proxy
(
this
.
keypress
,
this
)).
on
(
"
keyup
"
,
e
.
proxy
(
this
.
keyup
,
this
)),(
e
.
browser
.
chrome
||
e
.
browser
.
webkit
||
e
.
browser
.
msie
)
&&
this
.
$element
.
on
(
"
keydown
"
,
e
.
proxy
(
this
.
keydown
,
this
)),
this
.
$menu
.
on
(
"
click
"
,
e
.
proxy
(
this
.
click
,
this
)).
on
(
"
mouseenter
"
,
"
li
"
,
e
.
proxy
(
this
.
mouseenter
,
this
))},
move
:
function
(
e
){
if
(
!
this
.
shown
)
return
;
switch
(
e
.
keyCode
){
case
9
:
case
13
:
case
27
:
e
.
preventDefault
();
break
;
case
38
:
e
.
preventDefault
(),
this
.
prev
();
break
;
case
40
:
e
.
preventDefault
(),
this
.
next
()}
e
.
stopPropagation
()},
keydown
:
function
(
t
){
this
.
suppressKeyPressRepeat
=!~
e
.
inArray
(
t
.
keyCode
,[
40
,
38
,
9
,
13
,
27
]),
this
.
move
(
t
)},
keypress
:
function
(
e
){
if
(
this
.
suppressKeyPressRepeat
)
return
;
this
.
move
(
e
)},
keyup
:
function
(
e
){
switch
(
e
.
keyCode
){
case
40
:
case
38
:
break
;
case
9
:
case
13
:
if
(
!
this
.
shown
)
return
;
this
.
select
();
break
;
case
27
:
if
(
!
this
.
shown
)
return
;
this
.
hide
();
break
;
default
:
this
.
lookup
()}
e
.
stopPropagation
(),
e
.
preventDefault
()},
blur
:
function
(
e
){
var
t
=
this
;
setTimeout
(
function
(){
t
.
hide
()},
150
)},
click
:
function
(
e
){
e
.
stopPropagation
(),
e
.
preventDefault
(),
this
.
select
()},
mouseenter
:
function
(
t
){
this
.
$menu
.
find
(
"
.active
"
).
removeClass
(
"
active
"
),
e
(
t
.
currentTarget
).
addClass
(
"
active
"
)}},
e
.
fn
.
typeahead
=
function
(
n
){
return
this
.
each
(
function
(){
var
r
=
e
(
this
),
i
=
r
.
data
(
"
typeahead
"
),
s
=
typeof
n
==
"
object
"
&&
n
;
i
||
r
.
data
(
"
typeahead
"
,
i
=
new
t
(
this
,
s
)),
typeof
n
==
"
string
"
&&
i
[
n
]()})},
e
.
fn
.
typeahead
.
defaults
=
{
source
:[],
items
:
8
,
menu
:
'
<ul class="typeahead dropdown-menu"></ul>
'
,
item
:
'
<li><a href="#"></a></li>
'
,
minLength
:
1
},
e
.
fn
.
typeahead
.
Constructor
=
t
,
e
(
function
(){
e
(
"
body
"
).
on
(
"
focus.typeahead.data-api
"
,
'
[data-provide="typeahead"]
'
,
function
(
t
){
var
n
=
e
(
this
);
if
(
n
.
data
(
"
typeahead
"
))
return
;
t
.
preventDefault
(),
n
.
typeahead
(
n
.
data
())})})}(
window
.
jQuery
)
\ No newline at end of file
web/html/js/typeahead.js
0 → 100644
View file @
96bc86d1
"
use strict
"
;
const
typeahead
=
(
function
()
{
var
input
;
var
form
;
var
suggest_type
;
var
list
;
var
submit
=
true
;
function
resetResults
()
{
if
(
!
list
)
return
;
list
.
style
.
display
=
"
none
"
;
list
.
innerHTML
=
""
;
}
function
getCompleteList
()
{
if
(
!
list
)
{
list
=
document
.
createElement
(
"
UL
"
);
list
.
setAttribute
(
"
class
"
,
"
pkgsearch-typeahead
"
);
form
.
appendChild
(
list
);
setListLocation
();
}
return
list
;
}
function
onListClick
(
e
)
{
let
target
=
e
.
target
;
while
(
!
target
.
getAttribute
(
'
data-value
'
))
{
target
=
target
.
parentNode
;
}
input
.
value
=
target
.
getAttribute
(
'
data-value
'
);
if
(
submit
)
{
form
.
submit
();
}
}
function
setListLocation
()
{
if
(
!
list
)
return
;
const
rects
=
input
.
getClientRects
()[
0
];
list
.
style
.
top
=
(
rects
.
top
+
rects
.
height
)
+
"
px
"
;
list
.
style
.
left
=
rects
.
left
+
"
px
"
;
}
function
loadData
(
letter
,
data
)
{
const
pkgs
=
data
.
slice
(
0
,
10
);
// Show maximum of 10 results
resetResults
();
if
(
pkgs
.
length
===
0
)
{
return
;
}
const
ul
=
getCompleteList
();
ul
.
style
.
display
=
"
block
"
;
const
fragment
=
document
.
createDocumentFragment
();
for
(
let
i
=
0
;
i
<
pkgs
.
length
;
i
++
)
{
const
item
=
document
.
createElement
(
"
li
"
);
const
text
=
pkgs
[
i
].
replace
(
letter
,
'
<b>
'
+
letter
+
'
</b>
'
);
item
.
innerHTML
=
'
<a href="#">
'
+
text
+
'
</a>
'
;
item
.
setAttribute
(
'
data-value
'
,
pkgs
[
i
]);
fragment
.
appendChild
(
item
);
}
ul
.
appendChild
(
fragment
);
ul
.
addEventListener
(
'
click
'
,
onListClick
);
}
function
fetchData
(
letter
)
{
const
url
=
'
/rpc?type=
'
+
suggest_type
+
'
&arg=
'
+
letter
;
fetch
(
url
).
then
(
function
(
response
)
{
return
response
.
json
();
}).
then
(
function
(
data
)
{
loadData
(
letter
,
data
);
});
}
function
onInputClick
()
{
if
(
input
.
value
===
""
)
{
resetResults
();
return
;
}
fetchData
(
input
.
value
);
}
function
onKeyDown
(
e
)
{
if
(
!
list
)
return
;
const
elem
=
document
.
querySelector
(
"
.pkgsearch-typeahead li.active
"
);
switch
(
e
.
keyCode
)
{
case
13
:
// enter
if
(
!
submit
)
{
return
;
}
if
(
elem
)
{
input
.
value
=
elem
.
getAttribute
(
'
data-value
'
);
form
.
submit
();
}
else
{
form
.
submit
();
}
e
.
preventDefault
();
break
;
case
38
:
// up
if
(
elem
&&
elem
.
previousElementSibling
)
{
elem
.
className
=
""
;
elem
.
previousElementSibling
.
className
=
"
active
"
;
}
e
.
preventDefault
();
break
;
case
40
:
// down
if
(
elem
&&
elem
.
nextElementSibling
)
{
elem
.
className
=
""
;
elem
.
nextElementSibling
.
className
=
"
active
"
;
}
else
if
(
!
elem
&&
list
.
childElementCount
!==
0
)
{
list
.
children
[
0
].
className
=
"
active
"
;
}
e
.
preventDefault
();
break
;
}
}
// debounce https://davidwalsh.name/javascript-debounce-function
function
debounce
(
func
,
wait
,
immediate
)
{
var
timeout
;
return
function
()
{
var
context
=
this
,
args
=
arguments
;
var
later
=
function
()
{
timeout
=
null
;
if
(
!
immediate
)
func
.
apply
(
context
,
args
);
};
var
callNow
=
immediate
&&
!
timeout
;
clearTimeout
(
timeout
);
timeout
=
setTimeout
(
later
,
wait
);
if
(
callNow
)
func
.
apply
(
context
,
args
);
};
}
return
{
init
:
function
(
type
,
inputfield
,
formfield
,
submitdata
=
true
)
{
suggest_type
=
type
;
input
=
inputfield
;
form
=
formfield
;
submit
=
submitdata
;
input
.
addEventListener
(
"
input
"
,
onInputClick
);
input
.
addEventListener
(
"
keydown
"
,
onKeyDown
);
window
.
addEventListener
(
'
resize
'
,
debounce
(
setListLocation
,
150
));
document
.
addEventListener
(
"
click
"
,
resetResults
);
}
}
}());
web/html/packages.php
View file @
96bc86d1
...
...
@@ -49,6 +49,11 @@ html_header($title, $details);
<script
type=
"text/javascript"
>
function
collapseDependsList
(
list
)
{
list
=
document
.
getElementById
(
list
);
// Packages overview page also triggers collapseDependsList, ideally the Javascript
// is only included for the package details view.
if
(
!
list
)
{
return
;
}
// Hide everything past a given limit. Don't do anything if we don't have
// enough items, or the link already exists.
...
...
web/html/pkgmerge.php
View file @
96bc86d1
...
...
@@ -25,7 +25,7 @@ if (has_credential(CRED_PKGBASE_DELETE)): ?>
<?=
__
(
'Enter the package name you wish to merge the package into. '
);
?>
<?=
__
(
'Select the checkbox to confirm action.'
)
?>
</p>
<form
action=
"
<?=
get_pkgbase_uri
(
$pkgbase_name
);
?>
"
method=
"post"
>
<form
id=
"merge-form"
action=
"
<?=
get_pkgbase_uri
(
$pkgbase_name
);
?>
"
method=
"post"
>
<fieldset>
<input
type=
"hidden"
name=
"IDs[
<?=
$base_id
?>
]"
value=
"1"
/>
<input
type=
"hidden"
name=
"ID"
value=
"
<?=
$base_id
?>
"
/>
...
...
@@ -33,25 +33,17 @@ if (has_credential(CRED_PKGBASE_DELETE)): ?>
<?php
if
(
isset
(
$_GET
[
'via'
]))
:
?>
<input
type=
"hidden"
name=
"via"
value=
"
<?=
intval
(
$_GET
[
'via'
])
?>
"
/>
<?php
endif
;
?>
<script
type=
"text/javascript"
src=
"https://cdn.jsdelivr.net/npm/jquery@1.9.1/jquery.min.js"
></script>
<script
type=
"text/javascript"
src=
"/js/bootstrap-typeahead.min.js"
></script>
<script
type=
"text/javascript"
src=
"/js/typeahead.js"
></script>
<script
type=
"text/javascript"
>
$
(
document
).
ready
(
function
()
{
$
(
'
#merge_Into
'
).
typeahead
({
source
:
function
(
query
,
callback
)
{
$
.
getJSON
(
'
<?=
get_uri
(
'/rpc'
);
?>
'
,
{
type
:
"
suggest-pkgbase
"
,
arg
:
query
},
function
(
data
)
{
callback
(
data
);
});
},
matcher
:
function
(
item
)
{
return
true
;
},
sorter
:
function
(
items
)
{
return
items
;
},
menu
:
'
<ul class="pkgsearch-typeahead"></ul>
'
,
items
:
20
}).
attr
(
'
autocomplete
'
,
'
off
'
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
function
()
{
const
input
=
document
.
getElementById
(
'
merge_Into
'
);
const
form
=
document
.
getElementById
(
'
merge-form
'
);
const
type
=
"
suggest-pkgbase
"
;
typeahead
.
init
(
type
,
input
,
form
,
false
);
});
</script>
<p><label
id=
"merge-into"
for=
"merge_Into"
>
<?=
__
(
"Merge into:"
)
?>
</label>
<input
type=
"text"
id=
"merge_Into"
name=
"merge_Into"
value=
"
<?=
isset
(
$_GET
[
'into'
])
?
$_GET
[
'into'
]
:
''
?>
"
/></p>
<input
type=
"text"
id=
"merge_Into"
name=
"merge_Into"
value=
"
<?=
isset
(
$_GET
[
'into'
])
?
$_GET
[
'into'
]
:
''
?>
"
autocomplete=
"off"
/></p>
<p><label
class=
"confirmation"
><input
type=
"checkbox"
name=
"confirm"
value=
"1"
/>
<?=
__
(
"Confirm package merge"
)
?>
</label></p>
<p><input
type=
"submit"
class=
"button"
name=
"do_Delete"
value=
"
<?=
__
(
"Merge"
)
?>
"
/></p>
...
...
web/template/pkgreq_form.php
View file @
96bc86d1
...
...
@@ -9,7 +9,7 @@
<li>
<?=
htmlspecialchars
(
$pkgname
)
?>
</li>
<?php
endforeach
;
?>
</ul>
<form
action=
"
<?=
get_uri
(
'/pkgbase/'
);
?>
"
method=
"post"
>
<form
action=
"
<?=
get_uri
(
'/pkgbase/'
);
?>
"
id=
"request-form"
method=
"post"
>
<fieldset>
<input
type=
"hidden"
name=
"IDs[
<?=
$base_id
?>
]"
value=
"1"
/>
<input
type=
"hidden"
name=
"ID"
value=
"
<?=
$base_id
?>
"
/>
...
...
@@ -24,44 +24,41 @@
<?php
endif
;
?>
</select>
</p>
<script
type=
"text/javascript"
src=
"https://cdn.jsdelivr.net/npm/jquery@1.9.1/jquery.min.js"
></script>
<script
type=
"text/javascript"
src=
"/js/bootstrap-typeahead.min.js"
></script>
<script
type=
"text/javascript"
src=
"/js/typeahead.js"
></script>
<script
type=
"text/javascript"
>
function
showHideMergeSection
()
{
if
(
$
(
'
#id_type
'
).
val
()
==
'
merge
'
)
{
$
(
'
#merge_section
'
).
show
();
const
elem
=
document
.
getElementById
(
'
id_type
'
);
const
merge_section
=
document
.
getElementById
(
'
merge_section
'
);
if
(
elem
.
value
==
'
merge
'
)
{
merge_section
.
style
.
display
=
''
;
}
else
{
$
(
'
#
merge_section
'
).
hide
()
;
merge_section
.
style
.
display
=
'
none
'
;
}
}
function
showHideRequestHints
()
{
$
(
'
#deletion_hint
'
).
hide
();
$
(
'
#merge_hint
'
).
hide
();
$
(
'
#orphan_hint
'
).
hide
();
$
(
'
#
'
+
$
(
'
#id_type
'
).
val
()
+
'
_hint
'
).
show
();
document
.
getElementById
(
'
deletion_hint
'
).
style
.
display
=
'
none
'
;
document
.
getElementById
(
'
merge_hint
'
).
style
.
display
=
'
none
'
;
document
.
getElementById
(
'
orphan_hint
'
).
style
.
display
=
'
none
'
;
const
elem
=
document
.
getElementById
(
'
id_type
'
);
document
.
getElementById
(
elem
.
value
+
'
_hint
'
).
style
.
display
=
''
;
}
$
(
document
).
ready
(
function
()
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
function
()
{
showHideMergeSection
();
showHideRequestHints
();
$
(
'
#id_merge_into
'
).
typeahead
({
source
:
function
(
query
,
callback
)
{
$
.
getJSON
(
'
<?=
get_uri
(
'/rpc'
);
?>
'
,
{
type
:
"
suggest-pkgbase
"
,
arg
:
query
},
function
(
data
)
{
callback
(
data
);
});
},
matcher
:
function
(
item
)
{
return
true
;
},
sorter
:
function
(
items
)
{
return
items
;
},
menu
:
'
<ul class="pkgsearch-typeahead"></ul>
'
,
items
:
20
}).
attr
(
'
autocomplete
'
,
'
off
'
);
const
input
=
document
.
getElementById
(
'
id_merge_into
'
);
const
form
=
document
.
getElementById
(
'
request-form
'
);
const
type
=
"
suggest-pkgbase
"
;
typeahead
.
init
(
type
,
input
,
form
,
false
);
});
</script>
<p
id=
"merge_section"
>
<label
for=
"id_merge_into"
>
<?=
__
(
"Merge into"
)
?>
:
</label>
<input
type=
"text"
name=
"merge_into"
id=
"id_merge_into"
/>
<input
type=
"text"
name=
"merge_into"
id=
"id_merge_into"
autocomplete=
"off"
/>
</p>
<p>
<label
for=
"id_comments"
>
<?=
__
(
"Comments"
)
?>
:
</label>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment