11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciexport function anyToString(x: any): string {
61cb0ef41Sopenharmony_ci  return "" + x;
71cb0ef41Sopenharmony_ci}
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cifunction computeScrollTop(container, element) {
101cb0ef41Sopenharmony_ci  const height = container.offsetHeight;
111cb0ef41Sopenharmony_ci  const margin = Math.floor(height / 4);
121cb0ef41Sopenharmony_ci  const pos = element.offsetTop;
131cb0ef41Sopenharmony_ci  const currentScrollTop = container.scrollTop;
141cb0ef41Sopenharmony_ci  if (pos < currentScrollTop + margin) {
151cb0ef41Sopenharmony_ci    return Math.max(0, pos - margin);
161cb0ef41Sopenharmony_ci  } else if (pos > (currentScrollTop + 3 * margin)) {
171cb0ef41Sopenharmony_ci    return Math.max(0, pos - 3 * margin);
181cb0ef41Sopenharmony_ci  }
191cb0ef41Sopenharmony_ci  return pos;
201cb0ef41Sopenharmony_ci}
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ciexport class ViewElements {
231cb0ef41Sopenharmony_ci  container: HTMLElement;
241cb0ef41Sopenharmony_ci  scrollTop: number;
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  constructor(container: HTMLElement) {
271cb0ef41Sopenharmony_ci    this.container = container;
281cb0ef41Sopenharmony_ci    this.scrollTop = undefined;
291cb0ef41Sopenharmony_ci  }
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci  consider(element, doConsider) {
321cb0ef41Sopenharmony_ci    if (!doConsider) return;
331cb0ef41Sopenharmony_ci    const newScrollTop = computeScrollTop(this.container, element);
341cb0ef41Sopenharmony_ci    if (isNaN(newScrollTop)) {
351cb0ef41Sopenharmony_ci      console.log("NOO");
361cb0ef41Sopenharmony_ci    }
371cb0ef41Sopenharmony_ci    if (this.scrollTop === undefined) {
381cb0ef41Sopenharmony_ci      this.scrollTop = newScrollTop;
391cb0ef41Sopenharmony_ci    } else {
401cb0ef41Sopenharmony_ci      this.scrollTop = Math.min(this.scrollTop, newScrollTop);
411cb0ef41Sopenharmony_ci    }
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  apply(doApply) {
451cb0ef41Sopenharmony_ci    if (!doApply || this.scrollTop === undefined) return;
461cb0ef41Sopenharmony_ci    this.container.scrollTop = this.scrollTop;
471cb0ef41Sopenharmony_ci  }
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ciexport function sortUnique<T>(arr: Array<T>, f: (a: T, b: T) => number, equal: (a: T, b: T) => boolean) {
511cb0ef41Sopenharmony_ci  if (arr.length == 0) return arr;
521cb0ef41Sopenharmony_ci  arr = arr.sort(f);
531cb0ef41Sopenharmony_ci  const ret = [arr[0]];
541cb0ef41Sopenharmony_ci  for (let i = 1; i < arr.length; i++) {
551cb0ef41Sopenharmony_ci    if (!equal(arr[i - 1], arr[i])) {
561cb0ef41Sopenharmony_ci      ret.push(arr[i]);
571cb0ef41Sopenharmony_ci    }
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci  return ret;
601cb0ef41Sopenharmony_ci}
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci// Partial application without binding the receiver
631cb0ef41Sopenharmony_ciexport function partial(f: any, ...arguments1: Array<any>) {
641cb0ef41Sopenharmony_ci  return function (this: any, ...arguments2: Array<any>) {
651cb0ef41Sopenharmony_ci    f.apply(this, [...arguments1, ...arguments2]);
661cb0ef41Sopenharmony_ci  };
671cb0ef41Sopenharmony_ci}
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ciexport function isIterable(obj: any): obj is Iterable<any> {
701cb0ef41Sopenharmony_ci  return obj != null && obj != undefined
711cb0ef41Sopenharmony_ci    && typeof obj != 'string' && typeof obj[Symbol.iterator] === 'function';
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ciexport function alignUp(raw: number, multiple: number): number {
751cb0ef41Sopenharmony_ci  return Math.floor((raw + multiple - 1) / multiple) * multiple;
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ciexport function measureText(text: string) {
791cb0ef41Sopenharmony_ci  const textMeasure = document.getElementById('text-measure');
801cb0ef41Sopenharmony_ci  if (textMeasure instanceof SVGTSpanElement) {
811cb0ef41Sopenharmony_ci    textMeasure.textContent = text;
821cb0ef41Sopenharmony_ci    return {
831cb0ef41Sopenharmony_ci      width: textMeasure.getBBox().width,
841cb0ef41Sopenharmony_ci      height: textMeasure.getBBox().height,
851cb0ef41Sopenharmony_ci    };
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci  return { width: 0, height: 0 };
881cb0ef41Sopenharmony_ci}
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci// Interpolate between the given start and end values by a fraction of val/max.
911cb0ef41Sopenharmony_ciexport function interpolate(val: number, max: number, start: number, end: number) {
921cb0ef41Sopenharmony_ci  return start + (end - start) * (val / max);
931cb0ef41Sopenharmony_ci}
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ciexport function createElement(tag: string, cls: string, content?: string) {
961cb0ef41Sopenharmony_ci  const el = document.createElement(tag);
971cb0ef41Sopenharmony_ci  el.className = cls;
981cb0ef41Sopenharmony_ci  if (content != undefined) el.innerText = content;
991cb0ef41Sopenharmony_ci  return el;
1001cb0ef41Sopenharmony_ci}
101