<commit_before>// Copyright 2017 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.
// @ts-nocheck
// TODO(crbug.com/1011811): Enable TypeScript compiler checks

import * as Bindings from '../bindings/bindings.js';
import * as Common from '../common/common.js';
import * as SDK from '../sdk/sdk.js';
import * as TextUtils from '../text_utils/text_utils.js';
import * as Workspace from '../workspace/workspace.js';

import {FormatterInterface, FormatterSourceMapping} from './ScriptFormatter.js';  // eslint-disable-line no-unused-vars

export class SourceFormatData {
  /**
   * @param {!Workspace.UISourceCode.UISourceCode} originalSourceCode
   * @param {!Workspace.UISourceCode.UISourceCode} formattedSourceCode
   * @param {!FormatterSourceMapping} mapping
   */
  constructor(originalSourceCode, formattedSourceCode, mapping) {
    this.originalSourceCode = originalSourceCode;
    this.formattedSourceCode = formattedSourceCode;
    this.mapping = mapping;
  }

  originalPath() {
    return this.originalSourceCode.project().id() + ':' + this.originalSourceCode.url();
  }

  /**
   * @param {!Object} object
   * @return {?SourceFormatData}
   */
  static _for(object) {
    return object[SourceFormatData._formatDataSymbol];
  }
}

SourceFormatData._formatDataSymbol = Symbol('formatData');

export class SourceFormatter {
  constructor() {
    this._projectId = 'formatter:';
    this._project = new Bindings.ContentProviderBasedProject.ContentProviderBasedProject(
        Workspace.Workspace.WorkspaceImpl.instance(), this._projectId, Workspace.Workspace.projectTypes.Formatter,
        'formatter', true /* isServiceProject */);

    /** @type {!Map<!Workspace.UISourceCode.UISourceCode, !{promise: !Promise<!SourceFormatData>, formatData: ?SourceFormatData}>} */
    this._formattedSourceCodes = new Map();
    this._scriptMapping = new ScriptMapping();
    this._styleMapping = new StyleMapping();
    Workspace.Workspace.WorkspaceImpl.instance().addEventListener(
        Workspace.Workspace.Events.UISourceCodeRemoved, event => {
          this._onUISourceCodeRemoved(event);
        }, this);
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  async _onUISourceCodeRemoved(event) {
    const uiSourceCode = /** @type {!Workspace.UISourceCode.UISourceCode} */ (event.data);
    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
    if (cacheEntry && cacheEntry.formatData) {
      await this._discardFormatData(cacheEntry.formatData);
    }
    this._formattedSourceCodes.delete(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} formattedUISourceCode
   * @return {!Promise<?Workspace.UISourceCode.UISourceCode>}
   */
  async discardFormattedUISourceCode(formattedUISourceCode) {
    const formatData = SourceFormatData._for(formattedUISourceCode);
    if (!formatData) {
      return null;
    }
    await this._discardFormatData(formatData);
    this._formattedSourceCodes.delete(formatData.originalSourceCode);
    return formatData.originalSourceCode;
  }

  /**
   * @param {!SourceFormatData} formatData
   */
  async _discardFormatData(formatData) {
    delete formatData.formattedSourceCode[SourceFormatData._formatDataSymbol];
    await this._scriptMapping._setSourceMappingEnabled(formatData, false);
    this._styleMapping._setSourceMappingEnabled(formatData, false);
    this._project.removeFile(formatData.formattedSourceCode.url());
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {boolean}
   */
  hasFormatted(uiSourceCode) {
    return this._formattedSourceCodes.has(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Workspace.UISourceCode.UISourceCode}
   */
  getOriginalUISourceCode(uiSourceCode) {
    const formatData =
        /** @type {?SourceFormatData} */ (uiSourceCode[SourceFormatData._formatDataSymbol]);
    if (!formatData) {
      return uiSourceCode;
    }
    return formatData.originalSourceCode;
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Promise<!SourceFormatData>}
   */
  async format(uiSourceCode) {
    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
    if (cacheEntry) {
      return cacheEntry.promise;
    }

    let fulfillFormatPromise;
    const resultPromise = new Promise(fulfill => {
      fulfillFormatPromise = fulfill;
    });
    this._formattedSourceCodes.set(uiSourceCode, {promise: resultPromise, formatData: null});
    const {content} = await uiSourceCode.requestContent();
    // ------------ ASYNC ------------
    FormatterInterface.format(
        uiSourceCode.contentType(), uiSourceCode.mimeType(), content || '', formatDone.bind(this));
    return resultPromise;

    /**
     * @this SourceFormatter
     * @param {string} formattedContent
     * @param {!FormatterSourceMapping} formatterMapping
     */
    async function formatDone(formattedContent, formatterMapping) {
      const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
      if (!cacheEntry || cacheEntry.promise !== resultPromise) {
        return;
      }
      let formattedURL;
      let count = 0;
      let suffix = '';
      do {
        formattedURL = `${uiSourceCode.url()}:formatted${suffix}`;
        suffix = `:${count++}`;
      } while (this._project.uiSourceCodeForURL(formattedURL));
      const contentProvider = TextUtils.StaticContentProvider.StaticContentProvider.fromString(
          formattedURL, uiSourceCode.contentType(), formattedContent);
      const formattedUISourceCode =
          this._project.addContentProvider(formattedURL, contentProvider, uiSourceCode.mimeType());
      const formatData = new SourceFormatData(uiSourceCode, formattedUISourceCode, formatterMapping);
      formattedUISourceCode[SourceFormatData._formatDataSymbol] = formatData;
      await this._scriptMapping._setSourceMappingEnabled(formatData, true);
      await this._styleMapping._setSourceMappingEnabled(formatData, true);
      cacheEntry.formatData = formatData;

      for (const decoration of uiSourceCode.allDecorations()) {
        const range = decoration.range();
        const startLocation = formatterMapping.originalToFormatted(range.startLine, range.startColumn);
        const endLocation = formatterMapping.originalToFormatted(range.endLine, range.endColumn);

        formattedUISourceCode.addDecoration(
            new TextUtils.TextRange.TextRange(startLocation[0], startLocation[1], endLocation[0], endLocation[1]),
            /** @type {string} */ (decoration.type()), decoration.data());
      }

      fulfillFormatPromise(formatData);
    }
  }
}

/**
 * @implements {Bindings.DebuggerWorkspaceBinding.DebuggerSourceMapping}
 */
class ScriptMapping {
  constructor() {
    Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().addSourceMapping(this);
  }

  /**
   * @override
   * @param {!SDK.DebuggerModel.Location} rawLocation
   * @return {?Workspace.UISourceCode.UILocation}
   */
  rawLocationToUILocation(rawLocation) {
    const script = rawLocation.script();
    const formatData = script && SourceFormatData._for(script);
    if (!formatData) {
      return null;
    }
    if (script.isInlineScriptWithSourceURL()) {
      // Inline scripts with #sourceURL= have lineEndings wrt. the inline script (and not wrt. the containing document),
      // but `rawLocation` will always use locations wrt. the containing document, because that is what the back-end is
      // sending. This is a hack, because what we are really doing here is deciding the location based on /how/ the
      // script is displayed, which is really something this layer cannot and should not have to decide: The
      // SourceFormatter should not have to know wether a script is displayed inline (in its containing document) or
      // stand-alone.
      const [relativeLineNumber, relativeColumnNumber] = script.toRelativeLocation(rawLocation);
      const [formattedLineNumber, formattedColumnNumber] =
          formatData.mapping.originalToFormatted(relativeLineNumber, relativeColumnNumber);
      return formatData.formattedSourceCode.uiLocation(formattedLineNumber, formattedColumnNumber);
    }
    // Here we either have an inline script without a #sourceURL= or a stand-alone script. For stand-alone scripts, no
    // translation must be applied. For inline scripts, also no translation must be applied, because the line-endings
    // tables in the mapping are the same as in the containing document.
    const [lineNumber, columnNumber] =
        formatData.mapping.originalToFormatted(rawLocation.lineNumber, rawLocation.columnNumber || 0);
    return formatData.formattedSourceCode.uiLocation(lineNumber, columnNumber);
  }

  /**
   * @override
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @param {number} lineNumber
   * @param {number} columnNumber
   * @return {!Array<!SDK.DebuggerModel.Location>}
   */
  uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
    const formatData = SourceFormatData._for(uiSourceCode);
    if (!formatData) {
      return [];
    }
    const [originalLine, originalColumn] = formatData.mapping.formattedToOriginal(lineNumber, columnNumber);
    if (formatData.originalSourceCode.contentType().isScript()) {
      // Here we have a script that is displayed on its own (i.e. it has a dedicated uiSourceCode). This means it is
      // either a stand-alone script or an inline script with a #sourceURL= and in both cases we can just forward the
      // question to the original (unformatted) source code.
      const rawLocations = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
                               .uiLocationToRawLocationsForUnformattedJavaScript(
                                   formatData.originalSourceCode, originalLine, originalColumn);
      console.assert(rawLocations.every(l => l && !!l.script()));
      return rawLocations;
    }
    if (formatData.originalSourceCode.contentType() === Common.ResourceType.resourceTypes.Document) {
      const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(formatData.originalSourceCode);
      const debuggerModel = target && target.model(SDK.DebuggerModel.DebuggerModel);
      if (debuggerModel) {
        const scripts = debuggerModel.scriptsForSourceURL(formatData.originalSourceCode.url())
                            .filter(script => script.isInlineScript() && !script.hasSourceURL);
        // Here we have an inline script, which was formatted together with the containing document, so we must not
        // translate locations as they are relative to the start of the document.
        const locations = scripts.map(script => script.rawLocation(originalLine, originalColumn)).filter(l => !!l);
        console.assert(locations.every(l => l && !!l.script()));
        return locations;
      }
    }
    return [];
  }

  /**
   * @param {!SourceFormatData} formatData
   * @param {boolean} enabled
   */
  async _setSourceMappingEnabled(formatData, enabled) {
    const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode);
    if (!scripts.length) {
      return;
    }
    if (enabled) {
      for (const script of scripts) {
        script[SourceFormatData._formatDataSymbol] = formatData;
      }
    } else {
      for (const script of scripts) {
        delete script[SourceFormatData._formatDataSymbol];
      }
    }
    const updatePromises = scripts.map(
        script => Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().updateLocations(script));
    await Promise.all(updatePromises);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Array<!SDK.Script.Script>}
   */
  _scriptsForUISourceCode(uiSourceCode) {
    if (uiSourceCode.contentType() === Common.ResourceType.resourceTypes.Document) {
      const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(uiSourceCode);
      const debuggerModel = target && target.model(SDK.DebuggerModel.DebuggerModel);
      if (debuggerModel) {
        const scripts = debuggerModel.scriptsForSourceURL(uiSourceCode.url())
                            .filter(script => script.isInlineScript() && !script.hasSourceURL);
        return scripts;
      }
    }
    if (uiSourceCode.contentType().isScript()) {
      console.assert(
          !uiSourceCode[SourceFormatData._formatDataSymbol] ||
          uiSourceCode[SourceFormatData._formatDataSymbol] === uiSourceCode);
      const rawLocations = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
                               .uiLocationToRawLocationsForUnformattedJavaScript(uiSourceCode, 0, 0);
      return rawLocations.map(location => location.script()).filter(script => !!script);
    }
    return [];
  }
}

/**
 * @implements {Bindings.CSSWorkspaceBinding.SourceMapping}
 */
class StyleMapping {
  constructor() {
    Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().addSourceMapping(this);
    this._headersSymbol = Symbol('Formatter.SourceFormatter.StyleMapping._headersSymbol');
  }

  /**
   * @override
   * @param {!SDK.CSSModel.CSSLocation} rawLocation
   * @return {?Workspace.UISourceCode.UILocation}
   */
  rawLocationToUILocation(rawLocation) {
    const styleHeader = rawLocation.header();
    const formatData = styleHeader && SourceFormatData._for(styleHeader);
    if (!formatData) {
      return null;
    }
    const formattedLocation =
        formatData.mapping.originalToFormatted(rawLocation.lineNumber, rawLocation.columnNumber || 0);
    return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
  }

  /**
   * @override
   * @param {!Workspace.UISourceCode.UILocation} uiLocation
   * @return {!Array<!SDK.CSSModel.CSSLocation>}
   */
  uiLocationToRawLocations(uiLocation) {
    const formatData = SourceFormatData._for(uiLocation.uiSourceCode);
    if (!formatData) {
      return [];
    }
    const [originalLine, originalColumn] =
        formatData.mapping.formattedToOriginal(uiLocation.lineNumber, uiLocation.columnNumber);
    const headers = formatData.originalSourceCode[this._headersSymbol].filter(
        header => header.containsLocation(originalLine, originalColumn));
    return headers.map(header => new SDK.CSSModel.CSSLocation(header, originalLine, originalColumn));
  }

  /**
   * @param {!SourceFormatData} formatData
   * @param {boolean} enable
   */
  async _setSourceMappingEnabled(formatData, enable) {
    const original = formatData.originalSourceCode;
    const headers = this._headersForUISourceCode(original);
    if (enable) {
      original[this._headersSymbol] = headers;
      headers.forEach(header => {
        header[SourceFormatData._formatDataSymbol] = formatData;
      });
    } else {
      original[this._headersSymbol] = null;
      headers.forEach(header => delete header[SourceFormatData._formatDataSymbol]);
    }
    const updatePromises =
        headers.map(header => Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().updateLocations(header));
    await Promise.all(updatePromises);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Array<!SDK.CSSStyleSheetHeader.CSSStyleSheetHeader>}
   */
  _headersForUISourceCode(uiSourceCode) {
    if (uiSourceCode.contentType() === Common.ResourceType.resourceTypes.Document) {
      const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(uiSourceCode);
      const cssModel = target && target.model(SDK.CSSModel.CSSModel);
      if (cssModel) {
        return cssModel.headersForSourceURL(uiSourceCode.url())
            .filter(header => header.isInline && !header.hasSourceURL);
      }
    } else if (uiSourceCode.contentType().isStyleSheet()) {
      const rawLocations = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().uiLocationToRawLocations(
          uiSourceCode.uiLocation(0, 0));
      return rawLocations.map(rawLocation => rawLocation.header()).filter(header => !!header);
    }
    return [];
  }
}
<commit_msg>Sources: Restore breakpoints on formatted code<commit_after>// Copyright 2017 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.
// @ts-nocheck
// TODO(crbug.com/1011811): Enable TypeScript compiler checks

import * as Bindings from '../bindings/bindings.js';
import * as Common from '../common/common.js';
import * as SDK from '../sdk/sdk.js';
import * as TextUtils from '../text_utils/text_utils.js';
import * as Workspace from '../workspace/workspace.js';

import {FormatterInterface, FormatterSourceMapping} from './ScriptFormatter.js';  // eslint-disable-line no-unused-vars

export class SourceFormatData {
  /**
   * @param {!Workspace.UISourceCode.UISourceCode} originalSourceCode
   * @param {!Workspace.UISourceCode.UISourceCode} formattedSourceCode
   * @param {!FormatterSourceMapping} mapping
   */
  constructor(originalSourceCode, formattedSourceCode, mapping) {
    this.originalSourceCode = originalSourceCode;
    this.formattedSourceCode = formattedSourceCode;
    this.mapping = mapping;
  }

  originalPath() {
    return this.originalSourceCode.project().id() + ':' + this.originalSourceCode.url();
  }

  /**
   * @param {!Object} object
   * @return {?SourceFormatData}
   */
  static _for(object) {
    return object[SourceFormatData._formatDataSymbol];
  }
}

SourceFormatData._formatDataSymbol = Symbol('formatData');

export class SourceFormatter {
  constructor() {
    this._projectId = 'formatter:';
    this._project = new Bindings.ContentProviderBasedProject.ContentProviderBasedProject(
        Workspace.Workspace.WorkspaceImpl.instance(), this._projectId, Workspace.Workspace.projectTypes.Formatter,
        'formatter', true /* isServiceProject */);

    /** @type {!Map<!Workspace.UISourceCode.UISourceCode, !{promise: !Promise<!SourceFormatData>, formatData: ?SourceFormatData}>} */
    this._formattedSourceCodes = new Map();
    this._scriptMapping = new ScriptMapping();
    this._styleMapping = new StyleMapping();
    Workspace.Workspace.WorkspaceImpl.instance().addEventListener(
        Workspace.Workspace.Events.UISourceCodeRemoved, event => {
          this._onUISourceCodeRemoved(event);
        }, this);
  }

  /**
   * @param {!Common.EventTarget.EventTargetEvent} event
   */
  async _onUISourceCodeRemoved(event) {
    const uiSourceCode = /** @type {!Workspace.UISourceCode.UISourceCode} */ (event.data);
    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
    if (cacheEntry && cacheEntry.formatData) {
      await this._discardFormatData(cacheEntry.formatData);
    }
    this._formattedSourceCodes.delete(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} formattedUISourceCode
   * @return {!Promise<?Workspace.UISourceCode.UISourceCode>}
   */
  async discardFormattedUISourceCode(formattedUISourceCode) {
    const formatData = SourceFormatData._for(formattedUISourceCode);
    if (!formatData) {
      return null;
    }
    await this._discardFormatData(formatData);
    this._formattedSourceCodes.delete(formatData.originalSourceCode);
    return formatData.originalSourceCode;
  }

  /**
   * @param {!SourceFormatData} formatData
   */
  async _discardFormatData(formatData) {
    delete formatData.formattedSourceCode[SourceFormatData._formatDataSymbol];
    await this._scriptMapping._setSourceMappingEnabled(formatData, false);
    this._styleMapping._setSourceMappingEnabled(formatData, false);
    this._project.removeFile(formatData.formattedSourceCode.url());
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {boolean}
   */
  hasFormatted(uiSourceCode) {
    return this._formattedSourceCodes.has(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Workspace.UISourceCode.UISourceCode}
   */
  getOriginalUISourceCode(uiSourceCode) {
    const formatData =
        /** @type {?SourceFormatData} */ (uiSourceCode[SourceFormatData._formatDataSymbol]);
    if (!formatData) {
      return uiSourceCode;
    }
    return formatData.originalSourceCode;
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Promise<!SourceFormatData>}
   */
  async format(uiSourceCode) {
    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
    if (cacheEntry) {
      return cacheEntry.promise;
    }

    let fulfillFormatPromise;
    const resultPromise = new Promise(fulfill => {
      fulfillFormatPromise = fulfill;
    });
    this._formattedSourceCodes.set(uiSourceCode, {promise: resultPromise, formatData: null});
    const {content} = await uiSourceCode.requestContent();
    // ------------ ASYNC ------------
    FormatterInterface.format(
        uiSourceCode.contentType(), uiSourceCode.mimeType(), content || '', formatDone.bind(this));
    return resultPromise;

    /**
     * @this SourceFormatter
     * @param {string} formattedContent
     * @param {!FormatterSourceMapping} formatterMapping
     */
    async function formatDone(formattedContent, formatterMapping) {
      const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
      if (!cacheEntry || cacheEntry.promise !== resultPromise) {
        return;
      }
      let formattedURL;
      let count = 0;
      let suffix = '';
      do {
        formattedURL = `${uiSourceCode.url()}:formatted${suffix}`;
        suffix = `:${count++}`;
      } while (this._project.uiSourceCodeForURL(formattedURL));
      const contentProvider = TextUtils.StaticContentProvider.StaticContentProvider.fromString(
          formattedURL, uiSourceCode.contentType(), formattedContent);
      const formattedUISourceCode = this._project.createUISourceCode(formattedURL, contentProvider.contentType());
      const formatData = new SourceFormatData(uiSourceCode, formattedUISourceCode, formatterMapping);
      formattedUISourceCode[SourceFormatData._formatDataSymbol] = formatData;
      this._project.addUISourceCodeWithProvider(
          formattedUISourceCode, contentProvider, /* metadata */ null, uiSourceCode.mimeType());
      await this._scriptMapping._setSourceMappingEnabled(formatData, true);
      await this._styleMapping._setSourceMappingEnabled(formatData, true);
      cacheEntry.formatData = formatData;

      for (const decoration of uiSourceCode.allDecorations()) {
        const range = decoration.range();
        const startLocation = formatterMapping.originalToFormatted(range.startLine, range.startColumn);
        const endLocation = formatterMapping.originalToFormatted(range.endLine, range.endColumn);

        formattedUISourceCode.addDecoration(
            new TextUtils.TextRange.TextRange(startLocation[0], startLocation[1], endLocation[0], endLocation[1]),
            /** @type {string} */ (decoration.type()), decoration.data());
      }

      fulfillFormatPromise(formatData);
    }
  }
}

/**
 * @implements {Bindings.DebuggerWorkspaceBinding.DebuggerSourceMapping}
 */
class ScriptMapping {
  constructor() {
    Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().addSourceMapping(this);
  }

  /**
   * @override
   * @param {!SDK.DebuggerModel.Location} rawLocation
   * @return {?Workspace.UISourceCode.UILocation}
   */
  rawLocationToUILocation(rawLocation) {
    const script = rawLocation.script();
    const formatData = script && SourceFormatData._for(script);
    if (!formatData) {
      return null;
    }
    if (script.isInlineScriptWithSourceURL()) {
      // Inline scripts with #sourceURL= have lineEndings wrt. the inline script (and not wrt. the containing document),
      // but `rawLocation` will always use locations wrt. the containing document, because that is what the back-end is
      // sending. This is a hack, because what we are really doing here is deciding the location based on /how/ the
      // script is displayed, which is really something this layer cannot and should not have to decide: The
      // SourceFormatter should not have to know wether a script is displayed inline (in its containing document) or
      // stand-alone.
      const [relativeLineNumber, relativeColumnNumber] = script.toRelativeLocation(rawLocation);
      const [formattedLineNumber, formattedColumnNumber] =
          formatData.mapping.originalToFormatted(relativeLineNumber, relativeColumnNumber);
      return formatData.formattedSourceCode.uiLocation(formattedLineNumber, formattedColumnNumber);
    }
    // Here we either have an inline script without a #sourceURL= or a stand-alone script. For stand-alone scripts, no
    // translation must be applied. For inline scripts, also no translation must be applied, because the line-endings
    // tables in the mapping are the same as in the containing document.
    const [lineNumber, columnNumber] =
        formatData.mapping.originalToFormatted(rawLocation.lineNumber, rawLocation.columnNumber || 0);
    return formatData.formattedSourceCode.uiLocation(lineNumber, columnNumber);
  }

  /**
   * @override
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @param {number} lineNumber
   * @param {number} columnNumber
   * @return {!Array<!SDK.DebuggerModel.Location>}
   */
  uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
    const formatData = SourceFormatData._for(uiSourceCode);
    if (!formatData) {
      return [];
    }
    const [originalLine, originalColumn] = formatData.mapping.formattedToOriginal(lineNumber, columnNumber);
    if (formatData.originalSourceCode.contentType().isScript()) {
      // Here we have a script that is displayed on its own (i.e. it has a dedicated uiSourceCode). This means it is
      // either a stand-alone script or an inline script with a #sourceURL= and in both cases we can just forward the
      // question to the original (unformatted) source code.
      const rawLocations = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
                               .uiLocationToRawLocationsForUnformattedJavaScript(
                                   formatData.originalSourceCode, originalLine, originalColumn);
      console.assert(rawLocations.every(l => l && !!l.script()));
      return rawLocations;
    }
    if (formatData.originalSourceCode.contentType() === Common.ResourceType.resourceTypes.Document) {
      const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(formatData.originalSourceCode);
      const debuggerModel = target && target.model(SDK.DebuggerModel.DebuggerModel);
      if (debuggerModel) {
        const scripts = debuggerModel.scriptsForSourceURL(formatData.originalSourceCode.url())
                            .filter(script => script.isInlineScript() && !script.hasSourceURL);
        // Here we have an inline script, which was formatted together with the containing document, so we must not
        // translate locations as they are relative to the start of the document.
        const locations = scripts.map(script => script.rawLocation(originalLine, originalColumn)).filter(l => !!l);
        console.assert(locations.every(l => l && !!l.script()));
        return locations;
      }
    }
    return [];
  }

  /**
   * @param {!SourceFormatData} formatData
   * @param {boolean} enabled
   */
  async _setSourceMappingEnabled(formatData, enabled) {
    const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode);
    if (!scripts.length) {
      return;
    }
    if (enabled) {
      for (const script of scripts) {
        script[SourceFormatData._formatDataSymbol] = formatData;
      }
    } else {
      for (const script of scripts) {
        delete script[SourceFormatData._formatDataSymbol];
      }
    }
    const updatePromises = scripts.map(
        script => Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().updateLocations(script));
    await Promise.all(updatePromises);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Array<!SDK.Script.Script>}
   */
  _scriptsForUISourceCode(uiSourceCode) {
    if (uiSourceCode.contentType() === Common.ResourceType.resourceTypes.Document) {
      const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(uiSourceCode);
      const debuggerModel = target && target.model(SDK.DebuggerModel.DebuggerModel);
      if (debuggerModel) {
        const scripts = debuggerModel.scriptsForSourceURL(uiSourceCode.url())
                            .filter(script => script.isInlineScript() && !script.hasSourceURL);
        return scripts;
      }
    }
    if (uiSourceCode.contentType().isScript()) {
      console.assert(
          !uiSourceCode[SourceFormatData._formatDataSymbol] ||
          uiSourceCode[SourceFormatData._formatDataSymbol] === uiSourceCode);
      const rawLocations = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
                               .uiLocationToRawLocationsForUnformattedJavaScript(uiSourceCode, 0, 0);
      return rawLocations.map(location => location.script()).filter(script => !!script);
    }
    return [];
  }
}

/**
 * @implements {Bindings.CSSWorkspaceBinding.SourceMapping}
 */
class StyleMapping {
  constructor() {
    Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().addSourceMapping(this);
    this._headersSymbol = Symbol('Formatter.SourceFormatter.StyleMapping._headersSymbol');
  }

  /**
   * @override
   * @param {!SDK.CSSModel.CSSLocation} rawLocation
   * @return {?Workspace.UISourceCode.UILocation}
   */
  rawLocationToUILocation(rawLocation) {
    const styleHeader = rawLocation.header();
    const formatData = styleHeader && SourceFormatData._for(styleHeader);
    if (!formatData) {
      return null;
    }
    const formattedLocation =
        formatData.mapping.originalToFormatted(rawLocation.lineNumber, rawLocation.columnNumber || 0);
    return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
  }

  /**
   * @override
   * @param {!Workspace.UISourceCode.UILocation} uiLocation
   * @return {!Array<!SDK.CSSModel.CSSLocation>}
   */
  uiLocationToRawLocations(uiLocation) {
    const formatData = SourceFormatData._for(uiLocation.uiSourceCode);
    if (!formatData) {
      return [];
    }
    const [originalLine, originalColumn] =
        formatData.mapping.formattedToOriginal(uiLocation.lineNumber, uiLocation.columnNumber);
    const headers = formatData.originalSourceCode[this._headersSymbol].filter(
        header => header.containsLocation(originalLine, originalColumn));
    return headers.map(header => new SDK.CSSModel.CSSLocation(header, originalLine, originalColumn));
  }

  /**
   * @param {!SourceFormatData} formatData
   * @param {boolean} enable
   */
  async _setSourceMappingEnabled(formatData, enable) {
    const original = formatData.originalSourceCode;
    const headers = this._headersForUISourceCode(original);
    if (enable) {
      original[this._headersSymbol] = headers;
      headers.forEach(header => {
        header[SourceFormatData._formatDataSymbol] = formatData;
      });
    } else {
      original[this._headersSymbol] = null;
      headers.forEach(header => delete header[SourceFormatData._formatDataSymbol]);
    }
    const updatePromises =
        headers.map(header => Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().updateLocations(header));
    await Promise.all(updatePromises);
  }

  /**
   * @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
   * @return {!Array<!SDK.CSSStyleSheetHeader.CSSStyleSheetHeader>}
   */
  _headersForUISourceCode(uiSourceCode) {
    if (uiSourceCode.contentType() === Common.ResourceType.resourceTypes.Document) {
      const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(uiSourceCode);
      const cssModel = target && target.model(SDK.CSSModel.CSSModel);
      if (cssModel) {
        return cssModel.headersForSourceURL(uiSourceCode.url())
            .filter(header => header.isInline && !header.hasSourceURL);
      }
    } else if (uiSourceCode.contentType().isStyleSheet()) {
      const rawLocations = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().uiLocationToRawLocations(
          uiSourceCode.uiLocation(0, 0));
      return rawLocations.map(rawLocation => rawLocation.header()).filter(header => !!header);
    }
    return [];
  }
}
<|endoftext|>


<commit_before>const u = require('../styles/utils');
const c = require('../styles/config');
const colors = require('material-colors');

const dashboardPadding =
  25;

const halfCategorySpacing =
  10;
const categoryBorder = {
  width: 2,
  offset: 15,
};
const songHeight =
  40;
const arrowHeight =
  70;
const arrowWidth =
  20;

const transitionDuration =
  '150ms';
const transitionFunction =
  'cubic-bezier(0, 0, 0, 1)';
const foldedCategory =
  '.dashboard’s-category:not(.dashboard’s-category·unfolded)';

const arrowFilter =
  `drop-shadow(0px 0px ${u.inRem(c.displayShadowBlur / 3)} black)`;

module.exports = {
  '.dashboard': {
    'padding': u.inRem(dashboardPadding),
    'width': u.inRem(c.navBarWidth),
    'height': '100%',
    'overflow': 'auto',
  },

  '.dashboard::-webkit-scrollbar': {
    'display': 'none',
  },

  '.dashboard’s-title': {
    'font-size': u.inRem(40),
    'line-height': u.inRem(40),
  },

  '.dashboard’s-subtitle': {
    'font-size': u.inRem(12),
    'text-transform': 'uppercase',
    'letter-spacing': '0.2em',
  },

  '.dashboard’s-categories': {
    'list-style-type': 'none',
    'padding-top': u.inRem(40),
  },

  '.dashboard’s-category': {
    'line-height': u.inRem(songHeight),
    'position': 'relative',
    'margin': [
      '0',
      u.inRem(-dashboardPadding),
      u.inRem(halfCategorySpacing * 2),
      u.inRem(-dashboardPadding + categoryBorder.offset),
    ].join(' '),
  },

  [[
    '.dashboard’s-button',
    '.dashboard’s-button:focus',
  ].join(', ')]: {
    'display': 'block',
    'width': '100%',
    'padding': [
      '0',
      u.inRem(dashboardPadding),
      '0',
      u.inRem(dashboardPadding - categoryBorder.width - categoryBorder.offset),
    ].join(' '),

    'border-left': [
      u.inRem(categoryBorder.width),
      'solid',
      u.primaryColorOpacity(0.7),
    ].join(' '),

    'color': 'inherit',
    'text-decoration': 'none',
  },

  '.dashboard’s-button:hover': {
    'background': u.primaryColorOpacity(0.1),
  },

  '.dashboard’s-button:active': {
    'background': u.primaryColorOpacity(0.2),
  },

  '.dashboard’s-button:focus': {
    'outline': 'none',
    'border-left-color': colors.cyan[600],
  },

  '.dashboard’s-category-title': {
    'line-height': u.inRem(60),
    'font-size': u.inRem(14),
    'text-transform': 'uppercase',
    'letter-spacing': '0.07em',
  },

  '.dashboard’s-song': {
    'position': 'relative',
    'display': 'block',
    'color': u.primaryColorOpacity(1),
    'transition': [
      `line-height ${transitionDuration} ${transitionFunction}`,
      `color ${transitionDuration} ${transitionFunction}`,
      `visibility ${transitionDuration} step-start`,
    ].join(', '),
  },

  [`${foldedCategory} .dashboard’s-song:not(.dashboard’s-song·current)`]: {
    'line-height': '0rem',
    'visibility': 'hidden',
    'color': u.primaryColorOpacity(0),
    'transition-timing-function': [
      transitionFunction,
      transitionFunction,
      'step-end',
    ].join(', '),
  },

  '.dashboard’s-song·current::after': {
    'right': '0',
    'top': u.inRem((songHeight - arrowHeight) / 2),
    'content': '""',
    'display': 'block',
    'border': `${u.inRem(arrowHeight / 2)} transparent solid`,
    'border-left-width': '0',
    'border-right': `${u.inRem(arrowWidth)} black solid`,
    'position': 'absolute',
    '-webkit-filter': arrowFilter,
    'filter': arrowFilter,
  },
};
<commit_msg>Zoom-friendly styles<commit_after>const u = require('../styles/utils');
const c = require('../styles/config');
const colors = require('material-colors');

const dashboardPadding =
  25;

const halfCategorySpacing =
  10;
const categoryBorder = {
  width: 2,
  offset: 15,
};
const songHeight =
  40;
const arrowHeight =
  70;
const arrowWidth =
  20;

const transitionDuration =
  '150ms';
const transitionFunction =
  'cubic-bezier(0, 0, 0, 1)';
const foldedCategory =
  '.dashboard’s-category:not(.dashboard’s-category·unfolded)';

const arrowFilter =
  `drop-shadow(0px 0px ${u.inRem(c.displayShadowBlur / 3)} black)`;

module.exports = {
  '.dashboard': {
    'padding': u.inRem(dashboardPadding),
    'width': u.inRem(c.navBarWidth),
    'height': '100%',
    'overflow': 'auto',
  },

  '.dashboard::-webkit-scrollbar': {
    'display': 'none',
  },

  '.dashboard’s-title': {
    'font-size': u.inRem(40),
    'line-height': u.inRem(40),
  },

  '.dashboard’s-subtitle': {
    'font-size': u.inRem(12),
    'text-transform': 'uppercase',
    'letter-spacing': '0.2em',
  },

  '.dashboard’s-categories': {
    'list-style-type': 'none',
    'padding-top': u.inRem(40),
  },

  '.dashboard’s-category': {
    'line-height': u.inRem(songHeight),
    'position': 'relative',
    'margin': [
      '0',
      u.inRem(-dashboardPadding),
      u.inRem(halfCategorySpacing * 2),
      u.inRem(-dashboardPadding + categoryBorder.offset),
    ].join(' '),
  },

  [[
    '.dashboard’s-button',
    '.dashboard’s-button:focus',
  ].join(', ')]: {
    'display': 'block',
    'width': '100%',
    'padding': [
      '0',
      u.inRem(dashboardPadding),
      '0',
      u.inRem(dashboardPadding - categoryBorder.width - categoryBorder.offset),
    ].join(' '),

    'border-left': [
      u.inRem(categoryBorder.width),
      'solid',
      u.primaryColorOpacity(0.7),
    ].join(' '),

    'color': 'inherit',
    'text-decoration': 'none',
  },

  '.dashboard’s-button:hover': {
    'background': u.primaryColorOpacity(0.1),
  },

  '.dashboard’s-button:active': {
    'background': u.primaryColorOpacity(0.2),
  },

  '.dashboard’s-button:focus': {
    'outline': 'none',
    'border-left-color': colors.cyan[600],
  },

  '.dashboard’s-category-title': {
    'line-height': u.inRem(60),
    'font-size': u.inRem(14),
    'text-transform': 'uppercase',
    'letter-spacing': '0.07em',
  },

  '.dashboard’s-song': {
    'position': 'relative',
    'display': 'block',
    'color': u.primaryColorOpacity(1),
    'transition': [
      `line-height ${transitionDuration} ${transitionFunction}`,
      `color ${transitionDuration} ${transitionFunction}`,
      `visibility ${transitionDuration} step-start`,
    ].join(', '),
  },

  [`${foldedCategory} .dashboard’s-song:not(.dashboard’s-song·current)`]: {
    'line-height': '0rem',
    'visibility': 'hidden',
    'color': u.primaryColorOpacity(0),
    'transition-timing-function': [
      transitionFunction,
      transitionFunction,
      'step-end',
    ].join(', '),
  },

  '.dashboard’s-song·current::after': {
    'right': u.inRem(-1),
    'top': u.inRem((songHeight - arrowHeight) / 2),
    'content': '""',
    'display': 'block',
    'border': `${u.inRem(arrowHeight / 2)} transparent solid`,
    'border-left-width': '0',
    'border-right': `${u.inRem(arrowWidth + 1)} black solid`,
    'position': 'absolute',
    '-webkit-filter': arrowFilter,
    'filter': arrowFilter,
  },
};
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';

const nodeProps = [
    'ID',
    'Name',
    'Status',
    'Datacenter',
    'Drain',
    'HTTPAddr',
    'NodeClass',
];

const ClientInfo = ({ node }) =>

      <legend>Client Properties</legend>

        { nodeProps.map(nodeProp =>

{ nodeProp }

{ node[nodeProp] }

        )}

;

function mapStateToProps({ node }) {
    return { node };
}

ClientInfo.propTypes = {
    node: PropTypes.object.isRequired,
};

export default connect(mapStateToProps)(ClientInfo);
<commit_msg>display client meta and attributes<commit_after>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import MetaDisplay from '../meta';

const nodeProps = [
    'ID',
    'Name',
    'Status',
    'Datacenter',
    'Drain',
    'HTTPAddr',
    'NodeClass',
];

const ClientInfo = ({ node }) =>

        <legend>Client Properties</legend>

          { nodeProps.map(nodeProp =>

{ nodeProp }

{ node[nodeProp] }

          )}

        <legend>Meta Properties</legend>
        <MetaDisplay dtWithClass="wide" metaBag={ node.Meta } />

          <legend>Client Attributes</legend>
          <MetaDisplay dtWithClass="wide" metaBag={ node.Attributes } />

;

function mapStateToProps({ node }) {
    return { node };
}

ClientInfo.propTypes = {
    node: PropTypes.object.isRequired,
};

export default connect(mapStateToProps)(ClientInfo);
<|endoftext|>


<commit_before>process.env.DEV_SERVER = true;

process.argv.forEach(function(val) {
  if (val === '--lint') {
    process.env.LINT = true;
  }
});

var WebpackDevServer = require('webpack-dev-server');
var webpack = require('webpack');
var devServerConfig = require('./webpackdevserverconfig');

var bundles = require('./webpack.config.dev');
var compiler = webpack(bundles);
var server = new WebpackDevServer(compiler, {
  // webpack-dev-server options

  // contentBase: "http://localhost:3000/",
  // Can also be an array, or: contentBase: "http://localhost/",

  // Set this as true if you want to access dev server from arbitrary url.
  // This is handy if you are using a html5 router.
  historyApiFallback: false,

  // Set this if you want to enable gzip compression for assets
  compress: false,

  // webpack-dev-middleware options
  quiet: false,
  noInfo: false,
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000,
  },
  // It's a required option.
  publicPath: devServerConfig.publicPath,
  stats: {
    colors: true,
    chunks: false,
    errorDetails: true,
    modules: false,
  },
  headers: {
    'Access-Control-Allow-Origin': '*',
  },
});
server.listen(devServerConfig.port, devServerConfig.address, function() {});
<commit_msg>Reduce webpack logging<commit_after>process.env.DEV_SERVER = true;

process.argv.forEach(function(val) {
  if (val === '--lint') {
    process.env.LINT = true;
  }
});

var WebpackDevServer = require('webpack-dev-server');
var webpack = require('webpack');
var devServerConfig = require('./webpackdevserverconfig');

var bundles = require('./webpack.config.dev');
var compiler = webpack(bundles);
var server = new WebpackDevServer(compiler, {
  // webpack-dev-server options

  // contentBase: "http://localhost:3000/",
  // Can also be an array, or: contentBase: "http://localhost/",

  // Set this as true if you want to access dev server from arbitrary url.
  // This is handy if you are using a html5 router.
  historyApiFallback: false,

  // Set this if you want to enable gzip compression for assets
  compress: false,

  // webpack-dev-middleware options
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000,
  },
  // It's a required option.
  publicPath: devServerConfig.publicPath,
  stats: 'minimal',
  headers: {
    'Access-Control-Allow-Origin': '*',
  },
});
server.listen(devServerConfig.port, devServerConfig.address, function() {});
<|endoftext|>


<commit_before>var gems = angular.module('gems');

gems.controller('groupController', function($scope, $http){
    $scope.groupName = $scope.getGroupName();
    $scope.queryStarted = false;
    $scope.numberOfRows = 0;
    $scope.rows = [];
    $scope.columns = [];

    $scope.filteredGroups = [];
    $scope.pagedGroups = [];
    $scope.currentPage = 1;
    $scope.maxSize = 6;
    $scope.buttonText = "Display Results";
    $scope.queryDone = true;
    $scope.showAllResults = false;
    $scope.dispCol = {
        hide: false
    };

    $scope.fetchResults = function fetchResults(){
        $scope.rows = [];
        $scope.queryStarted = true;
        $scope.queryDone = false;
        $scope.buttonText = "Loading Results";
        $scope.showAllResults = false;
        var payload = {};

        if($scope.numberOfRows != null && $scope.numberOfRows > 0){
            payload.limit = $scope.numberOfRows;
        }

        payload.filters = $scope.filters
        $scope.columns = $scope.origColumns.slice();

        if ($scope.createGroup == false && $scope.groupKey != null) {
            var group_contacts;
            $http({url: 'group/contacts', method: 'POST', data: {group_key: $scope.groupKey}})
                .then(function(data) {
                    group_contacts = data.data;

                    $http({
                        url: '/query/',
                        method: 'POST',
                        data: payload
                    })
                    .then(function(data){
                        var results = data.data;

                        var retVal = $scope.processQueryResults(results, $scope.columns, payload.filters);
                        $scope.columns = retVal[0];
                        $scope.rows = retVal[1];

                        if ($scope.queryStarted == true){
                                $scope.buttonText = "Refresh Results";
                        }else{
                            $scope.buttonText = "Display Results";
                        }

                        for (var i=0; i<results.length; i++) {
                            if (group_contacts.indexOf(results[i].contact) >= 0) {
                                $scope.rows[i].selected = true;
                            }
                        }

                        $scope.queryDone = true;
                        $scope.currentPage = 0;
                        $scope.pagedGroups = $scope.groupToPages($scope.rows);
                    })
                });
        } else {
             $http({
                url: '/query/',
                method: 'POST',
                data: payload
                })
                .then(function(data){
                    var results = data.data;

                    var retVal = $scope.processQueryResults(results, $scope.columns, payload.filters);
                    $scope.columns = retVal[0];
                    $scope.rows = retVal[1];

                    if ($scope.queryStarted == true){
                            $scope.buttonText = "Refresh Results";
                    }else{
                        $scope.buttonText = "Display Results";
                    }

                    $scope.queryDone = true;
                    $scope.currentPage = 0;
                    $scope.pagedGroups = $scope.groupToPages($scope.rows);
                })
        }
    };

    $scope.selectRow = function selectRow(index){
        $scope.rows[index].selected = true;
    };

    $scope.selectFunction = function selectFunction(){
        if($scope.allRowsSelected()){
            // deselect all rows
            for(var x = 0; x < $scope.rows.length; ++x){
                $scope.rows[x].selected = false;
            }
        } else {
            // select all rows
            for(var x = 0; x < $scope.rows.length; ++x){
                $scope.rows[x].selected = true;
            }
        }
    };

    $scope.allRowsSelected = function allRowsSelected(){
        var retVal = true;

        for(var x = 0; x < $scope.rows.length; ++x){
            retVal = retVal && $scope.rows[x].selected;
        }

        return retVal;
    };

    $scope.anyRowsSelected = function anyRowsSelected(){
        var retVal = false;

        for(var x = 0; x < $scope.rows.length; ++x){
            retVal = retVal || $scope.rows[x].selected;
        }

        return retVal;
    };

    $scope.getGroup = function getGroup(filters){
        var group = {
            name: $scope.groupName,
            members: [],
            query_words: $scope.getQueryWords(),
            filters: JSON.stringify( filters )
        };

        var contactIndex = 0;

        for(var x = 0; x < $scope.fields.length; ++x){
            if($scope.fields[x].name === 'contact' ){
                contactIndex = x;
                break;
            }
        }

        for(var x = 0; x < $scope.rows.length; ++x){
            if($scope.rows[x].selected){
                group.members.push($scope.rows[x].fields[contactIndex]);
            }
        }

        return group;
    };

    $scope.saveGroup = function saveGroup(filters){
        var group = $scope.getGroup(filters);

        $scope.showMessage('Busy', 'Creating Group');
        $http.post('/create_contactgroup/', group, config={timeout: 300000}).
            success(function(status){
                $scope.hideMessage();
                $scope.showAlert('alert-success', 'Success:', status);
            }).
            error(function(data, status){
                $scope.hideMessage();
                $scope.showAlert('alert-warning', 'Failed:', status + ' : ' + data);
            });

        $scope.cancel();
    };

    //need group_key
    $scope.updateGroup = function updateGroup(filters){
        var group = $scope.getGroup(filters);
        group.group_key = $scope.groupKey;

        $http.post('/update_contactgroup/', group).
            success(function(status){
                $scope.showAlert('alert-success', 'Success', status);
            }).
            error(function(status){
                $scope.showAlert('alert-warning', 'Failed', 'Failed to update contact group.'  + '\n\n' + status);
            });

        $scope.cancel();
    };

    ///////PAGING/////
    $scope.groupToPages = function(results){
        var paged = [];
        var temp = results.slice();
        while (temp.length > 0)
        {
            paged.push(temp.splice(0, $scope.itemsPerPage));
        }
        return paged;
    };

    $scope.setPage = function (){
        $scope.currentPage = this.n;
    };

    $scope.cancel = function cancel(){
        $scope.hideCreateContact();
    };

    $scope.$watch('$parent.createGroup', function(newValue, oldValue){
        if(newValue){
            $scope.groupName = $scope.getGroupName();
        }
    });

    $scope.queryValid = function queryValid(){
        return $scope.getQueryValid();
    }

    $scope.toggleShowAllResults = function toggleShowAllResults(){
        $scope.showAllResults = !$scope.showAllResults;

        var retVal = $scope.toggleColumnsAndRows($scope.columns, $scope.rows);
        $scope.columns = retVal[0];
        $scope.rows = retVal[1];
    }
});
<commit_msg>Removed inconsistent white space<commit_after>var gems = angular.module('gems');

gems.controller('groupController', function($scope, $http){
    $scope.groupName = $scope.getGroupName();
    $scope.queryStarted = false;
    $scope.numberOfRows = 0;
    $scope.rows = [];
    $scope.columns = [];

    $scope.filteredGroups = [];
    $scope.pagedGroups = [];
    $scope.currentPage = 1;
    $scope.maxSize = 6;
    $scope.buttonText = "Display Results";
    $scope.queryDone = true;
    $scope.showAllResults = false;
    $scope.dispCol = {
        hide: false
    };

    $scope.fetchResults = function fetchResults(){
        $scope.rows = [];
        $scope.queryStarted = true;
        $scope.queryDone = false;
        $scope.buttonText = "Loading Results";
        $scope.showAllResults = false;
        var payload = {};

        if($scope.numberOfRows != null && $scope.numberOfRows > 0){
            payload.limit = $scope.numberOfRows;
        }

        payload.filters = $scope.filters
        $scope.columns = $scope.origColumns.slice();

        if ($scope.createGroup == false && $scope.groupKey != null) {
            var group_contacts;
            $http({url: 'group/contacts', method: 'POST', data: {group_key: $scope.groupKey}})
                .then(function(data) {
                    group_contacts = data.data;
                    $http({
                        url: '/query/',
                        method: 'POST',
                        data: payload
                    })
                    .then(function(data){
                        var results = data.data;
                        var retVal = $scope.processQueryResults(results, $scope.columns, payload.filters);
                        $scope.columns = retVal[0];
                        $scope.rows = retVal[1];

                        if ($scope.queryStarted == true) {
                                $scope.buttonText = "Refresh Results";
                        } else {
                            $scope.buttonText = "Display Results";
                        }

                        for (var i=0; i<results.length; i++) {
                            if (group_contacts.indexOf(results[i].contact) >= 0) {
                                $scope.rows[i].selected = true;
                            }
                        }
                        $scope.queryDone = true;
                        $scope.currentPage = 0;
                        $scope.pagedGroups = $scope.groupToPages($scope.rows);
                    });
                });
        } else {
            $http({
                url: '/query/',
                method: 'POST',
                data: payload
            })
            .then(function(data){
                var results = data.data;
                var retVal = $scope.processQueryResults(results, $scope.columns, payload.filters);
                $scope.columns = retVal[0];
                $scope.rows = retVal[1];

                if ($scope.queryStarted == true) {
                        $scope.buttonText = "Refresh Results";
                } else {
                    $scope.buttonText = "Display Results";
                }
                $scope.queryDone = true;
                $scope.currentPage = 0;
                $scope.pagedGroups = $scope.groupToPages($scope.rows);
            });
        }
    };

    $scope.selectRow = function selectRow(index){
        $scope.rows[index].selected = true;
    };

    $scope.selectFunction = function selectFunction(){
        if($scope.allRowsSelected()){
            // deselect all rows
            for(var x = 0; x < $scope.rows.length; ++x){
                $scope.rows[x].selected = false;
            }
        } else {
            // select all rows
            for(var x = 0; x < $scope.rows.length; ++x){
                $scope.rows[x].selected = true;
            }
        }
    };

    $scope.allRowsSelected = function allRowsSelected(){
        var retVal = true;

        for(var x = 0; x < $scope.rows.length; ++x){
            retVal = retVal && $scope.rows[x].selected;
        }

        return retVal;
    };

    $scope.anyRowsSelected = function anyRowsSelected(){
        var retVal = false;

        for(var x = 0; x < $scope.rows.length; ++x){
            retVal = retVal || $scope.rows[x].selected;
        }

        return retVal;
    };

    $scope.getGroup = function getGroup(filters){
        var group = {
            name: $scope.groupName,
            members: [],
            query_words: $scope.getQueryWords(),
            filters: JSON.stringify( filters )
        };

        var contactIndex = 0;

        for(var x = 0; x < $scope.fields.length; ++x){
            if($scope.fields[x].name === 'contact' ){
                contactIndex = x;
                break;
            }
        }

        for(var x = 0; x < $scope.rows.length; ++x){
            if($scope.rows[x].selected){
                group.members.push($scope.rows[x].fields[contactIndex]);
            }
        }

        return group;
    };

    $scope.saveGroup = function saveGroup(filters){
        var group = $scope.getGroup(filters);

        $scope.showMessage('Busy', 'Creating Group');
        $http.post('/create_contactgroup/', group, config={timeout: 300000}).
            success(function(status){
                $scope.hideMessage();
                $scope.showAlert('alert-success', 'Success:', status);
            }).
            error(function(data, status){
                $scope.hideMessage();
                $scope.showAlert('alert-warning', 'Failed:', status + ' : ' + data);
            });

        $scope.cancel();
    };

    //need group_key
    $scope.updateGroup = function updateGroup(filters){
        var group = $scope.getGroup(filters);
        group.group_key = $scope.groupKey;

        $http.post('/update_contactgroup/', group).
            success(function(status){
                $scope.showAlert('alert-success', 'Success', status);
            }).
            error(function(status){
                $scope.showAlert('alert-warning', 'Failed', 'Failed to update contact group.'  + '\n\n' + status);
            });

        $scope.cancel();
    };

    ///////PAGING/////
    $scope.groupToPages = function(results){
        var paged = [];
        var temp = results.slice();
        while (temp.length > 0)
        {
            paged.push(temp.splice(0, $scope.itemsPerPage));
        }
        return paged;
    };

    $scope.setPage = function (){
        $scope.currentPage = this.n;
    };

    $scope.cancel = function cancel(){
        $scope.hideCreateContact();
    };

    $scope.$watch('$parent.createGroup', function(newValue, oldValue){
        if(newValue){
            $scope.groupName = $scope.getGroupName();
        }
    });

    $scope.queryValid = function queryValid(){
        return $scope.getQueryValid();
    }

    $scope.toggleShowAllResults = function toggleShowAllResults(){
        $scope.showAllResults = !$scope.showAllResults;

        var retVal = $scope.toggleColumnsAndRows($scope.columns, $scope.rows);
        $scope.columns = retVal[0];
        $scope.rows = retVal[1];
    }
});
<|endoftext|>


<commit_before>define(function(require) {
    'use strict';

    var DataGridComponent;
    var helpers;
    var $ = require('jquery');
    var _ = require('underscore');
    var tools = require('oroui/js/tools');
    var mediator = require('oroui/js/mediator');
    var BaseComponent = require('oroui/js/app/components/base/component');
    var PageableCollection = require('orodatagrid/js/pageable-collection');
    var Grid = require('orodatagrid/js/datagrid/grid');
    var mapActionModuleName = require('orodatagrid/js/map-action-module-name');
    var mapCellModuleName = require('orodatagrid/js/map-cell-module-name');
    var gridContentManager = require('orodatagrid/js/content-manager');
    var FloatingHeaderPlugin = require('orodatagrid/js/app/plugins/grid/floating-header-plugin');
    var FullscreenPlugin = require('orodatagrid/js/app/plugins/grid/fullscreen-plugin');
    var ColumnManagerPlugin = require('orodatagrid/js/app/plugins/grid/column-manager-plugin');

    helpers = {
        cellType: function(type) {
            return type + 'Cell';
        },
        actionType: function(type) {
            return type + 'Action';
        }
    };

    /**
     * Runs passed builder
     *
     * @param {jQuery.Deferred} built
     * @param {Object} options
     * @param {Object} builder
     */
    function runBuilder(built, options, builder) {
        if (!_.has(builder, 'init') || !$.isFunction(builder.init)) {
            built.resolve();
            throw new TypeError('Builder does not have init method');
        }
        _.defer(_.bind(builder.init, builder), built, options);
    }

    DataGridComponent = BaseComponent.extend({
        initialize: function(options) {
            if (!options.enableFilters) {
                options.builders = _.reject(options.builders, function(module) {
                    return module === 'orofilter/js/datafilter-builder';
                });
            }
            options.builders.push('orodatagrid/js/inline-editing/builder');

            var self = this;
            this._deferredInit();
            this.built = $.Deferred();

            options = options || {};
            this.fixStates(options);
            this.processOptions(options);
            this.initDataGrid(options);

            var promises = [this.built.promise()];

            // run related builders
            _.each(options.builders, function(module) {
                var built = $.Deferred();
                promises.push(built.promise());
                require([module], _.partial(runBuilder, built, options));
            });

            $.when.apply($, promises).always(function() {
                self.subComponents = _.compact(arguments);
                self._resolveDeferredInit();
                self.$el.show();
                self.grid.trigger('shown');
            });
        },

        /**
         * Extends passed options
         *
         * @param options
         */
        processOptions: function(options) {
            if (typeof options.inputName === 'undefined') {
                throw new Error('Option inputName has to be specified');
            }

            options.$el = $(options.el);
            options.gridName = options.gridName || options.metadata.options.gridName;
            options.builders = options.builders || [];
            options.builders.push('orodatagrid/js/grid-views-builder');
            options.gridPromise = this.built.promise();
        },

        /**
         * Collects required modules and runs grid builder
         *
         * @param {Object} options
         */
        initDataGrid: function(options) {
            this.$el = $('<div>');
            $(options.el).append(this.$el);
            this.gridName = options.gridName;
            this.inputName = options.inputName;
            this.data = options.data;
            this.metadata = _.defaults(options.metadata, {
                columns: [],
                options: {},
                state: {},
                initialState: {},
                rowActions: {},
                massActions: {}
            });
            this.modules = {};

            this.collectModules();

            // load all dependencies and build grid
            tools.loadModules(this.modules, this.build, this);
        },

        /**
         * Collects required modules
         */
        collectModules: function() {
            var modules = this.modules;
            var metadata = this.metadata;
            // cells
            _.each(metadata.columns, function(column) {
                var type = column.type;
                modules[helpers.cellType(type)] = mapCellModuleName(type);
            });
            // row actions
            _.each(_.values(metadata.rowActions), function(action) {
                var type = action.frontend_type;
                modules[helpers.actionType(type)] = mapActionModuleName(type);
            });
            // mass actions
            _.each(_.values(metadata.massActions), function(action) {
                var type = action.frontend_type;
                modules[helpers.actionType(type)] = mapActionModuleName(type);
            });
        },

        /**
         * Build grid
         */
        build: function() {
            var collectionOptions;
            var grid;

            var collectionName = this.gridName;
            var collection = gridContentManager.get(collectionName);
            if (!collection) {
                // otherwise, create collection from metadata
                collectionOptions = this.combineCollectionOptions();
                collection = new PageableCollection(this.data, collectionOptions);
            } else if (this.data) {
                collection.reset(this.data, {parse: true});
            }

            // create grid
            var options = this.combineGridOptions();
            mediator.trigger('datagrid_create_before', options, collection);

            this.$el.hide();
            options.el = this.$el[0];
            grid = new Grid(_.extend({collection: collection}, options));
            this.grid = grid;
            grid.render();
            mediator.trigger('datagrid:rendered');

            if (options.routerEnabled !== false) {
                // trace collection changes
                gridContentManager.trace(collection);
            }

            var deferredBuilt = this.built;
            if (grid.deferredRender) {
                grid.deferredRender.then(function() {
                    deferredBuilt.resolve(grid);
                });
            } else {
                deferredBuilt.resolve(grid);
            }
        },

        /**
         * Process metadata and combines options for collection
         *
         * @returns {Object}
         */
        combineCollectionOptions: function() {
            var options = _.extend({
                inputName: this.inputName,
                parse: true,
                url: '\/user\/json',
                state: _.extend({
                    filters: {},
                    sorters: {},
                    columns: {}
                }, this.metadata.state),
                initialState: this.metadata.initialState
            }, this.metadata.options);
            return options;
        },

        /**
         * Process metadata and combines options for datagrid
         *
         * @returns {Object}
         */
        combineGridOptions: function() {
            var columns;
            var rowActions = {};
            var massActions = {};
            var defaultOptions = {
                sortable: false
            };
            var modules = this.modules;
            var metadata = this.metadata;
            var plugins = this.metadata.plugins || [];

            // columns
            columns = _.map(metadata.columns, function(cell) {
                var cellOptionKeys = ['name', 'label', 'renderable', 'editable', 'sortable', 'align',
                    'order', 'manageable', 'required'];
                var cellOptions = _.extend({}, defaultOptions, _.pick.apply(null, [cell].concat(cellOptionKeys)));
                var extendOptions = _.omit.apply(null, [cell].concat(cellOptionKeys.concat('type')));
                var cellType = modules[helpers.cellType(cell.type)];
                if (!_.isEmpty(extendOptions)) {
                    cellType = cellType.extend(extendOptions);
                }
                cellOptions.cell = cellType;
                return cellOptions;
            });

            // row actions
            _.each(metadata.rowActions, function(options, action) {
                rowActions[action] = modules[helpers.actionType(options.frontend_type)].extend(options);
            });

            // mass actions
            _.each(metadata.massActions, function(options, action) {
                massActions[action] = modules[helpers.actionType(options.frontend_type)].extend(options);
            });

            if (tools.isMobile()) {
                plugins.push(FloatingHeaderPlugin);
            } else {
                if (this.metadata.enableFullScreenLayout) {
                    plugins.push(FullscreenPlugin);
                }
            }

            if (metadata.options.toolbarOptions.addColumnManager) {
                plugins.push(ColumnManagerPlugin);
            }

            return {
                name: this.gridName,
                columns: columns,
                rowActions: rowActions,
                massActions: massActions,
                toolbarOptions: metadata.options.toolbarOptions || {},
                multipleSorting: metadata.options.multipleSorting || false,
                entityHint: metadata.options.entityHint,
                exportOptions: metadata.options.export || {},
                routerEnabled: _.isUndefined(metadata.options.routerEnabled) ? true : metadata.options.routerEnabled,
                multiSelectRowEnabled: metadata.options.multiSelectRowEnabled || !_.isEmpty(massActions),
                metadata: this.metadata,
                plugins: plugins
            };
        },

        fixStates: function(options) {
            if (options.metadata) {
                this.fixState(options.metadata.state);
                this.fixState(options.metadata.initialState);
            }
        },

        fixState: function(state) {
            if (_.isArray(state.filters) && _.isEmpty(state.filters)) {
                state.filters = {};
            }

            if (_.isArray(state.sorters) && _.isEmpty(state.sorters)) {
                state.sorters = {};
            }
        },

        dispose: function() {
            // disposes registered sub-components
            if (this.subComponents) {
                _.each(this.subComponents, function(component) {
                    if (component && typeof component.dispose === 'function') {
                        component.dispose();
                    }
                });
                delete this.subComponents;
            }
            DataGridComponent.__super__.dispose.call(this);
        }
    });

    return DataGridComponent;
});
<commit_msg>COM-214: Add quantity validation  - added grid instance as:rendered JS event parameter<commit_after>define(function(require) {
    'use strict';

    var DataGridComponent;
    var helpers;
    var $ = require('jquery');
    var _ = require('underscore');
    var tools = require('oroui/js/tools');
    var mediator = require('oroui/js/mediator');
    var BaseComponent = require('oroui/js/app/components/base/component');
    var PageableCollection = require('orodatagrid/js/pageable-collection');
    var Grid = require('orodatagrid/js/datagrid/grid');
    var mapActionModuleName = require('orodatagrid/js/map-action-module-name');
    var mapCellModuleName = require('orodatagrid/js/map-cell-module-name');
    var gridContentManager = require('orodatagrid/js/content-manager');
    var FloatingHeaderPlugin = require('orodatagrid/js/app/plugins/grid/floating-header-plugin');
    var FullscreenPlugin = require('orodatagrid/js/app/plugins/grid/fullscreen-plugin');
    var ColumnManagerPlugin = require('orodatagrid/js/app/plugins/grid/column-manager-plugin');

    helpers = {
        cellType: function(type) {
            return type + 'Cell';
        },
        actionType: function(type) {
            return type + 'Action';
        }
    };

    /**
     * Runs passed builder
     *
     * @param {jQuery.Deferred} built
     * @param {Object} options
     * @param {Object} builder
     */
    function runBuilder(built, options, builder) {
        if (!_.has(builder, 'init') || !$.isFunction(builder.init)) {
            built.resolve();
            throw new TypeError('Builder does not have init method');
        }
        _.defer(_.bind(builder.init, builder), built, options);
    }

    DataGridComponent = BaseComponent.extend({
        initialize: function(options) {
            if (!options.enableFilters) {
                options.builders = _.reject(options.builders, function(module) {
                    return module === 'orofilter/js/datafilter-builder';
                });
            }
            options.builders.push('orodatagrid/js/inline-editing/builder');

            var self = this;
            this._deferredInit();
            this.built = $.Deferred();

            options = options || {};
            this.fixStates(options);
            this.processOptions(options);
            this.initDataGrid(options);

            var promises = [this.built.promise()];

            // run related builders
            _.each(options.builders, function(module) {
                var built = $.Deferred();
                promises.push(built.promise());
                require([module], _.partial(runBuilder, built, options));
            });

            $.when.apply($, promises).always(function() {
                self.subComponents = _.compact(arguments);
                self._resolveDeferredInit();
                self.$el.show();
                self.grid.trigger('shown');
            });
        },

        /**
         * Extends passed options
         *
         * @param options
         */
        processOptions: function(options) {
            if (typeof options.inputName === 'undefined') {
                throw new Error('Option inputName has to be specified');
            }

            options.$el = $(options.el);
            options.gridName = options.gridName || options.metadata.options.gridName;
            options.builders = options.builders || [];
            options.builders.push('orodatagrid/js/grid-views-builder');
            options.gridPromise = this.built.promise();
        },

        /**
         * Collects required modules and runs grid builder
         *
         * @param {Object} options
         */
        initDataGrid: function(options) {
            this.$el = $('<div>');
            $(options.el).append(this.$el);
            this.gridName = options.gridName;
            this.inputName = options.inputName;
            this.data = options.data;
            this.metadata = _.defaults(options.metadata, {
                columns: [],
                options: {},
                state: {},
                initialState: {},
                rowActions: {},
                massActions: {}
            });
            this.modules = {};

            this.collectModules();

            // load all dependencies and build grid
            tools.loadModules(this.modules, this.build, this);
        },

        /**
         * Collects required modules
         */
        collectModules: function() {
            var modules = this.modules;
            var metadata = this.metadata;
            // cells
            _.each(metadata.columns, function(column) {
                var type = column.type;
                modules[helpers.cellType(type)] = mapCellModuleName(type);
            });
            // row actions
            _.each(_.values(metadata.rowActions), function(action) {
                var type = action.frontend_type;
                modules[helpers.actionType(type)] = mapActionModuleName(type);
            });
            // mass actions
            _.each(_.values(metadata.massActions), function(action) {
                var type = action.frontend_type;
                modules[helpers.actionType(type)] = mapActionModuleName(type);
            });
        },

        /**
         * Build grid
         */
        build: function() {
            var collectionOptions;
            var grid;

            var collectionName = this.gridName;
            var collection = gridContentManager.get(collectionName);
            if (!collection) {
                // otherwise, create collection from metadata
                collectionOptions = this.combineCollectionOptions();
                collection = new PageableCollection(this.data, collectionOptions);
            } else if (this.data) {
                collection.reset(this.data, {parse: true});
            }

            // create grid
            var options = this.combineGridOptions();
            mediator.trigger('datagrid_create_before', options, collection);

            this.$el.hide();
            options.el = this.$el[0];
            grid = new Grid(_.extend({collection: collection}, options));
            this.grid = grid;
            grid.render();
            mediator.trigger('datagrid:rendered', grid);

            if (options.routerEnabled !== false) {
                // trace collection changes
                gridContentManager.trace(collection);
            }

            var deferredBuilt = this.built;
            if (grid.deferredRender) {
                grid.deferredRender.then(function() {
                    deferredBuilt.resolve(grid);
                });
            } else {
                deferredBuilt.resolve(grid);
            }
        },

        /**
         * Process metadata and combines options for collection
         *
         * @returns {Object}
         */
        combineCollectionOptions: function() {
            var options = _.extend({
                inputName: this.inputName,
                parse: true,
                url: '\/user\/json',
                state: _.extend({
                    filters: {},
                    sorters: {},
                    columns: {}
                }, this.metadata.state),
                initialState: this.metadata.initialState
            }, this.metadata.options);
            return options;
        },

        /**
         * Process metadata and combines options for datagrid
         *
         * @returns {Object}
         */
        combineGridOptions: function() {
            var columns;
            var rowActions = {};
            var massActions = {};
            var defaultOptions = {
                sortable: false
            };
            var modules = this.modules;
            var metadata = this.metadata;
            var plugins = this.metadata.plugins || [];

            // columns
            columns = _.map(metadata.columns, function(cell) {
                var cellOptionKeys = ['name', 'label', 'renderable', 'editable', 'sortable', 'align',
                    'order', 'manageable', 'required'];
                var cellOptions = _.extend({}, defaultOptions, _.pick.apply(null, [cell].concat(cellOptionKeys)));
                var extendOptions = _.omit.apply(null, [cell].concat(cellOptionKeys.concat('type')));
                var cellType = modules[helpers.cellType(cell.type)];
                if (!_.isEmpty(extendOptions)) {
                    cellType = cellType.extend(extendOptions);
                }
                cellOptions.cell = cellType;
                return cellOptions;
            });

            // row actions
            _.each(metadata.rowActions, function(options, action) {
                rowActions[action] = modules[helpers.actionType(options.frontend_type)].extend(options);
            });

            // mass actions
            _.each(metadata.massActions, function(options, action) {
                massActions[action] = modules[helpers.actionType(options.frontend_type)].extend(options);
            });

            if (tools.isMobile()) {
                plugins.push(FloatingHeaderPlugin);
            } else {
                if (this.metadata.enableFullScreenLayout) {
                    plugins.push(FullscreenPlugin);
                }
            }

            if (metadata.options.toolbarOptions.addColumnManager) {
                plugins.push(ColumnManagerPlugin);
            }

            return {
                name: this.gridName,
                columns: columns,
                rowActions: rowActions,
                massActions: massActions,
                toolbarOptions: metadata.options.toolbarOptions || {},
                multipleSorting: metadata.options.multipleSorting || false,
                entityHint: metadata.options.entityHint,
                exportOptions: metadata.options.export || {},
                routerEnabled: _.isUndefined(metadata.options.routerEnabled) ? true : metadata.options.routerEnabled,
                multiSelectRowEnabled: metadata.options.multiSelectRowEnabled || !_.isEmpty(massActions),
                metadata: this.metadata,
                plugins: plugins
            };
        },

        fixStates: function(options) {
            if (options.metadata) {
                this.fixState(options.metadata.state);
                this.fixState(options.metadata.initialState);
            }
        },

        fixState: function(state) {
            if (_.isArray(state.filters) && _.isEmpty(state.filters)) {
                state.filters = {};
            }

            if (_.isArray(state.sorters) && _.isEmpty(state.sorters)) {
                state.sorters = {};
            }
        },

        dispose: function() {
            // disposes registered sub-components
            if (this.subComponents) {
                _.each(this.subComponents, function(component) {
                    if (component && typeof component.dispose === 'function') {
                        component.dispose();
                    }
                });
                delete this.subComponents;
            }
            DataGridComponent.__super__.dispose.call(this);
        }
    });

    return DataGridComponent;
});
<|endoftext|>


<commit_before>//
// Touristic Content
//

$(window).on('entity:map', function (e, data) {

    var map = data.map;
    var loaded_event = false;
    var loaded_touristic = false;
    // Show tourism layer in application maps
    $.each(['touristiccontent', 'touristicevent'], function (i, modelname) {
        var layer = new L.ObjectsLayer(null, {
            modelname: modelname,
            style: L.Util.extend(window.SETTINGS.map.styles[modelname] || {}, {clickable:false}),
        });
        map.layerscontrol.addOverlay(layer, tr(modelname), tr('Tourism'));

        map.on('layeradd', function(e){
            var options = e.layer.options || {'modelname': 'None'};
            if (! loaded_event){

                if (options.modelname == 'touristicevent'){
                    e.layer.load(window.SETTINGS.urls.touristicevent_layer);
                    loaded_event = true;
                }
            }
            if (! loaded_touristic){
                if (options.modelname == 'touristiccontent'){
                    e.layer.load(window.SETTINGS.urls.touristiccontent_layer);
                    loaded_touristic = true;
                }
        }
    });
    });
});

$(window).on('entity:view:list', function (e, data) {

    // Date picker
    $('#id_before, #id_after').datepicker({
        autoclose: true,
        language: window.SETTINGS.languages.default,
        format: window.SETTINGS.date_format
    });
    // prevent click on datepicker to close the filter popover
    $(document).on('click', '.datepicker, span.month, th.next, th.prev, th.datepicker-switch, span.year, td.day', function (e) {
        e.stopPropagation();
    });

    // Tooltips on categories in list view
    if (data.modelname != 'touristiccontent')
        return;
    $('.categories-filter a').tooltip();

    var $addButton = $("#list-panel .btn-toolbar .btn.btn-success").first();
    var addUrl = $addButton.attr('href');

    // Refresh list filter when click on a category button
    $('.categories-filter a').click(function () {
        var $this = $(this);

        // Show current in orange
        $('.categories-filter a').removeClass('btn-warning');
        $this.addClass('btn-warning');

        var category = $this.data('category');
        if (category) {
            // Category chosen
            $('select#id_category').val(category)
                                   .addClass('filter-set');
            $addButton.attr('href', addUrl + '?category=' + category);
        }
        else {
            // All chosen.
            $("select#id_category option").prop("selected", false);
            $('select#id_category').removeClass('filter-set');
            $addButton.attr('href', addUrl);
        }

        // Simulate form submission
        $('#mainfilter a#filter').click();
    });

    // Refresh types by category
    $('#mainfilter #id_category').change(function() {
        update_touristiccontent_types('1');
        update_touristiccontent_types('2');
    });
    $('#mainfilter #id_category').trigger('change');
});

$(window).on('entity:view:add entity:view:update', function (e, data) {

    // Date picker
    $('#id_begin_date, #id_end_date').datepicker({
        autoclose: true,
        language: window.SETTINGS.languages.default,
        format: window.SETTINGS.date_format
    });

    // Chosen on themes etc...
    $('select[multiple]').chosen({
        no_results_text: tr("No result"),
        placeholder_text_multiple: tr("Choose value(s)")
    });

    if (data.modelname != 'touristiccontent')
        return;

    // Refresh types by category
    $('#id_category').change(function() {
        update_touristiccontent_types('1');
        update_touristiccontent_types('2');

        // Hide geometry controls depending on category
        var categories = JSON.parse($('#categories-types').text());
        var category = $(this).val();
        var geometry_type = category ? categories[category]['geometry_type'] : 'any';
        if (geometry_type == 'any') {
            $('.leaflet-draw-toolbar a').show();
        }
        else {
            $('.leaflet-draw-toolbar-top a').hide();
            var controls = {'point': 'marker', 'line': 'polyline', 'polygon': 'polygon'};
            $('.leaflet-draw-toolbar a.leaflet-draw-draw-' + controls[geometry_type]).show();
        }
    });
    $('#id_category').trigger('change');
});

function update_touristiccontent_types(n) {
    var categories = JSON.parse($('#categories-types').text());
    var category = $('#id_category').val();
    var $select = $('#id_type' + n);
    var selected = $select.val() || [];

    var types_values = category ? categories[category]['type' + n + '_values'] : {};
    var type_label = category ? categories[category]['type' + n + '_label'] : '';

    // Refresh type label
    $('label[for=id_type' + n + ']').text(type_label);

    // Hide type field if no values for this category
    $('#div_id_type' + n).toggle(Object.keys(types_values).length > 0);

    // Refresh options list for types, depending on category
    $select.empty();
    for(var type_id in types_values) {
        var type_name = types_values[type_id];
        $('<option/>')
            .text(type_name)
            .attr('value', type_id)
            .prop('selected', selected.indexOf(type_id) >= 0)
            .appendTo($select);
    }
    $select.trigger('chosen:updated');
}
<commit_msg>Fix problems with options modelname equal data modelname<commit_after>//
// Touristic Content
//

$(window).on('entity:map', function (e, data) {

    var map = data.map;
    var loaded_event = false;
    var loaded_touristic = false;
    // Show tourism layer in application maps
    $.each(['touristiccontent', 'touristicevent'], function (i, modelname) {
        var layer = new L.ObjectsLayer(null, {
            modelname: modelname,
            style: L.Util.extend(window.SETTINGS.map.styles[modelname] || {}, {clickable:false}),
        });
        if (data.modelname != modelname){
            map.layerscontrol.addOverlay(layer, tr(modelname), tr('Tourism'));
        };
        map.on('layeradd', function(e){
            var options = e.layer.options || {'modelname': 'None'};
            if (! loaded_event){
                if (options.modelname == 'touristicevent' && options.modelname != data.modelname){
                    e.layer.load(window.SETTINGS.urls.touristicevent_layer);
                    loaded_event = true;
                }
            }
            if (! loaded_touristic){
                if (options.modelname == 'touristiccontent' && options.modelname != data.modelname){
                    e.layer.load(window.SETTINGS.urls.touristiccontent_layer);
                    loaded_touristic = true;
                }
        }
    });
    });
});

$(window).on('entity:view:list', function (e, data) {

    // Date picker
    $('#id_before, #id_after').datepicker({
        autoclose: true,
        language: window.SETTINGS.languages.default,
        format: window.SETTINGS.date_format
    });
    // prevent click on datepicker to close the filter popover
    $(document).on('click', '.datepicker, span.month, th.next, th.prev, th.datepicker-switch, span.year, td.day', function (e) {
        e.stopPropagation();
    });

    // Tooltips on categories in list view
    if (data.modelname != 'touristiccontent')
        return;
    $('.categories-filter a').tooltip();

    var $addButton = $("#list-panel .btn-toolbar .btn.btn-success").first();
    var addUrl = $addButton.attr('href');

    // Refresh list filter when click on a category button
    $('.categories-filter a').click(function () {
        var $this = $(this);

        // Show current in orange
        $('.categories-filter a').removeClass('btn-warning');
        $this.addClass('btn-warning');

        var category = $this.data('category');
        if (category) {
            // Category chosen
            $('select#id_category').val(category)
                                   .addClass('filter-set');
            $addButton.attr('href', addUrl + '?category=' + category);
        }
        else {
            // All chosen.
            $("select#id_category option").prop("selected", false);
            $('select#id_category').removeClass('filter-set');
            $addButton.attr('href', addUrl);
        }

        // Simulate form submission
        $('#mainfilter a#filter').click();
    });

    // Refresh types by category
    $('#mainfilter #id_category').change(function() {
        update_touristiccontent_types('1');
        update_touristiccontent_types('2');
    });
    $('#mainfilter #id_category').trigger('change');
});

$(window).on('entity:view:add entity:view:update', function (e, data) {

    // Date picker
    $('#id_begin_date, #id_end_date').datepicker({
        autoclose: true,
        language: window.SETTINGS.languages.default,
        format: window.SETTINGS.date_format
    });

    // Chosen on themes etc...
    $('select[multiple]').chosen({
        no_results_text: tr("No result"),
        placeholder_text_multiple: tr("Choose value(s)")
    });

    if (data.modelname != 'touristiccontent')
        return;

    // Refresh types by category
    $('#id_category').change(function() {
        update_touristiccontent_types('1');
        update_touristiccontent_types('2');

        // Hide geometry controls depending on category
        var categories = JSON.parse($('#categories-types').text());
        var category = $(this).val();
        var geometry_type = category ? categories[category]['geometry_type'] : 'any';
        if (geometry_type == 'any') {
            $('.leaflet-draw-toolbar a').show();
        }
        else {
            $('.leaflet-draw-toolbar-top a').hide();
            var controls = {'point': 'marker', 'line': 'polyline', 'polygon': 'polygon'};
            $('.leaflet-draw-toolbar a.leaflet-draw-draw-' + controls[geometry_type]).show();
        }
    });
    $('#id_category').trigger('change');
});

function update_touristiccontent_types(n) {
    var categories = JSON.parse($('#categories-types').text());
    var category = $('#id_category').val();
    var $select = $('#id_type' + n);
    var selected = $select.val() || [];

    var types_values = category ? categories[category]['type' + n + '_values'] : {};
    var type_label = category ? categories[category]['type' + n + '_label'] : '';

    // Refresh type label
    $('label[for=id_type' + n + ']').text(type_label);

    // Hide type field if no values for this category
    $('#div_id_type' + n).toggle(Object.keys(types_values).length > 0);

    // Refresh options list for types, depending on category
    $select.empty();
    for(var type_id in types_values) {
        var type_name = types_values[type_id];
        $('<option/>')
            .text(type_name)
            .attr('value', type_id)
            .prop('selected', selected.indexOf(type_id) >= 0)
            .appendTo($select);
    }
    $select.trigger('chosen:updated');
}
<|endoftext|>