当前位置: 首页>>代码示例>>TypeScript>>正文


TypeScript Throttler.last方法代码示例

本文整理汇总了TypeScript中@ephox/katamari.Throttler.last方法的典型用法代码示例。如果您正苦于以下问题:TypeScript Throttler.last方法的具体用法?TypeScript Throttler.last怎么用?TypeScript Throttler.last使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在@ephox/katamari.Throttler的用法示例。


在下文中一共展示了Throttler.last方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的TypeScript代码示例。

示例1: function

const register = function (toolstrip, socket, container, outerWindow, structure, cWin) {
  const scroller = BackgroundActivity(function (y) {
    return IosScrolling.moveWindowScroll(toolstrip, socket, y);
  });

  // NOTE: This is a WebView specific way of scrolling when out of bounds. When we need to make
  // the webapp work again, we'll have to adjust this function. Essentially, it just jumps the scroll
  // back to show the current selection rectangle.
  const scrollBounds = function () {
    const rects = Rectangles.getRectangles(cWin);
    return Option.from(rects[0]).bind(function (rect) {
      const viewTop = rect.top() - socket.dom().scrollTop;
      const outside = viewTop > outerWindow.innerHeight + VIEW_MARGIN || viewTop < -VIEW_MARGIN;
      return outside ? Option.some({
        top: Fun.constant(viewTop),
        bottom: Fun.constant(viewTop + rect.height())
      }) : Option.none();
    });
  };

  const scrollThrottle = Throttler.last(function () {
    /*
     * As soon as the window is back to 0 (idle), scroll the toolbar and socket back into place on scroll.
     */
    scroller.idle(function () {
      IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(function (/* _ */) {
        const extraScroll = scrollBounds();
        extraScroll.each(function (extra) {
          // TODO: Smoothly animate this in a way that doesn't conflict with anything else.
          socket.dom().scrollTop = socket.dom().scrollTop + extra.top();
        });
        scroller.start(0);
        structure.refresh();
      });
    });
  }, 1000);

  const onScroll = DomEvent.bind(Element.fromDom(outerWindow), 'scroll', function () {
    if (outerWindow.pageYOffset < 0) {
      return;
    }

    /*
    We've experimented with trying to set the socket scroll (hidden vs. scroll) based on whether the outer body
    has scrolled. When the window starts scrolling, we would lock the socket scroll, and we would
    unlock it when the window stopped scrolling. This would give a nice rubber-band effect at the end
    of the content, but would break the code that tried to position the text in the viewable area
    (more details below). Also, as soon as you flicked to outer scroll, if you started scrolling up again,
    you would drag the whole window down, because you would still be in outerscroll mode. That's hardly
    much of a problem, but it is a minor issue. It also didn't play nicely with keeping the toolbar on the screen.

    The big problem was that this was incompatible with the toolbar and scrolling code. We need a padding inside
    the socket so that the bottom of the content can be scrolled into the viewable greenzone. If it doesn't
    have padding, then unless we move the socket top to some negative value as well, then we can't get
    a scrollTop high enough to get the selection into the viewable greenzone. This is the purpose of the
    padding at the bottom of the iframe. Without it, the scroll consistently jumps back to its
    max scroll value, and you can't keep the last line on screen when the keyboard is up.

    However, if the padding is too large, then the content can be 'effectively' scrolled off the screen
    (the iframe anyway), and the user can get lost about where they are. Our short-term fix is just to
    make the padding at the end the height - the greenzone height so that content should always be
    visible on the screen, even if they've scrolled to the end.
    */

    scrollThrottle.throttle();
  });

  IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(Fun.identity);

  return {
    unbind: onScroll.unbind
  };
};
开发者ID:abstask,项目名称:tinymce,代码行数:73,代码来源:IosSetup.ts

示例2: function

const open = function (editor: Editor, charMap: CharMap[]) {
  const makeGroupItems = (): Types.Dialog.BodyComponentApi[] => [
    {
      label: 'Search',
      type: 'input',
      name: patternName
    },
    {
      type: 'collection',
      name: 'results',
      // TODO TINY-3229 implement collection columns properly
      // columns: 'auto'
    }
  ];

  const makeTabs = () => {
    return Arr.map(charMap, (charGroup) => {
      return {
        title: charGroup.name,
        items: makeGroupItems()
      };
    });
  };

  const currentTab = charMap.length === 1 ? Cell(UserDefined) : Cell('All');

  const makePanel = (): Types.Dialog.PanelApi => ({ type: 'panel', items: makeGroupItems() });

  const makeTabPanel = (): Types.Dialog.TabPanelApi => ({ type: 'tabpanel', tabs: makeTabs() });

  const scanAndSet = (dialogApi: Types.Dialog.DialogInstanceApi<typeof initialData>, pattern: string) => {
    Arr.find(charMap, (group) => group.name === currentTab.get()).each((f) => {
      const items = Scan.scan(f, pattern);
      dialogApi.setData({
        results: items
      });
    });
  };

  const SEARCH_DELAY = 40;

  const updateFilter = Throttler.last((dialogApi: Types.Dialog.DialogInstanceApi<typeof initialData>) => {
    const pattern = dialogApi.getData().pattern;
    scanAndSet(dialogApi, pattern);
  }, SEARCH_DELAY);

  const body = charMap.length === 1 ? makePanel() : makeTabPanel();

  const initialData = {
    pattern: '',
    results: Scan.scan(charMap[0], '')
  };

  const bridgeSpec: Types.Dialog.DialogApi<typeof initialData> = {
    title: 'Special Character',
    size: 'normal',
    body,
    buttons: [
      {
        type: 'cancel',
        name: 'close',
        text: 'Close',
        primary: true
      }
    ],
    initialData,
    onAction(api, details) {
      if (details.name === 'results') {
        Actions.insertChar(editor, details.value);
        api.close();
      }
    },

    onTabChange: (dialogApi, title: string) => {
      currentTab.set(title);
      updateFilter.throttle(dialogApi);
    },

    onChange: (dialogApi, changeData) => {
      if (changeData.name === patternName) {
        updateFilter.throttle(dialogApi);
      }
    }
  };
  editor.windowManager.open(bridgeSpec);
};
开发者ID:tinymce,项目名称:tinymce,代码行数:86,代码来源:Dialog.ts

示例3: Cell

const setup = (editor: Editor, registry: AnnotationsRegistry): AnnotationChanges => {
  const changeCallbacks = Cell<AnnotationListenerMap>({ });

  const initData = (): AnnotationListenerData => ({
    listeners: [ ],
    previous: Cell(Option.none())
  });

  const withCallbacks = (name: string, f: (listeners: AnnotationListenerData) => void) => {
    updateCallbacks(name, (data) => {
      f(data);
      return data;
    });
  };

  const updateCallbacks = (name: string, f: (inputData: AnnotationListenerData) => AnnotationListenerData) => {
    const callbackMap = changeCallbacks.get();
    const data = callbackMap.hasOwnProperty(name) ? callbackMap[name] : initData();
    const outputData = f(data);
    callbackMap[name] = outputData;
    changeCallbacks.set(callbackMap);
  };

  const fireCallbacks = (name: string, uid: string, elements: any[]): void => {
    withCallbacks(name, (data) => {
      Arr.each(data.listeners, (f) => f(true, name, {
        uid,
        nodes: Arr.map(elements, (elem) => elem.dom())
      }));
    });
  };

  const fireNoAnnotation = (name: string): void => {
    withCallbacks(name, (data) => {
      Arr.each(data.listeners, (f) => f(false, name));
    });
  };

  // NOTE: Runs in alphabetical order.
  const onNodeChange = Throttler.last(() => {
    const callbackMap = changeCallbacks.get();
    const annotations = Arr.sort(Obj.keys(callbackMap));
    Arr.each(annotations, (name) => {
      updateCallbacks(name, (data) => {
        const prev = data.previous.get();
        identify(editor, Option.some(name)).fold(
          () => {
            if (prev.isSome()) {
              // Changed from something to nothing.
              fireNoAnnotation(name);
              data.previous.set(Option.none());
            }
          },
          ({ uid, name, elements }) => {
            // Changed from a different annotation (or nothing)
            if (! prev.is(uid)) {
              fireCallbacks(name, uid, elements);
              data.previous.set(Option.some(uid));
            }
          }
        );

        return {
          previous: data.previous,
          listeners: data.listeners
        };
      });
    });
  }, 30);

  editor.on('remove', () => {
    onNodeChange.cancel();
  });

  editor.on('NodeChange', () => {
    onNodeChange.throttle();
  });

  const addListener = (name: string, f: AnnotationListener): void => {
    updateCallbacks(name, (data) => {
      return {
        previous: data.previous,
        listeners: data.listeners.concat([ f ])
      };
    });
  };

  return {
    addListener
  };
};
开发者ID:tinymce,项目名称:tinymce,代码行数:91,代码来源:AnnotationChanges.ts

示例4: function

const initEvents = function (editorApi, iosApi, toolstrip, socket, dropup) {
  const saveSelectionFirst = function () {
    iosApi.run(function (api) {
      api.highlightSelection();
    });
  };

  const refreshIosSelection = function () {
    iosApi.run(function (api) {
      api.refreshSelection();
    });
  };

  const scrollToY = function (yTop, height) {
    // Because the iframe has no scroll, and the socket is the part that scrolls,
    // anything visible inside the iframe actually has a top value (for bounding
    // rectangle) > socket.scrollTop. The rectangle is with respect to the top of
    // the iframe, which has scrolled up above the socket viewport.
    const y = yTop - socket.dom().scrollTop;
    iosApi.run(function (api) {
      api.scrollIntoView(y, y + height);
    });
  };

  const scrollToElement = function (target) {
    scrollToY(iosApi, socket);
  };

  const scrollToCursor = function () {
    editorApi.getCursorBox().each(function (box) {
      scrollToY(box.top(), box.height());
    });
  };

  const clearSelection = function () {
    // Clear any fake selections visible.
    iosApi.run(function (api) {
      api.clearSelection();
    });
  };

  const clearAndRefresh = function () {
    clearSelection();
    refreshThrottle.throttle();
  };

  const refreshView = function () {
    scrollToCursor();
    iosApi.run(function (api) {
      api.syncHeight();
    });
  };

  const reposition = function () {
    const toolbarHeight = Height.get(toolstrip);
    iosApi.run(function (api) {
      api.setViewportOffset(toolbarHeight);
    });

    refreshIosSelection();
    refreshView();
  };

  const toEditing = function () {
    iosApi.run(function (api) {
      api.toEditing();
    });
  };

  const toReading = function () {
    iosApi.run(function (api) {
      api.toReading();
    });
  };

  const onToolbarTouch = function (event) {
    iosApi.run(function (api) {
      api.onToolbarTouch(event);
    });
  };

  const tapping = TappingEvent.monitor(editorApi);

  const refreshThrottle = Throttler.last(refreshView, 300);
  const listeners = [
    // Clear any fake selections, scroll to cursor, and update the iframe height
    editorApi.onKeyup(clearAndRefresh),
    // Update any fake selections that are showing
    editorApi.onNodeChanged(refreshIosSelection),

    // Scroll to cursor, and update the iframe height
    editorApi.onDomChanged(refreshThrottle.throttle),
    // Update any fake selections that are showing
    editorApi.onDomChanged(refreshIosSelection),

    // Scroll to cursor and update the iframe height
    editorApi.onScrollToCursor(function (tinyEvent) {
      tinyEvent.preventDefault();
      refreshThrottle.throttle();
    }),
//.........这里部分代码省略.........
开发者ID:aha-app,项目名称:tinymce-word-paste-filter,代码行数:101,代码来源:IosEvents.ts

示例5: function

const open = function (editor: Editor, database: EmojiDatabase) {

  const initialState = {
    pattern: '',
    results: emojisFrom(database.listAll(), '', Option.some(300))
  };

  const scan = (dialogApi, category: string) => {
    const dialogData = dialogApi.getData();
    const candidates = database.listCategory(category);
    const results = emojisFrom(candidates, dialogData[patternName], category === ALL_CATEGORY ? Option.some(300) : Option.none());
    dialogApi.setData({
      results
    });
  };

  const updateFilter = Throttler.last((dialogApi) => {
    const category = currentTab.get();
    scan(dialogApi, category);
  }, 200);

  const currentTab = Cell(ALL_CATEGORY);

  const searchField: Types.Dialog.BodyComponentApi = {
    label: 'Search',
    type: 'input',
    name: patternName
  };

  const resultsField: Types.Dialog.BodyComponentApi = {
    type: 'collection',
    name: 'results',
    // TODO TINY-3229 implement collection columns properly
    // columns: 'auto'
  };

  const getInitialState = (): Types.Dialog.DialogApi<typeof initialState> => {
    const body: Types.Dialog.TabPanelApi = {
      type: 'tabpanel',
      // All tabs have the same fields.
      tabs: Arr.map(database.listCategories(), (cat) => ({
        title: cat,
        items: [searchField, resultsField]
      }))
    };
    return {
      title: 'Emoticons',
      size: 'normal',
      body,
      initialData: initialState,
      onTabChange: (dialogApi, title: string) => {
        currentTab.set(title);
        updateFilter.throttle(dialogApi);
      },
      onChange: updateFilter.throttle,
      onAction: (dialogApi, actionData) => {
        if (actionData.name === 'results') {
          insertEmoticon(editor, actionData.value);
          dialogApi.close();
        }
      },
      buttons: [
        {
          type: 'cancel',
          text: 'Close',
          primary: true
        }
      ]
    };
  };

  const dialogApi = editor.windowManager.open(getInitialState());

  dialogApi.focus(patternName);

  if (!database.hasLoaded()) {
    dialogApi.block('Loading emoticons...');
    database.waitForLoad().then(() => {
      dialogApi.redial(getInitialState());
      updateFilter.throttle(dialogApi);
      dialogApi.focus(patternName);
      dialogApi.unblock();
    }).catch((err) => {
      dialogApi.redial({
        title: 'Emoticons',
        body: {
          type: 'panel',
          items: [
            {
              type: 'alertbanner',
              level: 'error',
              icon: 'warning',
              text: '<p>Could not load emoticons</p>'
            }
          ]
        },
        buttons: [
          {
            type: 'cancel',
            text: 'Close',
//.........这里部分代码省略.........
开发者ID:tinymce,项目名称:tinymce,代码行数:101,代码来源:Dialog.ts

示例6: createAutocompleteItems

const register = (editor: Editor, sharedBackstage: UiFactoryBackstageShared) => {
  const autocompleter = GuiFactory.build(
    InlineView.sketch({
      dom: {
        tag: 'div',
        classes: [ 'tox-autocompleter' ]
      },
      components: [

      ],
      lazySink: sharedBackstage.getSink
    })
  );

  const isActive = () => InlineView.isOpen(autocompleter);
  const closeIfNecessary = () => {
    if (isActive()) {
      InlineView.hide(autocompleter);
    }
  };

  // This needs to be calcluated once things are ready, but the key events must be bound
  // before `init` or other keydown / keypress listeners will fire first. Therefore,
  // this is a thunk so that its value is calculated just once when it is used for the
  // first time, and after that it's value is stored.
  const getAutocompleters: () => Autocompleters.AutocompleterDatabase = Thunk.cached(() => {
    return Autocompleters.register(editor);
  });

  const getCombinedItems = (triggerChar: string, matches: AutocompleteLookupData[]): ItemTypes.ItemSpec[] => {
    const columns = Options.findMap(matches, (m) => Option.from(m.columns)).getOr(1);

    return Arr.bind(matches, (match) => {
      const choices = match.items;

      return createAutocompleteItems(
        choices,
        (itemValue, itemMeta) => {
          const nr = editor.selection.getRng();
          const textNode = nr.startContainer as Text; // TODO: Investigate if this is safe
          getContext(nr, triggerChar, textNode.data, nr.startOffset).fold(
            () => console.error('Lost context. Cursor probably moved'),
            ({ rng }) => {
              const autocompleterApi: InlineContent.AutocompleterInstanceApi = {
                hide: closeIfNecessary
              };
              match.onAction(autocompleterApi, rng, itemValue, itemMeta);
            }
          );
        },
        columns,
        ItemResponse.BUBBLE_TO_SANDBOX,
        sharedBackstage
      );
    });
  };

  const onKeypress = Throttler.last((e) => {
    const optMatches = e.key === ' ' ? Option.none<{ range: Range, triggerChar: string, lookupData: Promise<AutocompleteLookupData[]> }>() : lookup(editor, getAutocompleters);
    optMatches.fold(
      closeIfNecessary,
      (lookupInfo) => {
        lookupInfo.lookupData.then((lookupData) => {
          const combinedItems = getCombinedItems(lookupInfo.triggerChar, lookupData);

          // Only open the autocompleter if there are items to show
          if (combinedItems.length > 0) {
            const columns: Types.ColumnTypes = Options.findMap(lookupData, (ld) => Option.from(ld.columns)).getOr(1);
            InlineView.showAt(
              autocompleter,
              {
                anchor: 'selection',
                root: Element.fromDom(editor.getBody()),
                getSelection: () => {
                  return Option.some({
                    start: () => Element.fromDom(lookupInfo.range.startContainer),
                    soffset: () => lookupInfo.range.startOffset,
                    finish: () => Element.fromDom(lookupInfo.range.endContainer),
                    foffset: () => lookupInfo.range.endOffset
                  });
                }
              },
              Menu.sketch(
                createMenuFrom(
                  createPartialMenuWithAlloyItems('autocompleter-value', true, combinedItems, columns, 'normal'),
                  columns,
                  FocusMode.ContentFocus,
                  // Use the constant.
                  'normal'
                )
              )
            );

            InlineView.getContent(autocompleter).each(Highlighting.highlightFirst);
          } else {
            closeIfNecessary();
          }
        });
      }
    );
//.........这里部分代码省略.........
开发者ID:tinymce,项目名称:tinymce,代码行数:101,代码来源:Autocompleter.ts


注:本文中的@ephox/katamari.Throttler.last方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。