<commit_before>/**
 * @license
 * Copyright (c) 2018 Google Inc. All rights reserved.
 * This code may only be used under the BSD style license found at
 * http://polymer.github.io/LICENSE.txt
 * Code distributed by Google as part of this project is also
 * subject to an additional IP rights grant found at
 * http://polymer.github.io/PATENTS.txt
 */
import {ModalityHandler} from './modality-handler.js';
import {SlotComposer} from './slot-composer.js';
import {Arc} from './arc.js';
import {Suggestion} from './plan/suggestion.js';
import {SuggestDomConsumer} from './suggest-dom-consumer.js';
import {ProvidedSlotContext} from './slot-context.js';

export class SuggestionComposer {
  private _container: HTMLElement | undefined; // eg div element.

  private readonly _slotComposer: SlotComposer;
  private readonly arc: Arc;
  private _suggestions: Suggestion[] = [];

  // used in tests
  protected readonly _suggestConsumers: SuggestDomConsumer[] = [];

  constructor(arc: Arc, slotComposer: SlotComposer) {
    this._container = slotComposer.findContainerByName('suggestions');
    this._slotComposer = slotComposer;
    this.arc = arc;
  }

  get modalityHandler(): ModalityHandler { return this._slotComposer.modalityHandler; }

  clear(): void {
    if (this._container) {
      this.modalityHandler.slotConsumerClass.clear(this._container);
    }
    this._suggestConsumers.forEach(consumer => consumer.dispose());
    this._suggestConsumers.length = 0;
  }

  setSuggestions(suggestions: Suggestion[]) {
    this.clear();

    const sortedSuggestions = suggestions.sort(Suggestion.compare);
    for (const suggestion of sortedSuggestions) {
      // TODO(mmandlis): use modality-appropriate description.
      const suggestionContent = {template: suggestion.descriptionText};
      if (!suggestionContent) {
        throw new Error('No suggestion content available');
      }

      if (this._container) {
        this.modalityHandler.suggestionConsumerClass.render(this.arc, this._container, suggestion, suggestionContent);
      }

      this._addInlineSuggestion(suggestion, suggestionContent);
    }
  }

  private _addInlineSuggestion(suggestion, suggestionContent): void {
    const remoteSlots = suggestion.plan.slots.filter(s => !!s.id);
    if (remoteSlots.length !== 1) {
      return;
    }
    const remoteSlot = remoteSlots[0];

    const context = this._slotComposer.findContextById(remoteSlot.id) as ProvidedSlotContext;
    if (!context) {
      throw new Error('Missing context for ' + remoteSlot.id);
    }

    if (context.spec.isSet) {
      // TODO: Inline suggestion in a set slot is not supported yet. Implement!
      return;
    }
<commit_msg>fix inline suggestion instantiation (#2617)<commit_after>/**
 * @license
 * Copyright (c) 2018 Google Inc. All rights reserved.
 * This code may only be used under the BSD style license found at
 * http://polymer.github.io/LICENSE.txt
 * Code distributed by Google as part of this project is also
 * subject to an additional IP rights grant found at
 * http://polymer.github.io/PATENTS.txt
 */
import {ModalityHandler} from './modality-handler.js';
import {SlotComposer} from './slot-composer.js';
import {Arc} from './arc.js';
import {Suggestion} from './plan/suggestion.js';
import {SuggestDomConsumer} from './suggest-dom-consumer.js';
import {ProvidedSlotContext} from './slot-context.js';

export class SuggestionComposer {
  private _container: HTMLElement | undefined; // eg div element.

  private readonly _slotComposer: SlotComposer;
  private readonly arc: Arc;
  private _suggestions: Suggestion[] = [];

  // used in tests
  protected readonly _suggestConsumers: SuggestDomConsumer[] = [];

  constructor(arc: Arc, slotComposer: SlotComposer) {
    this._container = slotComposer.findContainerByName('suggestions');
    this._slotComposer = slotComposer;
    this.arc = arc;
  }

  get modalityHandler(): ModalityHandler { return this._slotComposer.modalityHandler; }

  clear(): void {
    if (this._container) {
      this.modalityHandler.slotConsumerClass.clear(this._container);
    }
    this._suggestConsumers.forEach(consumer => consumer.dispose());
    this._suggestConsumers.length = 0;
  }

  setSuggestions(suggestions: Suggestion[]) {
    this.clear();

    this._suggestions = suggestions.sort(Suggestion.compare);
    for (const suggestion of this._suggestions) {
      // TODO(mmandlis): use modality-appropriate description.
      const suggestionContent = {template: suggestion.descriptionText};
      if (!suggestionContent) {
        throw new Error('No suggestion content available');
      }

      if (this._container) {
        this.modalityHandler.suggestionConsumerClass.render(this.arc, this._container, suggestion, suggestionContent);
      }

      this._addInlineSuggestion(suggestion, suggestionContent);
    }
  }

  private _addInlineSuggestion(suggestion, suggestionContent): void {
    const remoteSlots = suggestion.plan.slots.filter(s => !!s.id);
    if (remoteSlots.length !== 1) {
      return;
    }
    const remoteSlot = remoteSlots[0];

    const context = this._slotComposer.findContextById(remoteSlot.id) as ProvidedSlotContext;
    if (!context) {
      throw new Error('Missing context for ' + remoteSlot.id);
    }

    if (context.spec.isSet) {
      // TODO: Inline suggestion in a set slot is not supported yet. Implement!
      return;
    }

{'fraction_non_alphanumeric': 0.11265775798069785, 'fraction_numerical': 0.0033407572383073497, 'mean_word_length': 3.777482269503546, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5610053', 'n_tokens_mistral': 1593, 'n_tokens_neox': 1502, 'n_words': 401}