Просмотр исходного кода

HPCC-9821 Allow raw HTML + JavaScript in result cells

Fixes HPCC-9821

Signed-off-by: Gordon Smith <gordon.smith@lexisnexis.com>
Gordon Smith 12 лет назад
Родитель
Сommit
37951548c1
2 измененных файлов с 89 добавлено и 22 удалено
  1. 84 22
      esp/files/scripts/ESPResult.js
  2. 5 0
      esp/files/scripts/ESPWorkunit.js

+ 84 - 22
esp/files/scripts/ESPResult.js

@@ -18,6 +18,7 @@ define([
     "dojo/_base/array",
     "dojo/_base/Deferred",
     "dojo/_base/lang",
+    "dojo/NodeList-manipulate",
     "dojo/data/ObjectStore",
     "dojo/store/util/QueryResults",
     "dojo/store/Observable",
@@ -30,7 +31,7 @@ define([
     "hpcc/ESPBase",
     "hpcc/ESPRequest",
     "hpcc/WsWorkunits"
-], function (declare, arrayUtil, Deferred, lang, ObjectStore, QueryResults, Observable, domConstruct,
+], function (declare, arrayUtil, Deferred, lang, NodeListManipulate, ObjectStore, QueryResults, Observable, domConstruct,
             parser, DomParser, entities,
             ESPBase, ESPRequest, WsWorkunits) {
 
@@ -64,7 +65,7 @@ define([
                 this.XmlSchema = [];
             }
             var rows = this.getValues(domXml, "Row", ["Row"]);
-            arrayUtil.forEach(rows, function (item, index) {
+            arrayUtil.forEach(rows, function(item, index) {
                 item.rowNum = request.Start + index + 1;
             });
             response.Result = rows;
@@ -144,8 +145,8 @@ define([
             return this.getFirstSchemaNode(complexType, "sequence");
         },
 
-        rowToTable: function (cell) {
-            var table = domConstruct.create("table", { border: 1, cellspacing: 0, width: "100%" });
+        rowToTable: function (cell, __row, node) {
+            var table = domConstruct.create("table", { border: 1, cellspacing: 0, width: "100%" }, node);
             if (Object.prototype.toString.call(cell) === '[object Object]') {
                 cell = [cell];
             } 
@@ -162,7 +163,12 @@ define([
                         if (cell[i][key]) {
                             if (Object.prototype.toString.call(cell[i][key]) === '[object Object]' || Object.prototype.toString.call(cell[i][key]) === '[object Array]') {
                                 var td = domConstruct.create("td", null, tr);
-                                td.appendChild(this.rowToTable(cell[i][key]));
+                                this.rowToTable(cell[i][key], cell[i], td);
+                            } else if (key.indexOf("__html", key.length - "__html".length) !== -1) {
+                                var td = domConstruct.create("td", { innerHTML : cell[i][key] }, tr);
+                            } else if (key.indexOf("__javascript", key.length - "__javascript".length) !== -1) {
+                                var td = domConstruct.create("td", null, tr);
+                                this.injectJavascript(cell[i][key], cell[i], td);
                             } else {
                                 var td = domConstruct.create("td", { innerHTML: entities.encode(cell[i][key]) }, tr);
                             }
@@ -172,9 +178,34 @@ define([
                     }
                 }
             }
-            return table;
         },
-
+        injectJavascript : function(__cellContent, __row, __cell, __width) {
+            //  Add paragraph so cells can valign  ---
+            domConstruct.create("p", {
+                style: {
+                    height : "1px"
+                },
+                innerHTML: "&nbsp;"
+            }, __cell);
+            try {
+                eval(__cellContent);
+            } catch (e) {
+                __cell.innerHTML = "<b>Error:</b>&nbsp;&nbsp;" + entities.encode(e.message) + "<br>" + entities.encode(__cellContent);
+            }
+        },
+        parseName: function (nameObj) {
+            nameObj.width = 500;
+            var titleParts = nameObj.name.split("__");
+            if (titleParts.length >= 3) {
+                var specifiedWidth = parseInt(titleParts[titleParts.length - 2]);
+                if (!isNaN(specifiedWidth)) {
+                    nameObj.width = specifiedWidth;
+                    titleParts = titleParts.slice(0, titleParts.length - 1);
+                }
+            }
+            titleParts = titleParts.slice(0, titleParts.length - 1);
+            nameObj.displayName = titleParts.join("__");
+        },
         getRowStructureFromSchema: function (parentNode, prefix) {
             var sequence = this.getFirstSequenceNode(parentNode, "sequence");
             if (!sequence)
@@ -187,16 +218,50 @@ define([
                     var name = node.getAttribute("name");
                     var type = node.getAttribute("type");
                     var children = this.getRowStructureFromSchema(node, name + "_");
-                    if (name && type) {
-                        retVal.push({
-                            label: name,
-                            field: prefix + name,
-                            width: this.extractWidth(type, name) * 9,
-                            className: "resultGridCell",
-                            sortable: false
-                        });
+                    var context = this;
+                    if (name && name.indexOf("__hidden", name.length - "__hidden".length) !== -1) {
+                    } else if (name && type) {
+                        if (name.indexOf("__html", name.length - "__html".length) !== -1) {
+                            var nameObj = {
+                                name: name
+                            };
+                            this.parseName(nameObj);
+                            retVal.push({
+                                label: nameObj.displayName,
+                                field: prefix + name,
+                                width: nameObj.width,
+                                className: "resultGridCell",
+                                formatter: function (cell, row) {
+                                    return cell;
+                                },
+                                sortable: false
+                            });
+                        } else if (name.indexOf("__javascript", name.length - "__javascript".length) !== -1) {
+                            var nameObj = {
+                                name: name
+                            };
+                            this.parseName(nameObj);
+                            retVal.push({
+                                label: nameObj.displayName,
+                                field: prefix + name,
+                                width: nameObj.width,
+                                className: "resultGridCell",
+                                renderCell: function(row, cell, node, options) {
+                                    context.injectJavascript(cell, row, node, this.width)
+                                },
+                                sortable: false
+                            });
+                        } else {
+                            retVal.push({
+                                label: name,
+                                field: prefix + name,
+                                width: this.extractWidth(type, name) * 9,
+                                className: "resultGridCell",
+                                sortable: false
+                            });
+                        }
                     } else if (children) {
-                        var childWidth = 0;
+                        var childWidth = 10;  //  Allow for html table
                         arrayUtil.forEach(children, function(item, idx) {
                             childWidth += item.width;
                         });
@@ -209,14 +274,11 @@ define([
                             sortable: false
                         });
                         */
-                        var context = this;
                         retVal.push({
                             label: name,
                             field: name,
-                            formatter: function (cell, row, grid) {
-                                var div = document.createElement("div");
-                                div.appendChild(context.rowToTable(cell));
-                                return div.innerHTML;
+                            renderCell: function(row, cell, node, options) {
+                                context.rowToTable(cell, row, node);
                             },
                             width: childWidth,
                             className: "resultGridCell",
@@ -239,7 +301,7 @@ define([
                         formatter: function (cell, row, grid) {
                             if (Object.prototype.toString.call(cell) === '[object Object]' || Object.prototype.toString.call(cell) === '[object Array]') {
                                 var div = document.createElement("div");
-                                div.appendChild(context.rowToTable(cell));
+                                context.rowToTable(cell, row, div);
                                 return div.innerHTML;
                             }
                             return cell;

+ 5 - 0
esp/files/scripts/ESPWorkunit.js

@@ -86,13 +86,18 @@ define([
         _ResultsSetter: function (Results) {
             var results = [];
             var sequenceResults = [];
+            var namedResults = [];
             for (var i = 0; i < Results.ECLResult.length; ++i) {
                 var espResult = ESPResult.Get(lang.mixin({ wu: this.wu, Wuid: this.Wuid }, Results.ECLResult[i]));
                 results.push(espResult);
                 sequenceResults[Results.ECLResult[i].Sequence] = espResult;
+                if (Results.ECLResult[i].Name) {
+                    namedResults[Results.ECLResult[i].Name] = espResult;
+                }
             }
             this.set("results", results);
             this.set("sequenceResults", sequenceResults);
+            this.set("namedResults", namedResults);
         },
         _SourceFilesSetter: function (SourceFiles) {
             var sourceFiles = [];