<commit_before>'use strict';

pinpointApp.directive('distributedCallFlow', [ '$filter', '$timeout',
    function ($filter, $timeout) {
        return {
            restrict: 'E',
            replace: true,
            templateUrl: 'views/distributedCallFlow.html',
            scope : {
                namespace : '@' // string value
            },
            link: function postLink(scope, element, attrs) {

                // initialize variables
                var grid, columns, dataView, lastAgent;

                // initialize variables of methods
                var initialize, treeFormatter, treeFilter, parseData, execTimeFormatter,
                    getColorByString, progressBarFormatter, argumentFormatter;

                // bootstrap
                window.callStacks = []; // Slick.Data.DataView 때문에, window 프로퍼티로 사용해야 scope 문제가 해결됨.

                getColorByString = function(str) {
                    // str to hash
                    for (var i = 0, hash = 0; i < str.length; hash = str.charCodeAt(i++) + ((hash << 5) - hash));
                    // int/hash to hex
                    for (var i = 0, colour = "#"; i < 3; colour += ("00" + ((hash >> i++ * 8) & 0xFF).toString(16)).slice(-2));
                    return colour;
                };

                treeFormatter = function (row, cell, value, columnDef, dataContext) {
                    var html = [];

                    value = value.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
                    var item = dataView.getItemById(dataContext.id);
                    lastAgent = item.agent ? item.agent : lastAgent;

                    var leftBarColor = getColorByString(lastAgent),
                        idx = dataView.getIdxById(dataContext.id),
                        divClass = 'dcf-popover';

                    if (item.hasException) {
                        divClass += ' has-exception';
                    } else if (!item.isMethod) {
                        divClass += ' not-method';
                    }
                    html.push('
');
                    html.push("

");
                    html.push("");

                    if (window.callStacks[idx + 1] && window.callStacks[idx + 1].indent > window.callStacks[idx].indent) {
                        if (dataContext._collapsed) {
                            html.push("  ");
                        } else {
                            html.push("  ");
                        }
                    } else {
                        html.push("  ");
                    }

                    if (item.hasException) {
                        html.push(' ');
                    } else if (!item.isMethod) {
                        html.push(' ');
                    }

                    html.push(value);
                    html.push('
');

                    return html.join('');
                };

                treeFilter = function (item) {
                    var result = true;
                    if (item.parent != null) {
                        var parent = window.callStacks[item.parent];
                        while (parent) {

                            if (parent._collapsed) {
                                result = false;
                            }
                            parent = window.callStacks[parent.parent];
                        }
                    }
                    return result;
                };

                argumentFormatter = function (row, cell, value, columnDef, dataConrtext) {
                    var html = [];

                    html.push('
');
                    html.push(value);
                    html.push('
');
                    return html.join('');
                };

                execTimeFormatter = function (row, cell, value, columnDef, dataContext) {
                    return $filter('date')(value, 'HH:mm:ss sss');
                };

                progressBarFormatter = function (row, cell, value, columnDef, dataContext) {
                    if (value == null || value === "" || value == 0) {
                        return "";
                    }
                    var color;
                    if (value < 30) {
                        color = "#5bc0de";
                    } else if (value < 70) {
                        color = "#5bc0de";
                    } else {
                        color = "#5bc0de";
                    }
                    return "";
                };

                columns = [
                    {id: "method", name: "Method", field: "method", width: 400, formatter: treeFormatter},
                    {id: "argument", name: "Argument", field: "argument", width: 300, formatter: argumentFormatter},
                    {id: "exec-time", name: "Exec Time", field: "execTime", width: 90, formatter: execTimeFormatter},
                    {id: "gap-ms", name: "Gap(ms)", field: "gapMs", width: 60, cssClass: "right-align"},
                    {id: "time-ms", name: "Time(ms)", field: "timeMs", width: 60, cssClass: "right-align"},
                    {id: "time-per", name: "Time(%)", field: "timePer", width: 100, formatter: progressBarFormatter},
                    {id: "class", name: "Class", field: "class", width: 120},
                    {id: "api-type", name: "Api Type", field: "apiType", width: 90},
                    {id: "agent", name: "Agent", field: "agent", width: 130},
                    {id: "application-name", name: "Application Name", field: "applicationName", width: 150}
                ];

                parseData = function(index, callStacks) {
                    var result = [],
                        barRatio = 100 / (callStacks[0][index.end] - callStacks[0][index.begin]);
                    angular.forEach(callStacks, function (val, key) {
                        result.push({
                            id: 'id_' + key,
                            parent: val[index['parentId']] ? val[index['parentId']] - 1 : null,
                            indent: val[index['tab']],
                            method: val[index['title']],
                            argument: val[index['arguments']],
                            execTime: val[index['begin']] > 0 ? val[index['begin']] : null,
                            gapMs: val[index['gap']],
                            timeMs: val[index['elapsedTime']],
                            timePer: val[index['elapsedTime']] ? ((val[index['end']] - val[index['begin']]) * barRatio) + 0.9 : null,
                            class: val[index['simpleClassName']],
                            apiType: val[index['apiType']],
                            agent: val[index['agent']],
                            applicationName: val[index['applicationName']],
                            hasException: val[index['hasException']],
                            isMethod: val[index['isMethod']]
                        });
                    });
                    return result;
                };

                /**
                 * initialize
                 * @param t transactionDetail
                 */
                initialize = function (t) {
                    window.callStacks = parseData(t.callStackIndex, t.callStack);
                    // initialize the model

                    var options = {
                        enableCellNavigation: true,
                        enableColumnReorder: true,
                        enableTextSelectionOnCells: true,
//                        autoHeight: true,
                        topPanelHeight: 30,
                        rowHeight: 25
                    };

                    dataView = new Slick.Data.DataView({ inlineFilters: true });
                    dataView.beginUpdate();
                    dataView.setItems(window.callStacks);
                    dataView.setFilter(treeFilter);
//                    dataView.getItemMetadata = function (row) {
//                        var item = dataView.getItemByIdx(row);
//                        if (!item.execTime) {
//                            return {
//                                "columns": {
//                                    2: {
//                                        "colspan": "*"
//                                    }
//                                }
//                            };
//                        }
//                    };
                    dataView.endUpdate();

                    grid = new Slick.Grid(element.get(0), dataView, columns, options);

                    var isSingleClick = true, clickTimeout = false;
                    grid.onClick.subscribe(function (e, args) {
                        if ($(e.target).hasClass("toggle")) {
                            var item = dataView.getItem(args.row);
                            if (item) {

                                if (!item._collapsed) {
                                    item._collapsed = true;
                                } else {
                                    item._collapsed = false;
                                }
                                dataView.updateItem(item.id, item);
                            }
                            e.stopImmediatePropagation();
                        }

                        if (!clickTimeout) {
                            clickTimeout = $timeout(function () {
                                if (isSingleClick) {
                                    element.find('.dcf-popover').popover('hide');
                                }
                                isSingleClick = true;
                                clickTimeout = false;
                            }, 300);
                        }
                    });

                    grid.onDblClick.subscribe(function (e, args) {
                        isSingleClick = false;
//                        console.log('isSingleClick = false');
                        $(e.target).popover('toggle');
                    });

                    grid.onCellChange.subscribe(function (e, args) {
                        dataView.updateItem(args.item.id, args.item);
                    });

                    grid.onActiveCellChanged.subscribe(function (e, args) {
                        scope.$emit('distributedCallFlow.rowSelected.' + scope.namespace, args.grid.getDataItem(args.row));
                    });

                    // wire up model events to drive the grid
                    dataView.onRowCountChanged.subscribe(function (e, args) {
                        grid.updateRowCount();
                        grid.render();
                    });

                    dataView.onRowsChanged.subscribe(function (e, args) {
                        grid.invalidateRows(args.rows);
                        grid.render();
                    });

                };

                /**
                 * scope event on distributedCallFlow.initialize
                 */
                scope.$on('distributedCallFlow.initialize.' + scope.namespace, function (event, transactionDetail) {
                    initialize(transactionDetail);
                });

                /**
                 * scope event on distributedCallFlow.resize
                 */
                scope.$on('distributedCallFlow.resize.' + scope.namespace, function (event) {
                    grid.resizeCanvas();
                });
            }
        };
    }
]);
<commit_msg>[임대현] #153 distributed call flow에서 키보드 방향키 사용.<commit_after>'use strict';

pinpointApp.directive('distributedCallFlow', [ '$filter', '$timeout',
    function ($filter, $timeout) {
        return {
            restrict: 'E',
            replace: true,
            templateUrl: 'views/distributedCallFlow.html',
            scope : {
                namespace : '@' // string value
            },
            link: function postLink(scope, element, attrs) {

                // initialize variables
                var grid, columns, dataView, lastAgent;

                // initialize variables of methods
                var initialize, treeFormatter, treeFilter, parseData, execTimeFormatter,
                    getColorByString, progressBarFormatter, argumentFormatter, hasChildNode;

                // bootstrap
                window.callStacks = []; // Slick.Data.DataView 때문에, window 프로퍼티로 사용해야 scope 문제가 해결됨.

                getColorByString = function(str) {
                    // str to hash
                    for (var i = 0, hash = 0; i < str.length; hash = str.charCodeAt(i++) + ((hash << 5) - hash));
                    // int/hash to hex
                    for (var i = 0, colour = "#"; i < 3; colour += ("00" + ((hash >> i++ * 8) & 0xFF).toString(16)).slice(-2));
                    return colour;
                };

                treeFormatter = function (row, cell, value, columnDef, dataContext) {
                    var html = [];

                    value = value.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
                    var item = dataView.getItemById(dataContext.id);
                    lastAgent = item.agent ? item.agent : lastAgent;

                    var leftBarColor = getColorByString(lastAgent),
                        idx = dataView.getIdxById(dataContext.id),
                        divClass = 'dcf-popover';

                    if (item.hasException) {
                        divClass += ' has-exception';
                    } else if (!item.isMethod) {
                        divClass += ' not-method';
                    }
                    html.push('
');
                    html.push("

");
                    html.push("");

                    if (window.callStacks[idx + 1] && window.callStacks[idx + 1].indent > window.callStacks[idx].indent) {
                        if (dataContext._collapsed) {
                            html.push("  ");
                        } else {
                            html.push("  ");
                        }
                    } else {
                        html.push("  ");
                    }

                    if (item.hasException) {
                        html.push(' ');
                    } else if (!item.isMethod) {
                        html.push(' ');
                    }

                    html.push(value);
                    html.push('
');

                    return html.join('');
                };

                treeFilter = function (item) {
                    var result = true;
                    if (item.parent != null) {
                        var parent = window.callStacks[item.parent];
                        while (parent) {

                            if (parent._collapsed) {
                                result = false;
                            }
                            parent = window.callStacks[parent.parent];
                        }
                    }
                    return result;
                };

                argumentFormatter = function (row, cell, value, columnDef, dataConrtext) {
                    var html = [];

                    html.push('
');
                    html.push(value);
                    html.push('
');
                    return html.join('');
                };

                execTimeFormatter = function (row, cell, value, columnDef, dataContext) {
                    return $filter('date')(value, 'HH:mm:ss sss');
                };

                progressBarFormatter = function (row, cell, value, columnDef, dataContext) {
                    if (value == null || value === "" || value == 0) {
                        return "";
                    }
                    var color;
                    if (value < 30) {
                        color = "#5bc0de";
                    } else if (value < 70) {
                        color = "#5bc0de";
                    } else {
                        color = "#5bc0de";
                    }
                    return "";
                };

                columns = [
                    {id: "method", name: "Method", field: "method", width: 400, formatter: treeFormatter},
                    {id: "argument", name: "Argument", field: "argument", width: 300, formatter: argumentFormatter},
                    {id: "exec-time", name: "Exec Time", field: "execTime", width: 90, formatter: execTimeFormatter},
                    {id: "gap-ms", name: "Gap(ms)", field: "gapMs", width: 60, cssClass: "right-align"},
                    {id: "time-ms", name: "Time(ms)", field: "timeMs", width: 60, cssClass: "right-align"},
                    {id: "time-per", name: "Time(%)", field: "timePer", width: 100, formatter: progressBarFormatter},
                    {id: "class", name: "Class", field: "class", width: 120},
                    {id: "api-type", name: "Api Type", field: "apiType", width: 90},
                    {id: "agent", name: "Agent", field: "agent", width: 130},
                    {id: "application-name", name: "Application Name", field: "applicationName", width: 150}
                ];

                parseData = function(index, callStacks) {
                    var result = [],
                        barRatio = 100 / (callStacks[0][index.end] - callStacks[0][index.begin]);
                    angular.forEach(callStacks, function (val, key) {
                        result.push({
                            id: 'id_' + key,
                            parent: val[index['parentId']] ? val[index['parentId']] - 1 : null,
                            indent: val[index['tab']],
                            method: val[index['title']],
                            argument: val[index['arguments']],
                            execTime: val[index['begin']] > 0 ? val[index['begin']] : null,
                            gapMs: val[index['gap']],
                            timeMs: val[index['elapsedTime']],
                            timePer: val[index['elapsedTime']] ? ((val[index['end']] - val[index['begin']]) * barRatio) + 0.9 : null,
                            class: val[index['simpleClassName']],
                            apiType: val[index['apiType']],
                            agent: val[index['agent']],
                            applicationName: val[index['applicationName']],
                            hasException: val[index['hasException']],
                            isMethod: val[index['isMethod']]
                        });
                    });
                    return result;
                };

                /**
                 * initialize
                 * @param t transactionDetail
                 */
                initialize = function (t) {
                    window.callStacks = parseData(t.callStackIndex, t.callStack);
                    // initialize the model

                    var options = {
                        enableCellNavigation: true,
                        enableColumnReorder: true,
                        enableTextSelectionOnCells: true,
//                        autoHeight: true,
                        topPanelHeight: 30,
                        rowHeight: 25
                    };

                    dataView = new Slick.Data.DataView({ inlineFilters: true });
                    dataView.beginUpdate();
                    dataView.setItems(window.callStacks);
                    dataView.setFilter(treeFilter);
//                    dataView.getItemMetadata = function (row) {
//                        var item = dataView.getItemByIdx(row);
//                        if (!item.execTime) {
//                            return {
//                                "columns": {
//                                    2: {
//                                        "colspan": "*"
//                                    }
//                                }
//                            };
//                        }
//                    };
                    dataView.endUpdate();

                    grid = new Slick.Grid(element.get(0), dataView, columns, options);

                    var isSingleClick = true, clickTimeout = false;
                    grid.onClick.subscribe(function (e, args) {
                        if ($(e.target).hasClass("toggle")) {
                            var item = dataView.getItem(args.row);
                            if (item) {
                                if (!item._collapsed) {
                                    item._collapsed = true;
                                } else {
                                    item._collapsed = false;
                                }
                                dataView.updateItem(item.id, item);
                            }
                            e.stopImmediatePropagation();
                        }

                        if (!clickTimeout) {
                            clickTimeout = $timeout(function () {
                                if (isSingleClick) {
                                    element.find('.dcf-popover').popover('hide');
                                }
                                isSingleClick = true;
                                clickTimeout = false;
                            }, 300);
                        }
                    });

                    grid.onDblClick.subscribe(function (e, args) {
                        isSingleClick = false;
//                        console.log('isSingleClick = false');
                        $(e.target).popover('toggle');
                    });

                    grid.onCellChange.subscribe(function (e, args) {
                        dataView.updateItem(args.item.id, args.item);
                    });

                    grid.onActiveCellChanged.subscribe(function (e, args) {
                        scope.$emit('distributedCallFlow.rowSelected.' + scope.namespace, args.grid.getDataItem(args.row));
                    });

                    hasChildNode = function (row) {
                        var nextItem = dataView.getItem(row + 1);
                        if (nextItem) {
                            if (row === nextItem.parent) {
                                return true;
                            }
                        }
                        return false;
                    };

                    grid.onKeyDown.subscribe(function (e, args) {
                        var item = dataView.getItem(args.row);

                        if (e.which == 37) {
                            if (hasChildNode(args.row)) {
                                item._collapsed = true;
                                dataView.updateItem(item.id, item);
                            } else if (item.indent > 0 && item.parent >= 0) {
                                var parent = dataView.getItem(item.parent);
                                parent._collapsed = true;
                                dataView.updateItem(item.id, item);
                                grid.setActiveCell(dataView.getRowById(parent.id), 0);
                            }

                        } else if (e.which == 39 && angular.isDefined(item._collapsed)) {
                            item._collapsed = false;
                            dataView.updateItem(item.id, item);
                        }
                    });

                    // wire up model events to drive the grid
                    dataView.onRowCountChanged.subscribe(function (e, args) {
                        grid.updateRowCount();
                        grid.render();
                    });

                    dataView.onRowsChanged.subscribe(function (e, args) {
                        grid.invalidateRows(args.rows);
                        grid.render();
                    });

                };

                /**
                 * scope event on distributedCallFlow.initialize
                 */
                scope.$on('distributedCallFlow.initialize.' + scope.namespace, function (event, transactionDetail) {
                    initialize(transactionDetail);
                });

                /**
                 * scope event on distributedCallFlow.resize
                 */
                scope.$on('distributedCallFlow.resize.' + scope.namespace, function (event) {
                    grid.resizeCanvas();
                });
            }
        };
    }
]);
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// These have to be sync'd with file_browser_private_apitest.cc
var expectedVolume1 = {
  devicePath: 'device_path1',
  mountPath: 'removable/mount_path1',
  systemPath: 'system_path1',
  filePath: 'file_path1',
  deviceLabel: 'device_label1',
  driveLabel: 'drive_label1',
  deviceType: 'usb',
  totalSize:  1073741824,
  isParent: false,
  isReadOnly: false,
  hasMedia: false,
  isOnBootDevice: false
};

var expectedVolume2 = {
  devicePath: 'device_path2',
  mountPath: 'mount_path2',
  mountPath: 'removable/mount_path2',
  systemPath: 'system_path2',
  filePath: 'file_path2',
  deviceLabel: 'device_label2',
  driveLabel: 'drive_label2',
  deviceType: 'mobile',
  totalSize:  47723,
  isParent: true,
  isReadOnly: true,
  hasMedia: true,
  isOnBootDevice: true
};

var expectedVolume3 = {
  devicePath: 'device_path3',
  mountPath: 'mount_path3',
  mountPath: 'removable/mount_path3',
  systemPath: 'system_path3',
  filePath: 'file_path3',
  deviceLabel: 'device_label3',
  driveLabel: 'drive_label3',
  deviceType: 'optical',
  totalSize:  0,
  isParent: true,
  isReadOnly: false,
  hasMedia: false,
  isOnBootDevice: true
};

// List of expected mount points.
// We have to treat archives specially because their sourceUrl is set to
// filesystem url. To make it easier to define expectation for archives,
// instead of sourceUrl, we set sourcePath that will be converted to filesystem
// url when received mountPoint is verified.
// NOTE: this has to be synced with values in file_browser_private_apitest.cc
//       and values sorted by mountPath.
var expectedMountPoints = [
  {
    sourcePath: 'Downloads/archive_path',
    mountPath: 'archive/archive_mount_path',
    mountType: 'file',
    mountCondition: ''
  },
  {
    sourceUrl: 'device_path1',
    mountPath: 'removable/mount_path1',
    mountType: 'device',
    mountCondition: ''
  },
  {
    sourceUrl: 'device_path2',
    mountPath: 'removable/mount_path2',
    mountType: 'device',
    mountCondition: ''
  },
  {
    sourceUrl: 'device_path3',
    mountPath: 'removable/mount_path3',
    mountType: 'device',
    mountCondition: ''
  }
];

function treatMountPointException(received, expected, key) {
  if (key != 'sourcePath')
    return { wasValidated: false, success: false };
  var expectedSourceUrl = createFileUrl(expected[key]);
  var success = (expectedSourceUrl == received['sourceUrl']);
  if (!success)
    console.warn("Expected mount point's sourceUrl to be '" +
                 expectedSourceUrl + "' but got '" + received['sourceUrl'] +
                 "' instead.");
  return { wasValidated: true, success: success };
};

function validateObject(received, expected, name, treatException) {
  for (var key in expected) {
    var validated = treatException &&
                    treatException(received, expected, key);
    if (validated && validated.wasValidated) {
      if (validated.success) {
        continue;
      } else {
        return false;
      }
    }
    if (received[key] != expected[key]) {
      console.warn('Expected "' + key + '" ' + name + ' property to be: "' +
                  expected[key] + '"' + ', but got: "' + received[key] +
                  '" instead.');
      return false;
    }
  }
  if (Object.keys(expected).length != Object.keys(received).length) {
    console.warn("Unexpected property found in returned volume");
    return false;
  }
  return true;
};

function createFileUrl(fileName) {
  var testExtensionId = "ddammdhioacbehjngdmkjcjbnfginlla";
  var fileUrl = "filesystem:chrome-extension://" + testExtensionId +
                "/external/" + fileName;
  return fileUrl;
};

chrome.test.runTests([
  function removeMount() {
    // The ID of this extension.
    var fileUrl = createFileUrl("tmp/test_file.zip");

    chrome.fileBrowserPrivate.removeMount(fileUrl);

    // We actually check this one on C++ side. If MountLibrary.RemoveMount
    // doesn't get called, test will fail.
    chrome.test.succeed();
  },

  function getVolumeMetadataValid1() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl(expectedVolume1.mountPath),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertTrue(
              validateObject(result, expectedVolume1, 'volume'),
              "getVolumeMetadata result for first volume not as expected");
    }));
  },

  function getVolumeMetadataValid2() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl(expectedVolume2.mountPath),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertTrue(
              validateObject(result, expectedVolume2, 'volume'),
              "getVolumeMetadata result for second volume not as expected");
    }));
  },

  function getVolumeMetadataValid3() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl(expectedVolume3.mountPath),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertTrue(
              validateObject(result, expectedVolume3, 'volume'),
              "getVolumeMetadata result for third volume not as expected");
    }));
  },

  function getVolumeMetadataNonExistentPath() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl("removable/non_existent_device_path"),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertEq(undefined, result);
    }));
  },

  function getVolumeMetadataArchive() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl("archive/archive_mount_path"),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertEq(undefined, result);
   }));
  },

  function getVolumeMetadataInvalidPath() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        "some path",
        chrome.test.callbackFail("Invalid mount path."));
  },

  function getMountPointsTest() {
    chrome.fileBrowserPrivate.getMountPoints(
        chrome.test.callbackPass(function(result) {
          chrome.test.assertEq(result.length, expectedMountPoints.length,
              'getMountPoints returned wrong number of mount points.');
          for (var i = 0; i < expectedMountPoints.length; i++) {
            chrome.test.assertTrue(
                validateObject(result[i], expectedMountPoints[i], 'mountPoint',
                               treatMountPointException),
                'getMountPoints result[' + i +'] not as expected');
          }
    }));
  }
]);
<commit_msg>Remove duplicate mountPaths in object literals<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// These have to be sync'd with file_browser_private_apitest.cc
var expectedVolume1 = {
  devicePath: 'device_path1',
  mountPath: 'removable/mount_path1',
  systemPath: 'system_path1',
  filePath: 'file_path1',
  deviceLabel: 'device_label1',
  driveLabel: 'drive_label1',
  deviceType: 'usb',
  totalSize:  1073741824,
  isParent: false,
  isReadOnly: false,
  hasMedia: false,
  isOnBootDevice: false
};

var expectedVolume2 = {
  devicePath: 'device_path2',
  mountPath: 'removable/mount_path2',
  systemPath: 'system_path2',
  filePath: 'file_path2',
  deviceLabel: 'device_label2',
  driveLabel: 'drive_label2',
  deviceType: 'mobile',
  totalSize:  47723,
  isParent: true,
  isReadOnly: true,
  hasMedia: true,
  isOnBootDevice: true
};

var expectedVolume3 = {
  devicePath: 'device_path3',
  mountPath: 'removable/mount_path3',
  systemPath: 'system_path3',
  filePath: 'file_path3',
  deviceLabel: 'device_label3',
  driveLabel: 'drive_label3',
  deviceType: 'optical',
  totalSize:  0,
  isParent: true,
  isReadOnly: false,
  hasMedia: false,
  isOnBootDevice: true
};

// List of expected mount points.
// We have to treat archives specially because their sourceUrl is set to
// filesystem url. To make it easier to define expectation for archives,
// instead of sourceUrl, we set sourcePath that will be converted to filesystem
// url when received mountPoint is verified.
// NOTE: this has to be synced with values in file_browser_private_apitest.cc
//       and values sorted by mountPath.
var expectedMountPoints = [
  {
    sourcePath: 'Downloads/archive_path',
    mountPath: 'archive/archive_mount_path',
    mountType: 'file',
    mountCondition: ''
  },
  {
    sourceUrl: 'device_path1',
    mountPath: 'removable/mount_path1',
    mountType: 'device',
    mountCondition: ''
  },
  {
    sourceUrl: 'device_path2',
    mountPath: 'removable/mount_path2',
    mountType: 'device',
    mountCondition: ''
  },
  {
    sourceUrl: 'device_path3',
    mountPath: 'removable/mount_path3',
    mountType: 'device',
    mountCondition: ''
  }
];

function treatMountPointException(received, expected, key) {
  if (key != 'sourcePath')
    return { wasValidated: false, success: false };
  var expectedSourceUrl = createFileUrl(expected[key]);
  var success = (expectedSourceUrl == received['sourceUrl']);
  if (!success)
    console.warn("Expected mount point's sourceUrl to be '" +
                 expectedSourceUrl + "' but got '" + received['sourceUrl'] +
                 "' instead.");
  return { wasValidated: true, success: success };
};

function validateObject(received, expected, name, treatException) {
  for (var key in expected) {
    var validated = treatException &&
                    treatException(received, expected, key);
    if (validated && validated.wasValidated) {
      if (validated.success) {
        continue;
      } else {
        return false;
      }
    }
    if (received[key] != expected[key]) {
      console.warn('Expected "' + key + '" ' + name + ' property to be: "' +
                  expected[key] + '"' + ', but got: "' + received[key] +
                  '" instead.');
      return false;
    }
  }
  if (Object.keys(expected).length != Object.keys(received).length) {
    console.warn("Unexpected property found in returned volume");
    return false;
  }
  return true;
};

function createFileUrl(fileName) {
  var testExtensionId = "ddammdhioacbehjngdmkjcjbnfginlla";
  var fileUrl = "filesystem:chrome-extension://" + testExtensionId +
                "/external/" + fileName;
  return fileUrl;
};

chrome.test.runTests([
  function removeMount() {
    // The ID of this extension.
    var fileUrl = createFileUrl("tmp/test_file.zip");

    chrome.fileBrowserPrivate.removeMount(fileUrl);

    // We actually check this one on C++ side. If MountLibrary.RemoveMount
    // doesn't get called, test will fail.
    chrome.test.succeed();
  },

  function getVolumeMetadataValid1() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl(expectedVolume1.mountPath),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertTrue(
              validateObject(result, expectedVolume1, 'volume'),
              "getVolumeMetadata result for first volume not as expected");
    }));
  },

  function getVolumeMetadataValid2() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl(expectedVolume2.mountPath),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertTrue(
              validateObject(result, expectedVolume2, 'volume'),
              "getVolumeMetadata result for second volume not as expected");
    }));
  },

  function getVolumeMetadataValid3() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl(expectedVolume3.mountPath),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertTrue(
              validateObject(result, expectedVolume3, 'volume'),
              "getVolumeMetadata result for third volume not as expected");
    }));
  },

  function getVolumeMetadataNonExistentPath() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl("removable/non_existent_device_path"),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertEq(undefined, result);
    }));
  },

  function getVolumeMetadataArchive() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        createFileUrl("archive/archive_mount_path"),
        chrome.test.callbackPass(function(result) {
          chrome.test.assertEq(undefined, result);
   }));
  },

  function getVolumeMetadataInvalidPath() {
    chrome.fileBrowserPrivate.getVolumeMetadata(
        "some path",
        chrome.test.callbackFail("Invalid mount path."));
  },

  function getMountPointsTest() {
    chrome.fileBrowserPrivate.getMountPoints(
        chrome.test.callbackPass(function(result) {
          chrome.test.assertEq(result.length, expectedMountPoints.length,
              'getMountPoints returned wrong number of mount points.');
          for (var i = 0; i < expectedMountPoints.length; i++) {
            chrome.test.assertTrue(
                validateObject(result[i], expectedMountPoints[i], 'mountPoint',
                               treatMountPointException),
                'getMountPoints result[' + i +'] not as expected');
          }
    }));
  }
]);
<|endoftext|>


<commit_before>/*
* Map Reduce procedure for the traffic collection hourly
*/

var map_rescode_hourly=function () {
  var date = new Date();
  date.setTime(this._id.sample_time);
  var sample_hour = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), 0, 0, 0);
  emit({
    "sample_time": sample_hour,
    "pubservhost": this._id.pubservhost,
    "zone": this._id.zone
  }, {
    "qps": {},
    "counters": this.qps,
    "count": 1,
    "created_time": this.created_time
  });
};

var reduce_hourly=function (key, values) {
  var r = {
    "qps": {},
    "counters": {},
    "count": 0,
    "created_time": 0
  };
  values.forEach(function(v) {
    r.counters = hash_add(v.counters, r.counters);
    r.count++;
    r.created_time = v.created_time;
  });
  return r;
};

var finalize_hourly=function (key, value) {
  // for hourly we divide the counters by 12 (5 minutes per hour)
  var r = {
    "qps": hash_divide(value.counters, 12),
    "counters": value.counters,
    "count": value.count,
    "created_time": value.created_time
  };
  return r;
};

// pull the last sample_time from the DB
var last_processed_cur = db.mr_rescode_traffic_hourly_log.find({}, {
  last_processed_time: 1
}).sort({
  last_processed_time: -1
}).limit(1);

// this is where we store the mapreduce output
var mr_output;
var last_processed_time;

// if we have a previous set processed
if (last_processed_cur.hasNext()) {
  var last_processed = last_processed_cur.next();
  last_processed_time = last_processed.last_processed_time;

  print("Running mapreduce with: gt: " + last_processed_time + "\n");

  // Run mapReduce with the previous value
  /* mr_output = db.traffic.mapReduce(map_rescode_hourly, reduce_hourly, {
    query: {
      created_time: {
        $gt: last_processed_time
      }
    },
    out: {
      reduce: "rescode_traffic_hourly"
    },
    finalize: finalize_hourly
  });
  */

  mr_output=db.runCommand( { "mapreduce":"traffic",
  			      "map": map_rescode_hourly,
  			      "reduce": reduce_hourly,
  			      "query":{ "created_time": { $gt: last_processed_time }},
  			      "out": { reduce: "rescode_traffic_hourly" },
  			      "finalize":finalize_hourly
  			    });

} else {
  print("Running mapreduce for the first time!\n");

  // This is the first time running
 /* mr_output = db.traffic.mapReduce(map_rescode_hourly, reduce_hourly, {
    out: {
      reduce: "rescode_traffic_hourly"
    },
    finalize: finalize_hourly
  });
*/

mr_output=db.runCommand( { "mapreduce":"traffic",
 			      "map": map_rescode_hourly,
 			      "reduce": reduce_hourly,
 			      "out": "rescode_traffic_hourly",
 			      "finalize":finalize_hourly
 			    });

  // Create index
  db.rescode_traffic_hourly.ensureIndex({
    "_id.sample_time": 1,
    "_id.pubservhost": 1,
    "_id.zone": 1
  });

  // Index the created time field
  db.rescode_traffic_hourly.ensureIndex({
    created_time: 1
  });
}

if (mr_output.ok) {
  db.mr_rescode_traffic_hourly_log.insert({
    "last_processed_time": last_processed_time,
    "result": mr_output
  });
}

<commit_msg>added last_processed time<commit_after>/*
* Map Reduce procedure for the traffic collection hourly
*/

var map_rescode_hourly=function () {
  var date = new Date();
  date.setTime(this._id.sample_time);
  var sample_hour = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), 0, 0, 0);
  emit({
    "sample_time": sample_hour,
    "pubservhost": this._id.pubservhost,
    "zone": this._id.zone
  }, {
    "qps": {},
    "counters": this.qps,
    "count": 1,
    "created_time": this.created_time
  });
};

var reduce_hourly=function (key, values) {
  var r = {
    "qps": {},
    "counters": {},
    "count": 0,
    "created_time": 0
  };
  values.forEach(function(v) {
    r.counters = hash_add(v.counters, r.counters);
    r.count++;
    r.created_time = v.created_time;
  });
  return r;
};

var finalize_hourly=function (key, value) {
  // for hourly we divide the counters by 12 (5 minutes per hour)
  var r = {
    "qps": hash_divide(value.counters, 12),
    "counters": value.counters,
    "count": value.count,
    "created_time": value.created_time
  };
  return r;
};

// pull the last sample_time from the DB
var last_processed_cur = db.mr_rescode_traffic_hourly_log.find({}, {
  last_processed_time: 1
}).sort({
  last_processed_time: -1
}).limit(1);

// this is where we store the mapreduce output
var mr_output;
var last_processed_time;

// if we have a previous set processed
if (last_processed_cur.hasNext()) {
  var last_processed = last_processed_cur.next();
  last_processed_time = last_processed.last_processed_time;

  print("Running mapreduce with: gt: " + last_processed_time + "\n");

  // Run mapReduce with the previous value
  /* mr_output = db.traffic.mapReduce(map_rescode_hourly, reduce_hourly, {
    query: {
      created_time: {
        $gt: last_processed_time
      }
    },
    out: {
      reduce: "rescode_traffic_hourly"
    },
    finalize: finalize_hourly
  });
  */

  mr_output=db.runCommand( { "mapreduce":"traffic",
  			      "map": map_rescode_hourly,
  			      "reduce": reduce_hourly,
  			      "query":{ "created_time": { $gt: last_processed_time }},
  			      "out": { reduce: "rescode_traffic_hourly" },
  			      "finalize":finalize_hourly
  			    });

} else {
  print("Running mapreduce for the first time!\n");

  // This is the first time running
 /* mr_output = db.traffic.mapReduce(map_rescode_hourly, reduce_hourly, {
    out: {
      reduce: "rescode_traffic_hourly"
    },
    finalize: finalize_hourly
  });
*/

mr_output=db.runCommand( { "mapreduce":"traffic",
 			      "map": map_rescode_hourly,
 			      "reduce": reduce_hourly,
 			      "out": "rescode_traffic_hourly",
 			      "finalize":finalize_hourly
 			    });

  // Create index
  db.rescode_traffic_hourly.ensureIndex({
    "_id.sample_time": 1,
    "_id.pubservhost": 1,
    "_id.zone": 1
  });

  // Index the created time field
  db.rescode_traffic_hourly.ensureIndex({
    created_time: 1
  });
}

if (mr_output.ok) {
  var last_processed_cur=db.rescode_traffic_hourly.find({},{created_time:1}).sort({created_time:-1}).limit(1);
  var last_processed = last_processed_cur.next();
  last_processed_time = last_processed.last_processed_time;

  db.mr_rescode_traffic_hourly_log.insert({
    "last_processed_time": last_processed_time,
    "result": mr_output
  });
}

<|endoftext|>


<commit_before>/*globals define,_*/
/*
 * Copyright (C) 2013 Vanderbilt University, All rights reserved.
 *
 * @author brollb / https://github/brollb
 *
 * This file simply extends the features of the SVG that the panel
 * will support.
 *
 */

define(['js/Widgets/SnapEditor/SnapEditorWidget.Constants',
        '../Core/SVGDecorator.Core',
        '../Core/SVGDecorator.Connections'], function (SNAP_CONSTANTS,
                                                       SVGDecoratorCore,
                                                       SVGDecoratorConnections) {

    "use strict";

    var SVGDecorator = function (options) {
        var opts = _.extend( {}, options);

        SVGDecoratorCore.apply(this, [opts]);

        this.setConnectionAreaDefaults({'role': SNAP_CONSTANTS.CONN_RECEIVING,
                                        'ptr': '' });

    };

    _.extend(SVGDecorator.prototype, SVGDecoratorCore.prototype);
    _.extend(SVGDecorator.prototype, SVGDecoratorConnections.prototype);

    SVGDecorator.prototype.processCustomSvgData = function () {
        //Clean the line highlight data...
        var i = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT].length,
            line;

        while (i--){
            if (this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].tagName === 'line'){//Only support lines for now
                line = {};
                line.x1 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].x1.baseVal.value;
                line.x2 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].x2.baseVal.value;
                line.y1 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].y1.baseVal.value;
                line.y2 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].y2.baseVal.value;
                line.id = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].id;
                line.class = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].getAttribute('class');

                this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i] = line;
            } else {
                this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT].splice(i,1);
            }
        }

        //Record the default measurements for various stretch areas by ptrName
        var w = 0,
            h = 0;

        i = this[SNAP_CONSTANTS.INITIAL_MEASURE].length;
        while (i--){
            if (this[SNAP_CONSTANTS.INITIAL_MEASURE][i].tagName === 'line'){
                //get line values
                line = {};
                line.x1 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].x1.baseVal.value;
                line.x2 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].x2.baseVal.value;
                line.y1 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].y1.baseVal.value;
                line.y2 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].y2.baseVal.value;

                //Record the measurements
                w = line.x2 - line.x1;
                h = line.y2 - line.y1;
            } else if (this[SNAP_CONSTANTS.INITIAL_MEASURE][i].tagName === 'rect'){
                w = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].width.baseVal.value;
                h = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].height.baseVal.value;
            }

            this.svgInitialStretch[this[SNAP_CONSTANTS.INITIAL_MEASURE][i].getAttribute('data-ptr')] = { x: w, y: h };
        }
    };

    return SVGDecorator;

});
<commit_msg>Added support for processing input fields from svg<commit_after>/*globals define,_*/
/*
 * Copyright (C) 2013 Vanderbilt University, All rights reserved.
 *
 * @author brollb / https://github/brollb
 *
 * This file simply extends the features of the SVG that the panel
 * will support.
 *
 */

define(['js/Widgets/SnapEditor/SnapEditorWidget.Constants',
        '../Core/SVGDecorator.Core',
        '../Core/SVGDecorator.Connections'], function (SNAP_CONSTANTS,
                                                       SVGDecoratorCore,
                                                       SVGDecoratorConnections) {

    "use strict";

    /**
     * SVGDecorator constructor
     *
     * @constructor
     * @param {Object} options
     */
    var SVGDecorator = function (options) {
        var opts = _.extend( {}, options);

        SVGDecoratorCore.apply(this, [opts]);

        this.setConnectionAreaDefaults({'role': SNAP_CONSTANTS.CONN_RECEIVING,
                                        'ptr': '' });

    };

    _.extend(SVGDecorator.prototype, SVGDecoratorCore.prototype);
    _.extend(SVGDecorator.prototype, SVGDecoratorConnections.prototype);

    /**
     * Process the custom data retrieved from the svg.
     *
     * @return {undefined}
     */
    SVGDecorator.prototype.processCustomSvgData = function () {
        var customDataElement;

        //Clean the line highlight data...
        var i = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT].length,
            line;

        while (i--){
            if (this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].tagName === 'line'){//Only support lines for now
                line = {};
                line.x1 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].x1.baseVal.value;
                line.x2 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].x2.baseVal.value;
                line.y1 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].y1.baseVal.value;
                line.y2 = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].y2.baseVal.value;
                line.id = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].id;
                line.class = this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i].getAttribute('class');

                this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT][i] = line;
            } else {
                this[SNAP_CONSTANTS.CONNECTION_HIGHLIGHT].splice(i,1);
            }
        }

        //Record the default measurements for various stretch areas by ptrName
        var w = 0,
            h = 0;

        i = this[SNAP_CONSTANTS.INITIAL_MEASURE].length;
        while (i--){
            if (this[SNAP_CONSTANTS.INITIAL_MEASURE][i].tagName === 'line'){
                //get line values
                line = {};
                line.x1 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].x1.baseVal.value;
                line.x2 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].x2.baseVal.value;
                line.y1 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].y1.baseVal.value;
                line.y2 = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].y2.baseVal.value;

                //Record the measurements
                w = line.x2 - line.x1;
                h = line.y2 - line.y1;
            } else if (this[SNAP_CONSTANTS.INITIAL_MEASURE][i].tagName === 'rect'){
                w = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].width.baseVal.value;
                h = this[SNAP_CONSTANTS.INITIAL_MEASURE][i].height.baseVal.value;
            }

            this.svgInitialStretch[this[SNAP_CONSTANTS.INITIAL_MEASURE][i].getAttribute('data-ptr')] = { x: w, y: h };

        }

        //Find the input areas and store them
        var type,
            attribute,
            content,
            target,
            input,
            x,
            y;

        //DOM section for input fields
        this.inputFieldUpdates = {};//input field updates to receive
        this.inputFields = {};
        this._inputFields2Update = {};

        for (i = this[SNAP_CONSTANTS.INPUT_FIELDS].length-1; i >=0; i--){
            customDataElement = this[SNAP_CONSTANTS.INPUT_FIELDS][i];
            //Populate input fields
            type = customDataElement.getAttribute('data-type');
            attribute = customDataElement.getAttribute('data-attribute');

            //Get location and size of the inputField
            x = parseFloat(customDataElement.getAttribute('x'));
            y = parseFloat(customDataElement.getAttribute('y'));
            w = parseFloat(customDataElement.getAttribute('width'));
            h = parseFloat(customDataElement.getAttribute('height'));

            //Get the content
            switch (type) {
                case SNAP_CONSTANTS.TEXT_FIELD.NAME:
                    input = $('<input type="text"/>');
                    content = SNAP_CONSTANTS.TEXT_FIELD.CONTENT.TEXT;
                    break;

                case SNAP_CONSTANTS.DROPDOWN.NAME:
                    input = $('<select/>');
                    content = customDataElement.getAttribute('data-content');
                    target = customDataElement.getAttribute('data-target');
                    break;

                default:
                this.logger.warn("Will not be able to populate dropdown menu for " + attribute);
            }

            //Create the record the update
            this.inputFieldUpdates[attribute] = { content: content, type: type };

            if (target){
                this.inputFieldUpdates[attribute].target = target;
            }

            //Create the data record
            this.inputFields[attribute] = { x: x, y: y, width: w, height: h, type: type, visible: true};

            //Add item to list of items to update
            this._inputFields2Update[attribute] = true;
        }
    };

    return SVGDecorator;

});
<|endoftext|>


<commit_before>function tinymce_init(selector) {
  var tinymce_config = {
    {% for key, value in callbacks.items %}
      '{{ key }}': {{ value|safe }},
    {% empty %}
    {% endfor %}
    {{ tinymce_config|safe }}
  };
  if (typeof selector != 'undefined') {
    tinymce_config['selector'] = selector;
  }
  tinyMCE.init(tinymce_config);
}
{% if not is_admin_inline %}
tinymce_init();
{% else %}
(function($) {
  $(document).off('formset:added').on('formset:added', function(event, $row, formsetName) {
    $('div#' + $row['0'].id + ' .tinymce4_editor').each(function(i, elem) {
      tinymce_init(elem.tagName + '#' + elem.id);
    });
  });
})(django.jQuery);
{% endif %}
<commit_msg>Refactor tinymce_init.js template<commit_after>(function($) {
  function tinymce_init(selector) {
    var tinymce_config = {
      {% for key, value in callbacks.items %}
        '{{ key }}': {{ value|safe }},
      {% empty %}
      {% endfor %}
      {{ tinymce_config|safe }}
    };
    if (typeof selector != 'undefined') {
      tinymce_config['selector'] = selector;
    }
    tinymce.init(tinymce_config);
  }
{% if not is_admin_inline %}
  tinymce_init();
})();
{% else %}
  // Add an event listener to initialise TinyMCE editors in
  // the new inline formset in Django admin.
  $(document).on('formset:added', function(event, $row, formsetName) {
    $row.find('.tinymce4_editor').each(function(i, elem) {
      tinymce_init(elem.tagName + '#' + elem.id);
    });
  });
  // Add and event listener to remove TinyMCE editors from the removed formset.
  $(document).on('formset:removed', function(event, $row, formsetName) {
    $row.find('.tinymce4_editor').each(function(i, elem) {
      var i;
      for (i = 0; tinymce.EditorManager.editors.length; i++) {
        if (tinymce.EditorManager.editors[i].id == elem.id) {
          tinymce.EditorManager.editors[i].remove();
          break;
        }
      }
    });
  });
})(django.jQuery);
{% endif %}
<|endoftext|>


<commit_before>$(function(){
    var originalFunction = SaveNewImageButton_Click;
    var originalFunctionString = SaveNewImageButton_Click.toString();
    var patchedFunctionString = originalFunctionString.replace("if (workEnd > new Date())", "if (workEnd != workEnd)").replace("function SaveNewImageButton_Click()", "function()");
    SaveNewImageButton_Click = eval("(" + patchedFunctionString + ")");
    var saveNewTSRecordOriginalFunction = saveNewTSRecord;
    var saveNewTSRecordFunctionString = saveNewTSRecord.toString();
    var patchedSaveNewTSRecordFunctionString = saveNewTSRecordFunctionString.replace("var sComment = tbComment.text();", "var sComment = tbComment.val();");
    saveNewTSRecord = eval("(" + patchedSaveNewTSRecordFunctionString + ")");
    var CreatePendingRecordOriginalFunction = CreatePendingRecord;
    var CreatePendingRecordFunctionString = CreatePendingRecord.toString();
    var patchedCreatePendingRecordFunctionString = CreatePendingRecordFunctionString.replace("$('#MasterPage_ContentPlaceHolder1_CommentTextBoxNew').text();", "$('#MasterPage_ContentPlaceHolder1_CommentTextBoxNew').val();");
    CreatePendingRecord = eval("(" + patchedCreatePendingRecordFunctionString + ")");
    //showThickbox("ThickBox1", "You can now log work against time in the future, with descriptions on Chrome! ;)");
    $("div#HomeContent span#MasterPage_PageTitleSuffix").html($("div#HomeContent span#MasterPage_PageTitleSuffix").text() + " (God Mode)");

    var lbBackToSummary_ClickOriginalFunction = lbBackToSummary_Click;
    var lbBackToSummary_ClickFunctionString = lbBackToSummary_Click.toString();
    var patchedlbBackToSummary_ClickFunctionString = lbBackToSummary_ClickFunctionString.replace("iDays: 5","iDays: window.$iDays");
    lbBackToSummary_Click = eval("(" + patchedlbBackToSummary_ClickFunctionString + ")");

    window.$iDays = 5;
    //$("form").prepend('

Number of days:<input type="text" id="duration" name="duration" value="5">Fetch

');
    $("#Menu").append('
Fetch data for days:<input type="text" id="duration" name="duration" value="5">Fetch
');
    $("#getrecords").click(function(e){
        window.$iDays = $("#duration").val();
        lbBackToSummary_Click();
        console.log("Fetching data for days: "+window.$iDays);
        $(document).ajaxComplete(function() {
            expandRecords();
        });
    });
    expandRecords();
});

function expandRecords(){
    var items = $("#TimesheetList a");
    for(var i=0;i<items.length;i++){
        if(i%2==0) {
            $(items[i])[0].click();
        }
    }
}<commit_msg>Updated the span label on the portal based on the days fetched.<commit_after>$(function(){
    var originalFunction = SaveNewImageButton_Click;
    var originalFunctionString = SaveNewImageButton_Click.toString();
    var patchedFunctionString = originalFunctionString.replace("if (workEnd > new Date())", "if (workEnd != workEnd)").replace("function SaveNewImageButton_Click()", "function()");
    SaveNewImageButton_Click = eval("(" + patchedFunctionString + ")");
    var saveNewTSRecordOriginalFunction = saveNewTSRecord;
    var saveNewTSRecordFunctionString = saveNewTSRecord.toString();
    var patchedSaveNewTSRecordFunctionString = saveNewTSRecordFunctionString.replace("var sComment = tbComment.text();", "var sComment = tbComment.val();");
    saveNewTSRecord = eval("(" + patchedSaveNewTSRecordFunctionString + ")");
    var CreatePendingRecordOriginalFunction = CreatePendingRecord;
    var CreatePendingRecordFunctionString = CreatePendingRecord.toString();
    var patchedCreatePendingRecordFunctionString = CreatePendingRecordFunctionString.replace("$('#MasterPage_ContentPlaceHolder1_CommentTextBoxNew').text();", "$('#MasterPage_ContentPlaceHolder1_CommentTextBoxNew').val();");
    CreatePendingRecord = eval("(" + patchedCreatePendingRecordFunctionString + ")");
    //showThickbox("ThickBox1", "You can now log work against time in the future, with descriptions on Chrome! ;)");
    $("div#HomeContent span#MasterPage_PageTitleSuffix").html($("div#HomeContent span#MasterPage_PageTitleSuffix").text() + " (God Mode)");

    var lbBackToSummary_ClickOriginalFunction = lbBackToSummary_Click;
    var lbBackToSummary_ClickFunctionString = lbBackToSummary_Click.toString();
    var patchedlbBackToSummary_ClickFunctionString = lbBackToSummary_ClickFunctionString.replace("iDays: 5","iDays: window.$iDays");
    lbBackToSummary_Click = eval("(" + patchedlbBackToSummary_ClickFunctionString + ")");

    window.$iDays = 5;
    $("#Menu").append('
Fetch data for days:<input type="text" id="duration" name="duration" value="5">Fetch
');
    $("#getrecords").click(function(e){
        window.$iDays = $("#duration").val();
        lbBackToSummary_Click();
        console.log("Fetching data for days: "+window.$iDays);
        $(document).ajaxComplete(function() {
            expandRecords();
        });
    });
    expandRecords();
});

function expandRecords(){
    $("#MasterPage_ContentPlaceHolder1_pnlSummary span").html(window.$iDays + " Day Summary");
    var items = $("#TimesheetList a");
    for(var i=0;i<items.length;i++){
        if(i%2==0) {
            $(items[i])[0].click();
        }
    }
}<|endoftext|>


<commit_before>Kwf.onContentReady(function(el) {
    Ext.fly(el).query('a').forEach(function(a) {
        var m = a.rel.match(/kwfViewAjaxFilter({.*?})/)
        if (m) {
            if (a.kwfViewAjaxInitDone) return;
            a.kwfViewAjaxInitDone = true;
            var config = Ext.decode(m[1]);

            if (!Kwc.Directories.List.ViewAjax.filterLinks[config.viewComponentId]) Kwc.Directories.List.ViewAjax.filterLinks[config.viewComponentId] = [];
            Kwc.Directories.List.ViewAjax.filterLinks[config.viewComponentId].push(a);

            Ext.fly(a).on('click', function(ev) {
                var view = Kwc.Directories.List.ViewAjax.byDirectoryViewComponentId[this.config.viewComponentId];
                if (!view) return
                view.loadView({
                    filterComponentId: this.config.componentId
                });
                if (view._getState().viewFilter != this.config.componentId) {
                    view._getState().viewFilter = this.config.componentId;
                    view._getState().menuLinkId = a.id;
                    Kwf.Utils.HistoryState.pushState(document.title, a.href);
                }
                Kwc.Directories.List.ViewAjax.filterLinks[this.config.viewComponentId].forEach(function(i) {
                    Ext.fly(i).removeClass('current');
                }, this);
                Ext.fly(a).addClass('current');

                ev.stopEvent();

            }, {config: config});
        }
    }, this);
});

Kwf.onElementReady('.kwcDirectoriesListViewAjax', function(el, config) {
    config.renderTo = el.down('.viewContainer');
    el.select('.kwcDirectoriesListViewAjaxPaging').remove(); //remove paging, we will do endless scrolling instead
    el.kwcViewAjax = new Kwc.Directories.List.ViewAjax(config);
}, this, {
    priority: 0 //call *after* initializing kwcForm to have access to searchForm
});

Ext.ns('Kwc.Directories.List');
Kwc.Directories.List.ViewAjax = Ext.extend(Ext.Panel, {

    controllerUrl: null,

    directoryUrl: null, //needed to implement back-link in detail without page load

    border: false,
    layout: 'fit',
    cls: 'posts',
    initComponent: function() {
        Kwc.Directories.List.ViewAjax.byComponentId[this.componentId] = this;
        Kwc.Directories.List.ViewAjax.byDirectoryViewComponentId[this.directoryViewComponentId] = this;
        this.view = new Kwc.Directories.List.ViewAjax.View({
            controllerUrl: this.controllerUrl,
            directoryUrl: this.directoryUrl,
            directoryComponentId: this.directoryComponentId,
            baseParams: {
                componentId: this.componentId
            },
            placeholder: this.placeholder
        });
        this.items = [this.view];

        this.renderTo.select('.noEntriesFound').remove(); //view renders own

        var records = [];
        this.renderTo.select('.kwfViewAjaxItem').each(function(el) {
            var id = el.dom.className.match(/kwfViewAjaxItem ([^ ]+)/);
            if (id) {
                id = id[1];
                records.push(new this.view.store.recordType({
                    id: id,
                    content: el.dom.innerHTML
                }));
            }
            el.remove();
        }, this);
        this.view.store.add(records);

        if (this.searchFormComponentId) {
            this.searchForm = Kwc.Form.formsByComponentId[this.searchFormComponentId];
        }

        if (this.searchForm) {

            this.view.applyBaseParams(this.searchForm.getValues());

            this.searchForm.on('fieldChange', function(f) {

                if (f instanceof Kwf.FrontendForm.Field && f.getValue().length < 3) return; //minimum length

                var values = this.searchForm.getValues();
                var diffFound = false;
                for(var i in values) {
                    if (values[i] != this.view.getBaseParams()[i]) {
                        diffFound = true;
                        break;
                    }
                }
                if (diffFound) {
                    this.view.applyBaseParams(values);
                    this.view.load();
                    this.addHistoryEntryDeleayedTask.delay(2000);
                }
            }, this, { buffer: 500 });

            this.searchForm.on('beforeSubmit', function(f) {
                var values = this.searchForm.getValues();
                this.view.applyBaseParams(values);
                this.view.load();
                this.pushSearchFormHistoryState();
                return false;
            }, this);

            this.addHistoryEntryDeleayedTask = new Ext.util.DelayedTask(function() {
                this.pushSearchFormHistoryState();
            }, this);
        }

        Kwf.Utils.HistoryState.currentState[this.componentId] = {};

        if (this.searchForm) {
            Kwf.Utils.HistoryState.currentState[this.componentId].searchFormValues = this.searchForm.getValues();
        }

        if (!Kwc.Directories.List.ViewAjax.filterLinks[this.componentId]) {
            Kwc.Directories.List.ViewAjax.filterLinks[this.componentId] = [];
        }

        //set menuLinkId to link that is current, be be able to set current again
        Kwc.Directories.List.ViewAjax.filterLinks[this.componentId].forEach(function(i) {
            if (Ext.fly(i).hasClass('current')) {
                Kwf.Utils.HistoryState.currentState[this.componentId].menuLinkId = i.id;
            }
        }, this);

        if (this.filterComponentId) {
            Kwf.Utils.HistoryState.currentState[this.componentId].viewFilter = this.filterComponentId;
            this.view.applyBaseParams({
                filterComponentId: this.filterComponentId
            });
            delete this.filterComponentId;
        }

        Kwf.Utils.HistoryState.updateState();

        Kwf.Utils.HistoryState.on('popstate', function() {
            if (!this._getState()) return;
            if (this.searchForm) {
                this.searchForm.setValues(this._getState().searchFormValues);
            }
            if (this._getState().viewDetail) {
                this.showDetail(this._getState().viewDetail);
            } else if (this._getState().viewFilter) {
                this.loadView({
                    filterComponentId: this._getState().viewFilter
                });
            } else {
                this.loadView({});
            }
            if (this._getState().menuLinkId) {
                Kwc.Directories.List.ViewAjax.filterLinks[this.componentId].forEach(function(i) {
                    Ext.fly(i).removeClass('current');
                }, this);
                var el = Ext.fly(this._getState().menuLinkId);
                if (el) {
                    el.addClass('current');
                }
            }
        }, this);

        Kwc.Directories.List.ViewAjax.superclass.initComponent.call(this);
    },

    afterRender: function() {
        Kwc.Directories.List.ViewAjax.superclass.afterRender.call(this);

        this.initialLoadingEl = this.el.createChild({cls:'initialLoading'});
        this.initialLoadingEl.enableDisplayMode();

        this.onMenuItemChanged();
    },

    pushSearchFormHistoryState: function()
    {
        this.addHistoryEntryDeleayedTask.cancel();
        this._getState().searchFormValues = this.searchForm.getValues();
        var url = location.protocol+'//'+location.host+this.viewUrl+'?'+Ext.urlEncode(this.searchForm.getValuesIncludingPost());
        Kwf.Utils.HistoryState.pushState(document.title, url);
    },

    onMenuItemChanged: function()
    {
        /*
        this.blockReload = true; //for filter changevalue so they won't reload too
        if (this.searchForm) {
            this.searchForm.clearValues();
        }
        this.blockReload = false;
        */
    },

    _getState: function()
    {
        return Kwf.Utils.HistoryState.currentState[this.componentId];
    },

    loadView: function(p)
    {
        var params = Ext.applyIf(p, {
            filterComponentId: null
        });
        if (this.searchForm) {
            Ext.apply(params, this.searchForm.getValues());
        }
        var diffFound = false;
        for(var i in params) {
            if (params[i] != this.view.getBaseParams()[i]) {
                diffFound = true;
                break;
            }
        }
        if (diffFound) {
            this.view.applyBaseParams(params);
            this.view.load();
        }
        this.onMenuItemChanged();
        this.view.showView();
    },

    showSearch: function(q)
    {
        this.loadView('search', { query: q });
    },

    showDetail: function(id) {
        this.view.showDetail(id);
    }

});

Kwc.Directories.List.ViewAjax.byComponentId = {};
Kwc.Directories.List.ViewAjax.byDirectoryViewComponentId = {};
Kwc.Directories.List.ViewAjax.filterLinks = {};

Kwc.Directories.List.ViewAjax.View = Ext.extend(Kwf.Binding.AbstractPanel,
{
    layout: 'fit',
    border: false,
    autoHeight: true,

    initComponent : function()
    {
        if (!this.tpl) {
            this.tpl = new Ext.XTemplate(
                '<tpl for=".">',
                    '
{content}
',
                '</tpl>'
            );
        }

        this.store = new Ext.data.Store({
            proxy: new Ext.data.HttpProxy({ url: this.controllerUrl + '/json-data' }),
            reader: new Ext.data.JsonReader({
                totalProperty: 'total',
                root: 'rows',
                id: 'id',
                sucessProperty: 'success',
                fields: [{
                    name: 'content'
                },{
                    name: 'id'
                }]
            }),
            remoteSort: true,
            pruneModifiedRecords: true
        });
        if (this.baseParams) {
            this.setBaseParams(this.baseParams);
            delete this.baseParams;
        }

        this.store.newRecords = []; //hier werden neue records gespeichert die nicht dirty sind

        this.store.on('loadexception', function(proxy, o, response, e) {
            throw e; //re-throw
        }, this);

        var viewConfig = {
            store: this.store,
            tpl: this.tpl,
            cls: 'kwfView',
            itemSelector: 'div.kwfViewAjaxItem',
            emptyText: ''+this.placeholder.noEntriesFound+'',
            deferEmptyText: false,
            singleSelect: false,
            border: false,
            autoHeight: true
        };

        this.view = new Ext.DataView(viewConfig);
        this.view.updateIndexes = this.view.updateIndexes.createSequence(function() {
            Kwf.callOnContentReady(this.view.el);
        }, this);

        this.view.on('click', this.onItemClick, this);

        this.items = [ this.view ];

        Kwc.Directories.List.ViewAjax.View.superclass.initComponent.call(this);

        Ext.fly(window).on('scroll', function() {
            var height = this.el.getTop()+this.el.getHeight();
            height -= Ext.getBody().getViewSize().height;
            height = height - Ext.getBody().getScroll().top;
            if (height < 700) {
                this.loadMore();
            }
        }, this, { buffer: 50 });
    },

    afterRender: function() {
        Kwc.Directories.List.ViewAjax.View.superclass.afterRender.call(this);

        this.kwfMainContent = this.el.parent('.kwfMainContent');
        if (this.kwfMainContent) {
            this.kwfMainContent.enableDisplayMode('block');
        }
    },

    loadMore: function() {
        if (!this.store || this.getStore().getCount()<20 || this.loadingMore || this.visibleDetail) return;
        this.loadingMore = true;
        this.body.addClass('loadingMore');
        this.getStore().load({
            params: {
                start: this.getStore().getCount(),
                limit: 10
            },
            add: true,
            callback: function(rows) {
                this.body.removeClass('loadingMore');
                if (rows.length) { //wenn nichts geladen sind wir bereits am ende
                    this.loadingMore = false;
                }
            },
            scope: this
        });
    },

    getStore : function() {
        return this.store;
    },

    //für AbstractPanel
    reset: function() {
        if (this.getStore()) {
            this.getStore().modified = [];
            this.getStore().newRecords = [];
        }
    },

    reload: function(options) {
        if (this.getStore()) {
            this.getStore().reload(options);
            this.getStore().commitChanges();
        }
    },

    load : function(params) {
        if (!params) params = {};
        if (!params.start) {
            params.start = 0;
        }
        if (this.el) this.el.mask('', 'loading');
        this.getStore().load({
            params: params,
            callback: function() {
                if (this.el) this.el.unmask();
            },
            scope: this
        });
    },

    getStore : function() {
        return this.store;
    },
    getBaseParams : function() {
        if (this.getStore()) {
            return this.getStore().baseParams;
        } else {
            return this.baseParams || {};
        }
    },
    setBaseParams : function(baseParams) {
        if (this.getStore()) {
            this.getStore().baseParams = baseParams;
        } else {
            //no store yet, apply them later
            this.baseParams = baseParams;
        }
    },
    applyBaseParams : function(baseParams) {
        if (this.getStore()) {
            Ext.apply(this.getStore().baseParams, baseParams);
        } else {
            //no store yet, apply them later
            if (!this.baseParams) this.baseParams = {};
            Ext.apply(this.baseParams, baseParams);
        }
    },

    onItemClick: function(view, number, target, ev) {
        var row = this.store.getAt(number);
        var target = Ext.get(ev.getTarget());
        if (target.dom.tagName.toLowerCase() != 'a') target = target.up('a');
        if (!target) return;
        var m = target.dom.rel.match(/kwfDetail([^ ]+)/);
        if (!m) return;
        var config = Ext.decode(m[1]);
        if (!config.directoryComponentId) return;
        if (config.directoryComponentId != this.directoryComponentId) return;

        ev.stopEvent();
        //more... Link clicked
        this.showDetail(target.dom.href);
    },

    hideDetail: function()
    {
        if (this.detailEl) {
            this.detailEl.remove();
            this.detailEl = null;
        }
    },

    showDetail: function(href)
    {
        if (this.visibleDetail == href) return;
        this.visibleDetail = href;

        if (this.ownerCt._getState().viewDetail != href) {
            this.ownerCt._getState().viewDetail = href;
            Kwf.Utils.HistoryState.pushState(document.title, href);
        }

        this.hideDetail();

        this.classNames = this.el.up('.kwcDirectoriesListViewAjax').dom.className;

        this.kwfMainContent.hide();
        this.detailEl = this.el.createChild({
            cls: 'kwfMainContent loadingContent ' +this.classNames,
            tag: 'div',
            style: 'width: ' + this.kwfMainContent.getStyle('width'),
            html: '

'
        }, this.kwfMainContent);
        var url = '/kwf/util/kwc/render';
        if (Kwf.Debug.rootFilename) url = Kwf.Debug.rootFilename + url;
        Ext.Ajax.request({
            url: url,
            params: { url: href },
            success: function(response, options) {
                if (!this.detailEl) return;
                this.detailEl.removeClass('loadingContent '+this.classNames);
                this.detailEl.update(response.responseText);

                this.detailEl.query('a').forEach(function(el) {
                    if (el.href == location.protocol+'//'+location.host+this.directoryUrl) {
                        el.kwfViewAjaxInitDone = true;
                        Ext.fly(el).on('click', function(ev) {
                            ev.stopEvent();
                            if (history.length > 1) {
                                history.back(); //keeps scroll position
                            } else {
                                this.showView();
                            }
                        }, this);
                    }
                }, this);

                Kwf.callOnContentReady(this.detailEl);
            },
            scope: this
        });
    },

    showView: function() {
        if (!this.visibleDetail) return;
        this.visibleDetail = null;

        this.hideDetail();

        this.kwfMainContent.show();

        this.ownerCt.onMenuItemChanged();
    }
});

<commit_msg>statistic count for ajaxview<commit_after>Kwf.onContentReady(function(el) {
    Ext.fly(el).query('a').forEach(function(a) {
        var m = a.rel.match(/kwfViewAjaxFilter({.*?})/)
        if (m) {
            if (a.kwfViewAjaxInitDone) return;
            a.kwfViewAjaxInitDone = true;
            var config = Ext.decode(m[1]);

            if (!Kwc.Directories.List.ViewAjax.filterLinks[config.viewComponentId]) Kwc.Directories.List.ViewAjax.filterLinks[config.viewComponentId] = [];
            Kwc.Directories.List.ViewAjax.filterLinks[config.viewComponentId].push(a);

            Ext.fly(a).on('click', function(ev) {
                var view = Kwc.Directories.List.ViewAjax.byDirectoryViewComponentId[this.config.viewComponentId];
                if (!view) return
                view.loadView({
                    filterComponentId: this.config.componentId
                });
                if (view._getState().viewFilter != this.config.componentId) {
                    view._getState().viewFilter = this.config.componentId;
                    view._getState().menuLinkId = a.id;
                    Kwf.Utils.HistoryState.pushState(document.title, a.href);
                }
                Kwc.Directories.List.ViewAjax.filterLinks[this.config.viewComponentId].forEach(function(i) {
                    Ext.fly(i).removeClass('current');
                }, this);
                Ext.fly(a).addClass('current');

                ev.stopEvent();

            }, {config: config});
        }
    }, this);
});

Kwf.onElementReady('.kwcDirectoriesListViewAjax', function(el, config) {
    config.renderTo = el.down('.viewContainer');
    el.select('.kwcDirectoriesListViewAjaxPaging').remove(); //remove paging, we will do endless scrolling instead
    el.kwcViewAjax = new Kwc.Directories.List.ViewAjax(config);
}, this, {
    priority: 0 //call *after* initializing kwcForm to have access to searchForm
});

Ext.ns('Kwc.Directories.List');
Kwc.Directories.List.ViewAjax = Ext.extend(Ext.Panel, {

    controllerUrl: null,

    directoryUrl: null, //needed to implement back-link in detail without page load

    border: false,
    layout: 'fit',
    cls: 'posts',
    initComponent: function() {
        Kwc.Directories.List.ViewAjax.byComponentId[this.componentId] = this;
        Kwc.Directories.List.ViewAjax.byDirectoryViewComponentId[this.directoryViewComponentId] = this;
        this.view = new Kwc.Directories.List.ViewAjax.View({
            controllerUrl: this.controllerUrl,
            directoryUrl: this.directoryUrl,
            directoryComponentId: this.directoryComponentId,
            baseParams: {
                componentId: this.componentId
            },
            placeholder: this.placeholder
        });
        this.items = [this.view];

        this.renderTo.select('.noEntriesFound').remove(); //view renders own

        var records = [];
        this.renderTo.select('.kwfViewAjaxItem').each(function(el) {
            var id = el.dom.className.match(/kwfViewAjaxItem ([^ ]+)/);
            if (id) {
                id = id[1];
                records.push(new this.view.store.recordType({
                    id: id,
                    content: el.dom.innerHTML
                }));
            }
            el.remove();
        }, this);
        this.view.store.add(records);

        if (this.searchFormComponentId) {
            this.searchForm = Kwc.Form.formsByComponentId[this.searchFormComponentId];
        }

        if (this.searchForm) {

            this.view.applyBaseParams(this.searchForm.getValues());

            this.searchForm.on('fieldChange', function(f) {

                if (f instanceof Kwf.FrontendForm.Field && f.getValue().length < 3) return; //minimum length

                var values = this.searchForm.getValues();
                var diffFound = false;
                for(var i in values) {
                    if (values[i] != this.view.getBaseParams()[i]) {
                        diffFound = true;
                        break;
                    }
                }
                if (diffFound) {
                    this.view.applyBaseParams(values);
                    this.view.load();
                    this.addHistoryEntryDeleayedTask.delay(2000);
                }
            }, this, { buffer: 500 });

            this.searchForm.on('beforeSubmit', function(f) {
                var values = this.searchForm.getValues();
                this.view.applyBaseParams(values);
                this.view.load();
                this.pushSearchFormHistoryState();
                return false;
            }, this);

            this.addHistoryEntryDeleayedTask = new Ext.util.DelayedTask(function() {
                this.pushSearchFormHistoryState();
            }, this);
        }

        Kwf.Utils.HistoryState.currentState[this.componentId] = {};

        if (this.searchForm) {
            Kwf.Utils.HistoryState.currentState[this.componentId].searchFormValues = this.searchForm.getValues();
        }

        if (!Kwc.Directories.List.ViewAjax.filterLinks[this.componentId]) {
            Kwc.Directories.List.ViewAjax.filterLinks[this.componentId] = [];
        }

        //set menuLinkId to link that is current, be be able to set current again
        Kwc.Directories.List.ViewAjax.filterLinks[this.componentId].forEach(function(i) {
            if (Ext.fly(i).hasClass('current')) {
                Kwf.Utils.HistoryState.currentState[this.componentId].menuLinkId = i.id;
            }
        }, this);

        if (this.filterComponentId) {
            Kwf.Utils.HistoryState.currentState[this.componentId].viewFilter = this.filterComponentId;
            this.view.applyBaseParams({
                filterComponentId: this.filterComponentId
            });
            delete this.filterComponentId;
        }

        Kwf.Utils.HistoryState.updateState();

        Kwf.Utils.HistoryState.on('popstate', function() {
            if (!this._getState()) return;
            if (this.searchForm) {
                this.searchForm.setValues(this._getState().searchFormValues);
            }
            if (this._getState().viewDetail) {
                this.showDetail(this._getState().viewDetail);
            } else if (this._getState().viewFilter) {
                this.loadView({
                    filterComponentId: this._getState().viewFilter
                });
            } else {
                this.loadView({});
            }
            if (this._getState().menuLinkId) {
                Kwc.Directories.List.ViewAjax.filterLinks[this.componentId].forEach(function(i) {
                    Ext.fly(i).removeClass('current');
                }, this);
                var el = Ext.fly(this._getState().menuLinkId);
                if (el) {
                    el.addClass('current');
                }
            }
        }, this);

        Kwc.Directories.List.ViewAjax.superclass.initComponent.call(this);
    },

    afterRender: function() {
        Kwc.Directories.List.ViewAjax.superclass.afterRender.call(this);

        this.initialLoadingEl = this.el.createChild({cls:'initialLoading'});
        this.initialLoadingEl.enableDisplayMode();

        this.onMenuItemChanged();
    },

    pushSearchFormHistoryState: function()
    {
        this.addHistoryEntryDeleayedTask.cancel();
        this._getState().searchFormValues = this.searchForm.getValues();
        var url = location.protocol+'//'+location.host+this.viewUrl+'?'+Ext.urlEncode(this.searchForm.getValuesIncludingPost());
        Kwf.Utils.HistoryState.pushState(document.title, url);
    },

    onMenuItemChanged: function()
    {
        /*
        this.blockReload = true; //for filter changevalue so they won't reload too
        if (this.searchForm) {
            this.searchForm.clearValues();
        }
        this.blockReload = false;
        */
    },

    _getState: function()
    {
        return Kwf.Utils.HistoryState.currentState[this.componentId];
    },

    loadView: function(p)
    {
        var params = Ext.applyIf(p, {
            filterComponentId: null
        });
        if (this.searchForm) {
            Ext.apply(params, this.searchForm.getValues());
        }
        var diffFound = false;
        for(var i in params) {
            if (params[i] != this.view.getBaseParams()[i]) {
                diffFound = true;
                break;
            }
        }
        if (diffFound) {
            this.view.applyBaseParams(params);
            this.view.load();
        }
        this.onMenuItemChanged();
        this.view.showView();
    },

    showSearch: function(q)
    {
        this.loadView('search', { query: q });
    },

    showDetail: function(id) {
        this.view.showDetail(id);
    }

});

Kwc.Directories.List.ViewAjax.byComponentId = {};
Kwc.Directories.List.ViewAjax.byDirectoryViewComponentId = {};
Kwc.Directories.List.ViewAjax.filterLinks = {};

Kwc.Directories.List.ViewAjax.View = Ext.extend(Kwf.Binding.AbstractPanel,
{
    layout: 'fit',
    border: false,
    autoHeight: true,

    initComponent : function()
    {
        if (!this.tpl) {
            this.tpl = new Ext.XTemplate(
                '<tpl for=".">',
                    '
{content}
',
                '</tpl>'
            );
        }

        this.store = new Ext.data.Store({
            proxy: new Ext.data.HttpProxy({ url: this.controllerUrl + '/json-data' }),
            reader: new Ext.data.JsonReader({
                totalProperty: 'total',
                root: 'rows',
                id: 'id',
                sucessProperty: 'success',
                fields: [{
                    name: 'content'
                },{
                    name: 'id'
                }]
            }),
            remoteSort: true,
            pruneModifiedRecords: true
        });
        if (this.baseParams) {
            this.setBaseParams(this.baseParams);
            delete this.baseParams;
        }

        this.store.newRecords = []; //hier werden neue records gespeichert die nicht dirty sind

        this.store.on('loadexception', function(proxy, o, response, e) {
            throw e; //re-throw
        }, this);

        var viewConfig = {
            store: this.store,
            tpl: this.tpl,
            cls: 'kwfView',
            itemSelector: 'div.kwfViewAjaxItem',
            emptyText: ''+this.placeholder.noEntriesFound+'',
            deferEmptyText: false,
            singleSelect: false,
            border: false,
            autoHeight: true
        };

        this.view = new Ext.DataView(viewConfig);
        this.view.updateIndexes = this.view.updateIndexes.createSequence(function() {
            Kwf.callOnContentReady(this.view.el);
        }, this);

        this.view.on('click', this.onItemClick, this);

        this.items = [ this.view ];

        Kwc.Directories.List.ViewAjax.View.superclass.initComponent.call(this);

        Ext.fly(window).on('scroll', function() {
            var height = this.el.getTop()+this.el.getHeight();
            height -= Ext.getBody().getViewSize().height;
            height = height - Ext.getBody().getScroll().top;
            if (height < 700) {
                this.loadMore();
            }
        }, this, { buffer: 50 });
    },

    afterRender: function() {
        Kwc.Directories.List.ViewAjax.View.superclass.afterRender.call(this);

        this.kwfMainContent = this.el.parent('.kwfMainContent');
        if (this.kwfMainContent) {
            this.kwfMainContent.enableDisplayMode('block');
        }
    },

    loadMore: function() {
        if (!this.store || this.getStore().getCount()<20 || this.loadingMore || this.visibleDetail) return;
        this.loadingMore = true;
        this.body.addClass('loadingMore');
        this.getStore().load({
            params: {
                start: this.getStore().getCount(),
                limit: 10
            },
            add: true,
            callback: function(rows) {
                this.body.removeClass('loadingMore');
                if (rows.length) { //wenn nichts geladen sind wir bereits am ende
                    this.loadingMore = false;
                }
            },
            scope: this
        });
    },

    getStore : function() {
        return this.store;
    },

    //für AbstractPanel
    reset: function() {
        if (this.getStore()) {
            this.getStore().modified = [];
            this.getStore().newRecords = [];
        }
    },

    reload: function(options) {
        if (this.getStore()) {
            this.getStore().reload(options);
            this.getStore().commitChanges();
        }
    },

    load : function(params) {
        if (!params) params = {};
        if (!params.start) {
            params.start = 0;
        }
        if (this.el) this.el.mask('', 'loading');
        this.getStore().load({
            params: params,
            callback: function() {
                if (this.el) this.el.unmask();
            },
            scope: this
        });
    },

    getStore : function() {
        return this.store;
    },
    getBaseParams : function() {
        if (this.getStore()) {
            return this.getStore().baseParams;
        } else {
            return this.baseParams || {};
        }
    },
    setBaseParams : function(baseParams) {
        if (this.getStore()) {
            this.getStore().baseParams = baseParams;
        } else {
            //no store yet, apply them later
            this.baseParams = baseParams;
        }
    },
    applyBaseParams : function(baseParams) {
        if (this.getStore()) {
            Ext.apply(this.getStore().baseParams, baseParams);
        } else {
            //no store yet, apply them later
            if (!this.baseParams) this.baseParams = {};
            Ext.apply(this.baseParams, baseParams);
        }
    },

    onItemClick: function(view, number, target, ev) {
        var row = this.store.getAt(number);
        var target = Ext.get(ev.getTarget());
        if (target.dom.tagName.toLowerCase() != 'a') target = target.up('a');
        if (!target) return;
        var m = target.dom.rel.match(/kwfDetail([^ ]+)/);
        if (!m) return;
        var config = Ext.decode(m[1]);
        if (!config.directoryComponentId) return;
        if (config.directoryComponentId != this.directoryComponentId) return;

        ev.stopEvent();
        //more... Link clicked
        this.showDetail(target.dom.href);
    },

    hideDetail: function()
    {
        if (this.detailEl) {
            this.detailEl.remove();
            this.detailEl = null;
        }
    },

    showDetail: function(href)
    {
        if (this.visibleDetail == href) return;
        this.visibleDetail = href;

        if (this.ownerCt._getState().viewDetail != href) {
            this.ownerCt._getState().viewDetail = href;
            Kwf.Utils.HistoryState.pushState(document.title, href);
        }

        this.hideDetail();

        this.classNames = this.el.up('.kwcDirectoriesListViewAjax').dom.className;

        this.kwfMainContent.hide();
        this.detailEl = this.el.createChild({
            cls: 'kwfMainContent loadingContent ' +this.classNames,
            tag: 'div',
            style: 'width: ' + this.kwfMainContent.getStyle('width'),
            html: '

'
        }, this.kwfMainContent);
        var url = '/kwf/util/kwc/render';
        if (Kwf.Debug.rootFilename) url = Kwf.Debug.rootFilename + url;
        Ext.Ajax.request({
            url: url,
            params: { url: href },
            success: function(response, options) {
                if (!this.detailEl) return;
                this.detailEl.removeClass('loadingContent '+this.classNames);
                this.detailEl.update(response.responseText);
                Kwf.Statistics.count(href);

                this.detailEl.query('a').forEach(function(el) {
                    if (el.href == location.protocol+'//'+location.host+this.directoryUrl) {
                        el.kwfViewAjaxInitDone = true;
                        Ext.fly(el).on('click', function(ev) {
                            ev.stopEvent();
                            if (history.length > 1) {
                                history.back(); //keeps scroll position
                            } else {
                                this.showView();
                            }
                        }, this);
                    }
                }, this);

                Kwf.callOnContentReady(this.detailEl);
            },
            scope: this
        });
    },

    showView: function() {
        if (!this.visibleDetail) return;
        this.visibleDetail = null;

        this.hideDetail();

        this.kwfMainContent.show();

        this.ownerCt.onMenuItemChanged();
    }
});

<|endoftext|>