Ejemplo n.º 1
0
  return function (editor, shiftKey) {
    const isMatch = Arr.foldl(predicates, function (res, p) {
      return res && p(editor, shiftKey);
    }, true);

    return isMatch ? Option.some(action) : Option.none();
  };
Ejemplo n.º 2
0
const generateContextMenu = (contextMenus: Record<string, Menu.ContextMenuApi>, menuConfig: string[], selectedElement: Element) => {
  const items = Arr.foldl(menuConfig, (acc, name) => {
    // Either read and convert the list of items out of the plugin, or assume it's a standard menu item reference
    if (Obj.has(contextMenus, name)) {
      const items = contextMenus[name].update(selectedElement);
      if (Type.isString(items)) {
        return addContextMenuGroup(acc, items.split(' '));
      } else if (items.length > 0) {
        // TODO: Should we add a ValueSchema check here?
        const allItems = Arr.map(items, makeContextItem);
        return addContextMenuGroup(acc, allItems);
      } else {
        return acc;
      }
    } else {
      return acc.concat([name]);
    }
  }, []);

  // Strip off any trailing separator
  if (items.length > 0 && isSeparator(items[items.length - 1])) {
    items.pop();
  }

  return items;
};
Ejemplo n.º 3
0
const unwrapReferences = (items: Array<string | SingleMenuItemApi>, menuItems: MenuItemRegistry): SingleMenuItemApi[] => {
  // Unwrap any string based menu item references
  const realItems = Arr.foldl(items, (acc, item) => {
    if (isMenuItemReference(item)) {
      if (item === '') {
        return acc;
      } else if (item === '|') {
        // Ignore the separator if it's at the start or a duplicate
        return acc.length > 0 && !isSeparator(acc[acc.length - 1]) ? acc.concat([separator]) : acc;
      } else if (Obj.has(menuItems, item.toLowerCase())) {
        return acc.concat([ menuItems[item.toLowerCase()] ]);
      } else {
        // TODO: Add back after TINY-3232 is implemented
        // console.error('No representation for menuItem: ' + item);
        return acc;
      }
    } else {
      return acc.concat([ item ]);
    }
  }, []);

  // Remove any trailing separators
  if (realItems.length > 0 && isSeparator(realItems[realItems.length - 1])) {
    realItems.pop();
  }

  return realItems;
};
Ejemplo n.º 4
0
const composeList = (scope: Document, entries: Entry[]): Option<Element> => {
  const cast: Segment[] = Arr.foldl(entries, (cast, entry) => {
    return entry.depth > cast.length ? writeDeep(scope, cast, entry) : writeShallow(scope, cast, entry);
  }, []);

  return Arr.head(cast).map((segment) => segment.list);
};
Ejemplo n.º 5
0
const wrap = function (innerElm, elms) {
  const wrapped = Arr.foldl(elms, function (acc, elm) {
    Insert.append(elm, acc);
    return elm;
  }, innerElm);
  return elms.length > 0 ? Fragment.fromElements([wrapped]) : wrapped;
};
Ejemplo n.º 6
0
const isXYWithinRange = function (clientX, clientY, range) {
  if (range.collapsed) {
    return false;
  }

  return Arr.foldl(range.getClientRects(), function (state, rect) {
    return state || containsXY(rect, clientX, clientY);
  }, false);
};
Ejemplo n.º 7
0
const isAtomicContentEditableFalse = (node: Node): boolean => {
  if (!isNonUiContentEditableFalse(node)) {
    return false;
  }

  return Arr.foldl(Arr.from(node.getElementsByTagName('*')), function (result, elm) {
    return result || isContentEditableTrue(elm);
  }, false) !== true;
};
Ejemplo n.º 8
0
const getLinkAttrs = (data: LinkDialogOutput): Record<string, string> => {
  return Arr.foldl([ 'title', 'rel', 'class', 'target' ], (acc, key) => {
    data[key].each((value) => {
      // If dealing with an empty string, then treat that as being null so the attribute is removed
      acc[key] = value.length > 0 ? value : null;
    });
    return acc;
  }, {
    href: data.href
  });
};
Ejemplo n.º 9
0
const findClosestCorner = (corners: Corner[], x: number, y: number): Option<Corner> => {
  return Arr.foldl(corners, (acc, newCorner) => {
    return acc.fold(
      () => Option.some(newCorner),
      (oldCorner) => {
        const oldDist = Math.sqrt(Math.abs(oldCorner.x - x) + Math.abs(oldCorner.y - y));
        const newDist = Math.sqrt(Math.abs(newCorner.x - x) + Math.abs(newCorner.y - y));
        return Option.some(newDist < oldDist ? newCorner : oldCorner);
      }
    );
  }, Option.none());
};
Ejemplo n.º 10
0
const resolvePath = (root: Node, path: number[]): Option<{node: Text, offset: number}> => {
  const nodePath = path.slice();
  const offset = nodePath.pop();
  return Arr.foldl(nodePath, (optNode: Option<Node>, index: number) => {
    return optNode.bind((node) => Option.from(node.childNodes[index]));
  }, Option.some(root)).bind((node) => {
    if (isText(node) && offset >= 0 && offset <= node.data.length) {
      return Option.some({node, offset});
    }
    return Option.none();
  });
};