<commit_before>// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {searchSegment} from '../base/binary_search';
import {Actions} from '../common/actions';
import {getContainingTrackId} from '../common/state';
import {fromNs, TimeSpan, toNs} from '../common/time';

import {globals} from './globals';

export function executeSearch(reverse = false) {
  const state = globals.frontendLocalState;
  const index = state.searchIndex;
  const startNs = toNs(globals.frontendLocalState.visibleWindowTime.start);
  const endNs = toNs(globals.frontendLocalState.visibleWindowTime.end);
  const currentTs = globals.currentSearchResults.tsStarts[index];

  // If this is a new search or the currentTs is not in the viewport,
  // select the first/last item in the viewport.
  if (index === -1 || currentTs < startNs || currentTs > endNs) {
    if (reverse) {
      const [smaller,] =
        searchSegment(globals.currentSearchResults.tsStarts, endNs);
      globals.frontendLocalState.setSearchIndex(smaller);
    } else {
      const [, larger] =
          searchSegment(globals.currentSearchResults.tsStarts, startNs);
      globals.frontendLocalState.setSearchIndex(larger);
    }
    // If there is no result in the current viewport, move it.
    const currentTs = globals.currentSearchResults.tsStarts[state.searchIndex];
    if (currentTs < startNs || currentTs > endNs) {
      moveViewportToCurrentSearch();
    }
  } else {
    // If the currentTs is in the viewport, increment the index and move the
    // viewport if necessary.
    if (reverse) {
      globals.frontendLocalState.setSearchIndex(Math.max(index - 1, 0));
    } else {
      globals.frontendLocalState.setSearchIndex(Math.min(
          index + 1, globals.currentSearchResults.sliceIds.length - 1));
    }
    moveViewportToCurrentSearch();
  }
  selectCurrentSearchResult();
}

function moveViewportToCurrentSearch() {
  // Move viewport if our selection moves outside.
  const startNs = toNs(globals.frontendLocalState.visibleWindowTime.start);
  const endNs = toNs(globals.frontendLocalState.visibleWindowTime.end);
  const currentTs = globals.currentSearchResults
                        .tsStarts[globals.frontendLocalState.searchIndex];
  const currentViewNs = endNs - startNs;
  if (currentTs < startNs || currentTs > endNs) {
    // TODO(taylori): This is an ugly jump, we should do a smooth pan instead.
    globals.frontendLocalState.updateVisibleTime(new TimeSpan(
        fromNs(currentTs - currentViewNs / 2),
        fromNs(currentTs + currentViewNs / 2)));
  }

  // Update vertical (up/down) scroll position
  const trackId = globals.currentSearchResults
                      .trackIds[globals.frontendLocalState.searchIndex];
  let track = document.querySelector('#track_' + trackId);

  if (!track) {
    const parentTrackId = getContainingTrackId(globals.state, trackId);
    if (parentTrackId) {
      track = document.querySelector('#track_' + parentTrackId);
    }
  }

  if (!track) {
    console.error(`Can't scroll search result track not found (${trackId})`);
    return;
  }

  // block: 'nearest' means that it will only scroll if the track is not
  // currently in view.
  track.scrollIntoView({behavior: 'smooth', block: 'nearest'});
}

function selectCurrentSearchResult() {
  const state = globals.frontendLocalState;
  const index = state.searchIndex;
  const refType = globals.currentSearchResults.refTypes[index];
  const currentId = globals.currentSearchResults.sliceIds[index];

  if (currentId === undefined) return;

  if (refType === 'cpu') {
    globals.dispatch(Actions.selectSlice({
      utid: globals.currentSearchResults.utids[index],
      id: currentId,
    }));
  }
  if (refType === 'utid') {
    globals.dispatch(Actions.selectChromeSlice({
      slice_id: currentId,
    }));
  }
}<commit_msg>perfetto-ui: Fix build am: 59d12490ef am: 19a2deb94f am: 83616804da<commit_after>// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {searchSegment} from '../base/binary_search';
import {Actions} from '../common/actions';
import {getContainingTrackId} from '../common/state';
import {fromNs, TimeSpan, toNs} from '../common/time';

import {globals} from './globals';

export function executeSearch(reverse = false) {
  const state = globals.frontendLocalState;
  const index = state.searchIndex;
  const startNs = toNs(globals.frontendLocalState.visibleWindowTime.start);
  const endNs = toNs(globals.frontendLocalState.visibleWindowTime.end);
  const currentTs = globals.currentSearchResults.tsStarts[index];

  // If this is a new search or the currentTs is not in the viewport,
  // select the first/last item in the viewport.
  if (index === -1 || currentTs < startNs || currentTs > endNs) {
    if (reverse) {
      const [smaller,] =
        searchSegment(globals.currentSearchResults.tsStarts, endNs);
      globals.frontendLocalState.setSearchIndex(smaller);
    } else {
      const [, larger] =
          searchSegment(globals.currentSearchResults.tsStarts, startNs);
      globals.frontendLocalState.setSearchIndex(larger);
    }
    // If there is no result in the current viewport, move it.
    const currentTs = globals.currentSearchResults.tsStarts[state.searchIndex];
    if (currentTs < startNs || currentTs > endNs) {
      moveViewportToCurrentSearch();
    }
  } else {
    // If the currentTs is in the viewport, increment the index and move the
    // viewport if necessary.
    if (reverse) {
      globals.frontendLocalState.setSearchIndex(Math.max(index - 1, 0));
    } else {
      globals.frontendLocalState.setSearchIndex(Math.min(
          index + 1, globals.currentSearchResults.sliceIds.length - 1));
    }
    moveViewportToCurrentSearch();
  }
  selectCurrentSearchResult();
}

function moveViewportToCurrentSearch() {
  // Move viewport if our selection moves outside.
  const startNs = toNs(globals.frontendLocalState.visibleWindowTime.start);
  const endNs = toNs(globals.frontendLocalState.visibleWindowTime.end);
  const currentTs = globals.currentSearchResults
                        .tsStarts[globals.frontendLocalState.searchIndex];
  const currentViewNs = endNs - startNs;
  if (currentTs < startNs || currentTs > endNs) {
    // TODO(taylori): This is an ugly jump, we should do a smooth pan instead.
    globals.frontendLocalState.updateVisibleTime(new TimeSpan(
        fromNs(currentTs - currentViewNs / 2),
        fromNs(currentTs + currentViewNs / 2)));
  }

  // Update vertical (up/down) scroll position
  const trackId = globals.currentSearchResults
                      .trackIds[globals.frontendLocalState.searchIndex];
  let track = document.querySelector('#track_' + trackId);

  if (!track) {
    const parentTrackId = getContainingTrackId(globals.state, trackId);
    if (parentTrackId) {
      track = document.querySelector('#track_' + parentTrackId);
    }
  }

  if (!track) {
    console.error(`Can't scroll search result track not found (${trackId})`);
    return;
  }

  // block: 'nearest' means that it will only scroll if the track is not
  // currently in view.
  track.scrollIntoView({behavior: 'smooth', block: 'nearest'});
}

function selectCurrentSearchResult() {
  const state = globals.frontendLocalState;
  const index = state.searchIndex;
  const refType = globals.currentSearchResults.refTypes[index];
  const currentId = globals.currentSearchResults.sliceIds[index];

  if (currentId === undefined) return;

  if (refType === 'cpu') {
    globals.dispatch(Actions.selectSlice({
      utid: globals.currentSearchResults.utids[index],
      id: currentId,
    }));
  }
  if (refType === 'utid') {
    globals.dispatch(Actions.selectChromeSlice({
      id: currentId,
    }));
  }
}
{'fraction_non_alphanumeric': 0.10860190649114844, 'fraction_numerical': 0.005674080798910576, 'mean_word_length': 3.599686847599165, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '6324648', 'n_tokens_mistral': 2623, 'n_tokens_neox': 2544, 'n_words': 718}