Skip to content

Commit

Permalink
Change escaping of edited data, fix width of grid
Browse files Browse the repository at this point in the history
1) `autoencode:true` not follow encoding of edited data by
`$.jgrid.htmlEncode`. It can be bad if one send data via JSON encodding
for example.

2) jqGrid have now new option `autoEncodeOnEdit` (default value `false`)
which can be used to force old behavior. Even if `autoEncodeOnEdit:true`
is used, there are minor differences. The encodding will be done now
directly before sending the data. The validation functions and other
callbacks will see not-encodded data.

3) The new functions `$.jgrid.oldEncodePostedData` and
`$.jgrid.oldDecodePostedData` be used now for encodding the data which
need be posted on editing. The functions `$.jgrid.htmlDecode` and
`$.jgrid.htmlEncode` encode now the characters `'` and `/`.

4) main grid table (`.ui-jqgrid-btable`) and header hable
(`.ui-jqgrid-htable`) have now `width:1px` CSS property, which force
usage of `table-layout: fixed` and fix small problem with differences in
the width of the grid and the table with column header. The problems
were in Google Chrome, in case of zoom factor not equal 100% (or 200%,
...). See [the answer](http://stackoverflow.com/a/33875600/315935) for
more details.

5) Small fixes in `title` which will be set inside of `setRowData`
method.

Thank to [Andrus](http://stackoverflow.com/users/742402/andrus)
([kobruleht](https://github.com/kobruleht)) for helpful discussion about
the above changes, preparing the demos and testing preliminary versions
of suggested changes.
  • Loading branch information
OlegKi committed Nov 23, 2015
1 parent 284c13d commit d31b70f
Show file tree
Hide file tree
Showing 7 changed files with 716 additions and 634 deletions.
49 changes: 37 additions & 12 deletions js/grid.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Dual licensed under the MIT and GPL licenses
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl-2.0.html
* Date: 2015-11-22
* Date: 2015-11-23
*/
//jsHint options
/*jshint evil:true, eqeqeq:false, eqnull:true, devel:true */
Expand Down Expand Up @@ -554,8 +554,10 @@
String(value)
.replace(/>/g, ">")
.replace(/&lt;/g, "<")
//.replace(/&#x27;/g, "'")
//.replace(/&#x2F;/g, "\/")
.replace(/&#x27;/g, "'")
.replace(/&#x2F;/g, "\/")
.replace(/&#39;/g, "'")
.replace(/&#47;/g, "\/")
.replace(/&quot;/g, "\"")
.replace(/&amp;/g, "&");
},
Expand All @@ -566,11 +568,34 @@
String(value)
.replace(/&/g, "&amp;")
.replace(/\"/g, "&quot;")
//.replace(/\'/g, "&#x27;")
//.replace(/\//g, "&#x2F;")
.replace(/\'/g, "&#39;")
.replace(/\//g, "&#47;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
},
oldEncodePostedData: function (value) {
return !value ?
value :
String(value)
.replace(/&/g, "&amp;")
.replace(/\"/g, "&quot;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
},
oldDecodePostedData: function (value) {
if (value && (value === "&nbsp;" ||
value === "&#160;" ||
(value.length === 1 && value.charCodeAt(0) === 160))) {
return "";
}
return !value ?
value :
String(value)
.replace(/&gt;/g, ">")
.replace(/&lt;/g, "<")
.replace(/&quot;/g, "\"")
.replace(/&amp;/g, "&");
},
clearArray: function (ar) {
// see http://jsperf.com/empty-javascript-array
while (ar.length > 0) {
Expand Down Expand Up @@ -2275,6 +2300,7 @@
viewsortcols: [false, "vertical", true],
resizeclass: "",
autoencode: false, // true is better for the most cases, but we hold old value to have better backwards compatibility
autoEncodeOnEdit: false,
remapColumns: [],
cmNamesInputOrder: [],
ajaxGridOptions: {},
Expand Down Expand Up @@ -2610,8 +2636,8 @@
p.colModel[idx + p.nv].width = nw;
} else {
p.tblwidth = self.newWidth || p.tblwidth;
$bTable.css("width", p.tblwidth + "px");
getGridComponent(COMPONENT_NAMES.HEADER_TABLE, self.hDiv).css("width", p.tblwidth + "px");
//$bTable.css("width", p.tblwidth + "px");
//getGridComponent(COMPONENT_NAMES.HEADER_TABLE, self.hDiv).css("width", p.tblwidth + "px");
if (skipGridAdjustments !== true) {
self.hDiv.scrollLeft = self.bDiv.scrollLeft;
if (p.footerrow) {
Expand Down Expand Up @@ -4683,7 +4709,6 @@
}
p.widthOrg = p.width;
setInitialColWidth();
hTable.css("width", p.tblwidth + "px");
$(eg).css("width", grid.width + "px")
.append("<div class='" + getGuiStyles("resizer", "ui-jqgrid-resize-mark") + "' id='" + p.rsId + "'>&#160;</div>");
$(p.rs)
Expand Down Expand Up @@ -5083,7 +5108,7 @@
if (p.maxHeight) {
$(grid.bDiv).css("max-height", p.maxHeight + (isNaN(p.maxHeight) ? "" : "px"));
}
$self0.css({ width: p.tblwidth + "px" });
$self0.css({ width: "1px" });
if (!$.support.tbody) { //IE
if ($(">tbody", ts).length === 2) { $(">tbody:gt(0)", ts).remove(); }
}
Expand Down Expand Up @@ -5709,8 +5734,8 @@
lcdata[nm] = vl;
}
}
title = cm.title ? { "title": vl } : {};
vl = t.formatter(rowid, dval, i, data, "edit");
title = cm.title ? { "title": stripHtml(vl) } : {};
var $dataFiled = $(ind.cells[i]);//$("td[role=gridcell]:eq(" + i + ")", ind);
if (p.treeGrid === true && nm === p.ExpandColumn) {
$dataFiled = $dataFiled.children("span.cell-wrapperleaf,span.cell-wrapper").first();
Expand Down Expand Up @@ -6211,8 +6236,8 @@
if (p.tblwidth) {
p.tblwidth = parseInt(p.tblwidth, 10); // round till integer value of px;
newGridWidth = p.tblwidth;
$($t).css("width", newGridWidth + "px");
getGridComponent(COMPONENT_NAMES.HEADER_TABLE, hDiv).css("width", newGridWidth + "px");
//$($t).css("width", newGridWidth + "px");
//getGridComponent(COMPONENT_NAMES.HEADER_TABLE, hDiv).css("width", newGridWidth + "px");
hDiv.scrollLeft = bDiv.scrollLeft;
if (p.footerrow) {
getGridComponent(COMPONENT_NAMES.FOOTER_TABLE, sDiv).css("width", newGridWidth + "px");
Expand Down
14 changes: 9 additions & 5 deletions js/grid.celledit.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@
} catch (ex) {
tmp = edittype === "textarea" ? cc.text() : cc.html();
}
if (p.autoencode) {
tmp = jgrid.htmlDecode(tmp);
if (p.autoEncodeOnEdit) {
tmp = jgrid.oldDecodePostedData(tmp);
}
savedRow.push({ id: iRow, ic: iCol, name: nm, v: tmp });
if (tmp === "&nbsp;" || tmp === "&#160;" || (tmp.length === 1 && tmp.charCodeAt(0) === 160)) {
Expand Down Expand Up @@ -242,14 +242,18 @@
if (p.cellsubmit === "remote") {
if (p.cellurl) {
var postdata = {};
if (p.autoencode) {
v = jgrid.htmlEncode(v);
}
postdata[nm] = v;
var opers = p.prmNames, idname = opers.id, oper = opers.oper, hDiv = $t.grid.hDiv;
postdata[idname] = jgrid.stripPref(p.idPrefix, rowid);
postdata[oper] = opers.editoper;
postdata = $.extend(addpost, postdata);
if (p.autoEncodeOnEdit) {
$.each(postdata, function (n, val) {
if (!$.isFunction(val)) {
postdata[n] = jgrid.oldEncodePostedData(val);
}
});
}
$self.jqGrid("progressBar", { method: "show", loadtype: p.loadui, htmlcontent: jgrid.defaults.savetext || "Saving..." });
hDiv.loading = true;
$.ajax($.extend({
Expand Down
18 changes: 12 additions & 6 deletions js/grid.formedit.js
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,6 @@
postdata[nm] = $(this).val();
break;
}
// REMARK: to be exactly one should call htmlEncode LATER and to use validation and unformatting of unencoded data!!
if (p.autoencode) { postdata[nm] = jgrid.htmlEncode(postdata[nm]); }
}
});
return true;
Expand Down Expand Up @@ -607,7 +605,7 @@
tmp = $.isFunction(opt.defaultValue) ? opt.defaultValue.call($t) : opt.defaultValue;
}
if (!cm.edittype) { cm.edittype = "text"; }
if (p.autoencode) { tmp = jgrid.htmlDecode(tmp); }
if (p.autoEncodeOnEdit) { tmp = jgrid.oldDecodePostedData(tmp); }
elc = jgrid.createEl.call($t, cm.edittype, opt, tmp, false, $.extend({}, jgrid.ajaxOptions, p.ajaxSelectOptions || {}));
//if(tmp === "" && cm.edittype == "checkbox") {tmp = $(elc).data("offval");}
//if(tmp === "" && cm.edittype == "select") {tmp = $("option:eq(0)",elc).text();}
Expand Down Expand Up @@ -711,7 +709,7 @@
} catch (_) {
tmp = cm[i].edittype === "textarea" ? $(this).text() : $(this).html();
}
if (p.autoencode) { tmp = jgrid.htmlDecode(tmp); }
if (p.autoEncodeOnEdit) { tmp = jgrid.oldDecodePostedData(tmp); }
if (o.checkOnSubmit === true || o.checkOnUpdate) { o._savedData[nm] = tmp; }
nm = "#" + jqID(nm);
switch (cm[i].edittype) {
Expand Down Expand Up @@ -861,6 +859,14 @@
}

postdata[idname] = jgrid.stripPref(p.idPrefix, postdata[idname]);
if (p.autoEncodeOnEdit) {
$.each(postdata, function (n, v) {
if (!$.isFunction(v)) {
postdata[n] = jgrid.oldEncodePostedData(v);
}
});
}

var ajaxOptions = $.extend({
url: url,
type: o.mtype,
Expand Down Expand Up @@ -895,9 +901,9 @@
$("#FormError>td", frmtb).html(ret[1]);
$("#FormError", frmtb).show();
} else {
if (p.autoencode) {
if (p.autoEncodeOnEdit) {
$.each(postdata, function (n, v) {
postdata[n] = jgrid.htmlDecode(v);
postdata[n] = jgrid.oldDecodePostedData(v);
});
}
//o.reloadAfterSubmit = o.reloadAfterSubmit && $t.o.datatype != "local";
Expand Down
12 changes: 9 additions & 3 deletions js/grid.inlinedit.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@
if (cv[0] === false) {
return false;
}
if (isRemoteSave && p.autoencode) { v = jgrid.htmlEncode(v); }
if (formatter === "date" && formatoptions.sendFormatted !== true) {
// TODO: call all other predefined formatters!!! Not only formatter: "date" have the problem.
// Floating point separator for example
Expand Down Expand Up @@ -320,6 +319,13 @@
$self.jqGrid("progressBar", { method: "show", loadtype: o.saveui, htmlcontent: o.savetext });
postData = $.extend({}, tmp, postData);
postData[idname] = jgrid.stripPref(p.idPrefix, postData[idname]);
if (p.autoEncodeOnEdit) {
$.each(postData, function (n, v) {
if (!$.isFunction(v)) {
postData[n] = jgrid.oldEncodePostedData(v);
}
});
}

$.ajax($.extend({
url: o.url,
Expand All @@ -345,9 +351,9 @@
ret = sucret;
}
if (ret === true) {
if (p.autoencode) {
if (p.autoEncodeOnEdit) {
$.each(tmp, function (n, v) {
tmp[n] = jgrid.htmlDecode(v);
tmp[n] = jgrid.oldDecodePostedData(v);
});
}
tmp = $.extend({}, tmp, tmp2);
Expand Down

0 comments on commit d31b70f

Please sign in to comment.