handling further JSHint warnings and TODOs
This commit is contained in:
parent
98d07e0789
commit
ffae6111b0
18
js/common.js
18
js/common.js
@ -109,45 +109,45 @@ exports.htmlEntities = function(str) {
|
||||
/[&<>"'`=\/]/g, function(s) {
|
||||
return entityMap[s];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// provides random lowercase characters from a to z
|
||||
exports.jscA2zString = function() {
|
||||
return jsc.elements(a2zString);
|
||||
}
|
||||
};
|
||||
|
||||
// provides random lowercase alpha numeric characters (a to z and 0 to 9)
|
||||
exports.jscAlnumString = function() {
|
||||
return jsc.elements(alnumString);
|
||||
}
|
||||
};
|
||||
|
||||
// provides random characters allowed in GET queries
|
||||
exports.jscQueryString = function() {
|
||||
return jsc.elements(queryString);
|
||||
}
|
||||
};
|
||||
|
||||
// provides random characters allowed in base64 encoded strings
|
||||
exports.jscBase64String = function() {
|
||||
return jsc.elements(base64String);
|
||||
}
|
||||
};
|
||||
|
||||
// provides a random URL schema supported by the whatwg-url library
|
||||
exports.jscSchemas = function() {
|
||||
return jsc.elements(schemas);
|
||||
}
|
||||
};
|
||||
|
||||
// provides a random supported language string
|
||||
exports.jscSupportedLanguages = function() {
|
||||
return jsc.elements(supportedLanguages);
|
||||
}
|
||||
};
|
||||
|
||||
// provides a random mime type
|
||||
exports.jscMimeTypes = function() {
|
||||
return jsc.elements(mimeTypes);
|
||||
}
|
||||
};
|
||||
|
||||
// provides a random PrivateBin paste formatter
|
||||
exports.jscFormats = function() {
|
||||
return jsc.elements(formats);
|
||||
}
|
||||
};
|
||||
|
||||
|
109
js/privatebin.js
109
js/privatebin.js
@ -557,7 +557,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @param {string} key
|
||||
* @param {string} password
|
||||
* @param {string} data - JSON with encrypted data
|
||||
* @return {string} decrypted message
|
||||
* @return {string} decrypted message, empty if decryption failed
|
||||
*/
|
||||
me.decipher = function(key, password, data)
|
||||
{
|
||||
@ -568,11 +568,10 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
try {
|
||||
return decompress(sjcl.decrypt(key + sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash(password)), data));
|
||||
} catch(e) {
|
||||
// ignore error, because ????? @TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -634,7 +633,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @name Model.getExpirationDefault
|
||||
* @function
|
||||
* @return string
|
||||
* @TODO the template can be simplified as #pasteExpiration is no longer modified (only default value)
|
||||
*/
|
||||
me.getExpirationDefault = function()
|
||||
{
|
||||
@ -647,7 +645,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @name Model.getFormatDefault
|
||||
* @function
|
||||
* @return string
|
||||
* @TODO the template can be simplified as #pasteFormatter is no longer modified (only default value)
|
||||
*/
|
||||
me.getFormatDefault = function()
|
||||
{
|
||||
@ -1026,18 +1023,10 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @param {string|array} message string, use an array for %s/%d options
|
||||
* @param {string|null} icon optional, the icon to show,
|
||||
* default: leave previous icon
|
||||
* @param {bool} dismissable optional, whether the notification
|
||||
* can be dismissed (closed), default: false
|
||||
* @param {bool|int} autoclose optional, after how many seconds the
|
||||
* notification should be hidden automatically;
|
||||
* default: disabled (0); use true for default value
|
||||
*/
|
||||
me.showStatus = function(message, icon, dismissable, autoclose)
|
||||
me.showStatus = function(message, icon)
|
||||
{
|
||||
console.info('status shown: ', message);
|
||||
// @TODO: implement dismissable
|
||||
// @TODO: implement autoclose
|
||||
|
||||
handleNotification(1, $statusMessage, message, icon);
|
||||
};
|
||||
|
||||
@ -1051,18 +1040,10 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @param {string|array} message string, use an array for %s/%d options
|
||||
* @param {string|null} icon optional, the icon to show, default:
|
||||
* leave previous icon
|
||||
* @param {bool} dismissable optional, whether the notification
|
||||
* can be dismissed (closed), default: false
|
||||
* @param {bool|int} autoclose optional, after how many seconds the
|
||||
* notification should be hidden automatically;
|
||||
* default: disabled (0); use true for default value
|
||||
*/
|
||||
me.showError = function(message, icon, dismissable, autoclose)
|
||||
me.showError = function(message, icon)
|
||||
{
|
||||
console.error('error message shown: ', message);
|
||||
// @TODO: implement dismissable (bootstrap add-on has it)
|
||||
// @TODO: implement autoclose
|
||||
|
||||
handleNotification(3, $errorMessage, message, icon);
|
||||
};
|
||||
|
||||
@ -1089,10 +1070,9 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @name Alert.showLoading
|
||||
* @function
|
||||
* @param {string|array|null} message optional, use an array for %s/%d options, default: 'Loading…'
|
||||
* @param {int} percentage optional, default: null
|
||||
* @param {string|null} icon optional, the icon to show, default: leave previous icon
|
||||
*/
|
||||
me.showLoading = function(message, percentage, icon)
|
||||
me.showLoading = function(message, icon)
|
||||
{
|
||||
if (typeof message !== 'undefined' && message !== null) {
|
||||
console.info('status changed: ', message);
|
||||
@ -1103,9 +1083,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
message = 'Loading…';
|
||||
}
|
||||
|
||||
// currently percentage parameter is ignored
|
||||
// // @TODO handle it here…
|
||||
|
||||
handleNotification(0, $loadingIndicator, message, icon);
|
||||
|
||||
// show loading status (cursor)
|
||||
@ -1214,9 +1191,8 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @name PasteStatus.sendToShortener
|
||||
* @private
|
||||
* @function
|
||||
* @param {Event} event
|
||||
*/
|
||||
function sendToShortener(event)
|
||||
function sendToShortener()
|
||||
{
|
||||
window.location.href = $shortenButton.data('shortener')
|
||||
+ encodeURIComponent($pasteUrl.attr('href'));
|
||||
@ -1230,9 +1206,8 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
*
|
||||
* @name PasteStatus.pasteLinkClick
|
||||
* @function
|
||||
* @param {Event} event
|
||||
*/
|
||||
function pasteLinkClick(event)
|
||||
function pasteLinkClick()
|
||||
{
|
||||
// check if location is (already) shown in URL bar
|
||||
if (window.location.href === $pasteUrl.attr('href')) {
|
||||
@ -2161,12 +2136,9 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @name DiscussionViewer.handleNotification
|
||||
* @function
|
||||
* @param {string} alertType
|
||||
* @param {jQuery} $element
|
||||
* @param {string|array} args
|
||||
* @param {string|null} icon
|
||||
* @return {bool|jQuery}
|
||||
*/
|
||||
me.handleNotification = function(alertType, $element, args, icon)
|
||||
me.handleNotification = function(alertType)
|
||||
{
|
||||
// ignore loading messages
|
||||
if (alertType === 'loading') {
|
||||
@ -2501,12 +2473,11 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @name TopNav.rawText
|
||||
* @private
|
||||
* @function
|
||||
* @param {Event} event
|
||||
*/
|
||||
function rawText(event)
|
||||
function rawText()
|
||||
{
|
||||
TopNav.hideAllButtons();
|
||||
Alert.showLoading('Showing raw text…', 0, 'time');
|
||||
Alert.showLoading('Showing raw text…', 'time');
|
||||
var paste = PasteViewer.getText();
|
||||
|
||||
// push a new state to allow back navigation with browser back button
|
||||
@ -2550,9 +2521,8 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
* @name TopNav.clickNewPaste
|
||||
* @private
|
||||
* @function
|
||||
* @param {Event} event
|
||||
*/
|
||||
function clickNewPaste(event)
|
||||
function clickNewPaste()
|
||||
{
|
||||
Controller.hideStatusMessages();
|
||||
Controller.newPaste();
|
||||
@ -2587,9 +2557,8 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
*
|
||||
* @name TopNav.displayQrCode
|
||||
* @function
|
||||
* @param {Event} event
|
||||
*/
|
||||
function displayQrCode(event)
|
||||
function displayQrCode()
|
||||
{
|
||||
var qrCanvas = kjua({
|
||||
render: 'canvas',
|
||||
@ -2802,7 +2771,8 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
if (!$file.length || !$file[0].files.length) {
|
||||
return null;
|
||||
}
|
||||
// @TODO is this really necessary
|
||||
|
||||
// ensure the selected file is still accessible
|
||||
if (!($file[0].files && $file[0].files[0])) {
|
||||
return null;
|
||||
}
|
||||
@ -3309,7 +3279,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
*/
|
||||
function showUploadedComment(status, data) {
|
||||
// show success message
|
||||
// Alert.showStatus('Comment posted.');
|
||||
Alert.showStatus('Comment posted.');
|
||||
|
||||
// reload paste
|
||||
Controller.refreshPaste(function () {
|
||||
@ -3347,7 +3317,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
|
||||
// run callback
|
||||
return callback();
|
||||
}
|
||||
};
|
||||
|
||||
// actually read first file
|
||||
reader.readAsDataURL(file);
|
||||
@ -3377,7 +3347,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
|
||||
// UI loading state
|
||||
TopNav.hideAllButtons();
|
||||
Alert.showLoading('Sending comment…', 0, 'cloud-upload');
|
||||
Alert.showLoading('Sending comment…', 'cloud-upload');
|
||||
|
||||
// get data
|
||||
var plainText = DiscussionViewer.getReplyMessage(),
|
||||
@ -3399,7 +3369,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
})) {
|
||||
return; // to prevent multiple executions
|
||||
}
|
||||
Alert.showLoading(null, 10);
|
||||
|
||||
// prepare Uploader
|
||||
Uploader.prepare();
|
||||
@ -3413,7 +3382,9 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
TopNav.showViewButtons();
|
||||
|
||||
// show error message
|
||||
Alert.showError(Uploader.parseUploadError(status, data, 'post comment'));
|
||||
Alert.showError(
|
||||
Uploader.parseUploadError(status, data, 'post comment')
|
||||
);
|
||||
|
||||
// reset error handler
|
||||
Alert.setCustomHandler(null);
|
||||
@ -3423,7 +3394,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
Uploader.setUnencryptedData('pasteid', Model.getPasteId());
|
||||
if (typeof parentid === 'undefined') {
|
||||
// if parent id is not set, this is the top-most comment, so use
|
||||
// paste id as parent @TODO is this really good?
|
||||
// paste id as parent, as the root element of the discussion tree
|
||||
Uploader.setUnencryptedData('parentid', Model.getPasteId());
|
||||
} else {
|
||||
Uploader.setUnencryptedData('parentid', parentid);
|
||||
@ -3452,7 +3423,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
|
||||
// UI loading state
|
||||
TopNav.hideAllButtons();
|
||||
Alert.showLoading('Sending paste…', 0, 'cloud-upload');
|
||||
Alert.showLoading('Sending paste…', 'cloud-upload');
|
||||
TopNav.collapseBar();
|
||||
|
||||
// get data
|
||||
@ -3468,8 +3439,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
return;
|
||||
}
|
||||
|
||||
Alert.showLoading(null, 10);
|
||||
|
||||
// check entropy
|
||||
if (!checkRequirements(function () {
|
||||
me.sendPaste();
|
||||
@ -3489,7 +3458,9 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
TopNav.showCreateButtons();
|
||||
|
||||
// show error message
|
||||
Alert.showError(Uploader.parseUploadError(status, data, 'create paste'));
|
||||
Alert.showError(
|
||||
Uploader.parseUploadError(status, data, 'create paste')
|
||||
);
|
||||
});
|
||||
|
||||
// fill it with unencrypted submitted options
|
||||
@ -3706,7 +3677,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
me.run = function(paste)
|
||||
{
|
||||
Alert.hideMessages();
|
||||
Alert.showLoading('Decrypting paste…', 0, 'cloud-download'); // @TODO icon maybe rotation-lock, but needs full Glyphicons
|
||||
Alert.showLoading('Decrypting paste…', 'cloud-download');
|
||||
|
||||
if (typeof paste === 'undefined') {
|
||||
paste = $.parseJSON(Model.getCipherData());
|
||||
@ -3716,7 +3687,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
password = Prompt.getPassword();
|
||||
|
||||
if (PasteViewer.isPrettyPrinted()) {
|
||||
console.error('Too pretty! (don\'t know why this check)'); //@TODO
|
||||
// don't decrypt twice
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3803,7 +3774,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
// Important: This *must not* run Alert.hideMessages() as previous
|
||||
// errors from viewing a paste should be shown.
|
||||
TopNav.hideAllButtons();
|
||||
Alert.showLoading('Preparing new paste…', 0, 'time');
|
||||
Alert.showLoading('Preparing new paste…', 'time');
|
||||
|
||||
PasteStatus.hideMessages();
|
||||
PasteViewer.hide();
|
||||
@ -3832,7 +3803,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
// missing decryption key (or paste ID) in URL?
|
||||
if (window.location.hash.length === 0) {
|
||||
Alert.showError('Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)');
|
||||
// @TODO adjust error message as it is less specific now, probably include thrown exception for a detailed error
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3862,7 +3832,9 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
TopNav.showViewButtons();
|
||||
|
||||
// show error message
|
||||
Alert.showError(Uploader.parseUploadError(status, data, 'refresh display'));
|
||||
Alert.showError(
|
||||
Uploader.parseUploadError(status, data, 'refresh display')
|
||||
);
|
||||
});
|
||||
Uploader.setSuccess(function (status, data) {
|
||||
PasteDecrypter.run(data);
|
||||
@ -3880,13 +3852,12 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
*
|
||||
* @name Controller.clonePaste
|
||||
* @function
|
||||
* @param {Event} event
|
||||
*/
|
||||
me.clonePaste = function(event)
|
||||
me.clonePaste = function()
|
||||
{
|
||||
TopNav.collapseBar();
|
||||
TopNav.hideAllButtons();
|
||||
Alert.showLoading('Cloning paste…', 0, 'transfer');
|
||||
Alert.showLoading('Cloning paste…', 'transfer');
|
||||
|
||||
// hide messages from previous paste
|
||||
me.hideStatusMessages();
|
||||
@ -3912,7 +3883,9 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
[
|
||||
'The cloned file \'%s\' was attached to this paste.',
|
||||
AttachmentViewer.getAttachment()[1]
|
||||
], 'copy', true, true);
|
||||
],
|
||||
'copy'
|
||||
);
|
||||
}
|
||||
|
||||
Editor.setText(PasteViewer.getText());
|
||||
@ -3939,8 +3912,10 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
|
||||
Uploader.setUnencryptedData('deletetoken', deleteToken);
|
||||
|
||||
Uploader.setFailure(function () {
|
||||
Alert.showError(I18n._('Could not delete the paste, it was not stored in burn after reading mode.'));
|
||||
})
|
||||
Alert.showError(
|
||||
I18n._('Could not delete the paste, it was not stored in burn after reading mode.')
|
||||
);
|
||||
});
|
||||
Uploader.run();
|
||||
};
|
||||
|
||||
|
@ -99,10 +99,9 @@ describe('Alert', function () {
|
||||
'shows a loading message',
|
||||
jsc.array(common.jscAlnumString()),
|
||||
jsc.array(common.jscAlnumString()),
|
||||
'integer',
|
||||
function (icon, message, number) {
|
||||
icon = icon.join('');
|
||||
function (message, icon) {
|
||||
message = message.join('');
|
||||
icon = icon.join('');
|
||||
var defaultMessage = 'Loading…';
|
||||
if (message.length === 0) {
|
||||
message = defaultMessage;
|
||||
@ -118,7 +117,7 @@ describe('Alert', function () {
|
||||
defaultMessage + '</li></ul>'
|
||||
);
|
||||
$.PrivateBin.Alert.init();
|
||||
$.PrivateBin.Alert.showLoading(message, number, icon);
|
||||
$.PrivateBin.Alert.showLoading(message, icon);
|
||||
var result = $('body').html();
|
||||
return expected === result;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
require('../common');
|
||||
|
||||
describe('CryptTool', function () {
|
||||
describe('cipher & decipher', function () {
|
||||
@ -180,8 +180,7 @@ describe('CryptTool', function () {
|
||||
// the parameter is used to ensure the test is run more then one time
|
||||
jsc.property(
|
||||
'returns random, non-empty keys',
|
||||
'nat',
|
||||
function(n) {
|
||||
function() {
|
||||
var key = $.PrivateBin.CryptTool.getSymmetricKey(),
|
||||
result = (key !== '' && keys.indexOf(key) === -1);
|
||||
keys.push(key);
|
||||
|
@ -1,5 +1,5 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
require('../common');
|
||||
|
||||
describe('Editor', function () {
|
||||
describe('show, hide, getText, setText & isPreview', function () {
|
||||
|
@ -75,7 +75,7 @@ if ($MARKDOWN):
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-8qxSDsu+97uCV1BQisPlTAyCAX0fl2tQTwoHoI6uxLlaznKyJbJdclGIWuwzCiWsuYJbNJ8HxBXui8sfu8U0Nw==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-kln7CKhJse+R3qsKw01qJ5nLISVhC/S4T/RRetZbNW3uhheH49NBd8NamOaYcXGQ+CRU8OoN1iD7JLX88Jt0Sg==" crossorigin="anonymous"></script>
|
||||
<!--[if lt IE 10]>
|
||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||
<![endif]-->
|
||||
@ -525,7 +525,6 @@ endif;
|
||||
if ($DISCUSSION):
|
||||
?>
|
||||
<div id="templates">
|
||||
<!-- @TODO: when I intend/structure this corrrectly Firefox adds whitespaces everywhere which completly destroy the layout. (same possible when you remove the template data below and show this area in the browser) -->
|
||||
<article id="commenttemplate" class="comment"><div class="commentmeta"><span class="nickname">name</span><span class="commentdate">0000-00-00</span></div><div class="commentdata">c</div><button class="btn btn-default btn-sm"><?php echo I18n::_('Reply'); ?></button></article>
|
||||
<p id="commenttailtemplate" class="comment"><button class="btn btn-default btn-sm"><?php echo I18n::_('Add comment'); ?></button></p>
|
||||
<div id="replytemplate" class="reply hidden"><input type="text" id="nickname" class="form-control" title="<?php echo I18n::_('Optional nickname…'); ?>" placeholder="<?php echo I18n::_('Optional nickname…'); ?>" /><textarea id="replymessage" class="replymessage form-control" cols="80" rows="7"></textarea><br /><div id="replystatus" role="alert" class="statusmessage hidden alert"><span class="glyphicon" aria-hidden="true"></span> </div><button id="replybutton" class="btn btn-default btn-sm"><?php echo I18n::_('Post comment'); ?></button></div>
|
||||
|
@ -54,7 +54,7 @@ if ($QRCODE):
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-8qxSDsu+97uCV1BQisPlTAyCAX0fl2tQTwoHoI6uxLlaznKyJbJdclGIWuwzCiWsuYJbNJ8HxBXui8sfu8U0Nw==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-kln7CKhJse+R3qsKw01qJ5nLISVhC/S4T/RRetZbNW3uhheH49NBd8NamOaYcXGQ+CRU8OoN1iD7JLX88Jt0Sg==" crossorigin="anonymous"></script>
|
||||
<!--[if lt IE 10]>
|
||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||
<![endif]-->
|
||||
@ -252,7 +252,6 @@ endif;
|
||||
if ($DISCUSSION):
|
||||
?>
|
||||
<div id="templates">
|
||||
<!-- @TODO: when I intend/structure this corrrectly Firefox adds whitespaces everywhere which completly destroy the layout. (same possible when you remove the template data below and show this area in the browser) -->
|
||||
<article id="commenttemplate" class="comment"><div class="commentmeta"><span class="nickname">name</span><span class="commentdate">0000-00-00</span></div><div class="commentdata">c</div><button class="btn btn-default btn-sm"><?php echo I18n::_('Reply'); ?></button></article>
|
||||
<div id="commenttailtemplate" class="comment"><button class="btn btn-default btn-sm"><?php echo I18n::_('Add comment'); ?></button></div>
|
||||
<div id="replytemplate" class="reply hidden"><input type="text" id="nickname" class="form-control" title="<?php echo I18n::_('Optional nickname…'); ?>" placeholder="<?php echo I18n::_('Optional nickname…'); ?>" /><textarea id="replymessage" class="replymessage form-control" cols="80" rows="7"></textarea><br /><div id="replystatus" role="alert" class="statusmessage hidden alert"><span class="glyphicon" aria-hidden="true"></span> </div><button id="replybutton" class="btn btn-default btn-sm"><?php echo I18n::_('Post comment'); ?></button></div>
|
||||
|
Loading…
Reference in New Issue
Block a user