Example #1
0
const createPatternSet = (patterns: Pattern[]): PatternSet => {
  return {
    inlinePatterns: sortPatterns(Arr.filter(patterns, isInlinePattern)),
    blockPatterns: sortPatterns(Arr.filter(patterns, isBlockPattern)),
    replacementPatterns: Arr.filter(patterns, isReplacementPattern),
  };
};
Example #2
0
const getMultipleToolbarsSetting = (editor: Editor) => {
  const keys = Obj.keys(editor.settings);
  const toolbarKeys = Arr.filter(keys, (key) => /^toolbar([1-9])$/.test(key));
  const toolbars = Arr.map(toolbarKeys, (key) => editor.getParam(key, false, 'string'));
  const toolbarArray = Arr.filter(toolbars, (toolbar) => typeof toolbar === 'string');
  return toolbarArray.length > 0 ? Option.some(toolbarArray) : Option.none();
};
const trimMenuItems = function (menuItems) {
  const menuItems2 = Arr.filter(menuItems, function (menuItem, i, menuItems) {
    return !isSeparator(menuItem) || !isSeparator(menuItems[i - 1]);
  });

  return Arr.filter(menuItems2, function (menuItem, i, menuItems) {
    return !isSeparator(menuItem) || i > 0 && i < menuItems.length - 1;
  });
};
Example #4
0
const cleanupMenu = function (namedMenuItems, removedMenuItems) {
  const menuItemsPass1 = Arr.filter(namedMenuItems, function (namedMenuItem) {
    return removedMenuItems.hasOwnProperty(namedMenuItem.name) === false;
  });

  const menuItemsPass2 = Arr.filter(menuItemsPass1, function (namedMenuItem, i, namedMenuItems) {
    return !isSeparator(namedMenuItem) || !isSeparator(namedMenuItems[i - 1]);
  });

  return Arr.filter(menuItemsPass2, function (namedMenuItem, i, namedMenuItems) {
    return !isSeparator(namedMenuItem) || i > 0 && i < namedMenuItems.length - 1;
  });
};
Example #5
0
const moveToCeFalseVertically = function (direction: LineWalker.VDirection, editor, walkerFn, range: Range) {
  let caretPosition, linePositions, nextLinePositions;
  let closestNextLineRect, caretClientRect, clientX;
  let dist1, dist2, contentEditableFalseNode;

  contentEditableFalseNode = getSelectedNode(range);
  caretPosition = CaretUtils.getNormalizedRangeEndPoint(direction, editor.getBody(), range);
  linePositions = walkerFn(editor.getBody(), LineWalker.isAboveLine(1), caretPosition);
  nextLinePositions = Arr.filter(linePositions, LineWalker.isLine(1));
  caretClientRect = ArrUtils.last(caretPosition.getClientRects());

  if (isBeforeContentEditableFalse(caretPosition) || CaretUtils.isBeforeTable(caretPosition)) {
    contentEditableFalseNode = caretPosition.getNode();
  }

  if (isAfterContentEditableFalse(caretPosition) || CaretUtils.isAfterTable(caretPosition)) {
    contentEditableFalseNode = caretPosition.getNode(true);
  }

  if (!caretClientRect) {
    return null;
  }

  clientX = caretClientRect.left;

  closestNextLineRect = LineUtils.findClosestClientRect(nextLinePositions, clientX);
  if (closestNextLineRect) {
    if (isContentEditableFalse(closestNextLineRect.node)) {
      dist1 = Math.abs(clientX - closestNextLineRect.left);
      dist2 = Math.abs(clientX - closestNextLineRect.right);

      return CefUtils.showCaret(direction, editor, closestNextLineRect.node, dist1 < dist2, true);
    }
  }

  if (contentEditableFalseNode) {
    const caretPositions = LineWalker.positionsUntil(direction, editor.getBody(), LineWalker.isAboveLine(1), contentEditableFalseNode);

    closestNextLineRect = LineUtils.findClosestClientRect(Arr.filter(caretPositions, LineWalker.isLine(1)), clientX);
    if (closestNextLineRect) {
      return CefUtils.renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);
    }

    closestNextLineRect = ArrUtils.last(Arr.filter(caretPositions, LineWalker.isLine(0)));
    if (closestNextLineRect) {
      return CefUtils.renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);
    }
  }
};
const removeTrailingBr = function (elm) {
  const allBrs = SelectorFilter.descendants(elm, 'br');
  const brs = Arr.filter(getLastChildren(elm).slice(-1), ElementType.isBr);
  if (allBrs.length === brs.length) {
    Arr.each(brs, Remove.remove);
  }
};
Example #7
0
const normalizePlugins = function (plugins) {
  const pluginNames = Type.isArray(plugins) ? plugins.join(' ') : plugins;
  const trimmedPlugins = Arr.map(Type.isString(pluginNames) ? pluginNames.split(' ') : [ ], Strings.trim);
  return Arr.filter(trimmedPlugins, function (item) {
    return item.length > 0;
  });
};
Example #8
0
  const fromMenuItems = function (type) {
    const filteredTargets = Arr.filter(targets, function (target) {
      return target.type === type;
    });

    return toMenuItems(filteredTargets);
  };
Example #9
0
const getClosestCell = (getYAxisValue: GetAxisValue, isTargetCorner: IsTargetCorner, table: HTMLElement, x: number, y: number): Option<HTMLElement> => {
  const cells = SelectorFilter.descendants(Element.fromDom(table), 'td,th').map((e) => e.dom());
  const corners = Arr.filter(getCorners(getYAxisValue, cells), (corner) => isTargetCorner(corner, y));

  return findClosestCorner(corners, x, y).map((corner) => {
    return corner.cell;
  });
};
Example #10
0
  Arr.each(formats.split(','), (format) => {
    formatChangeItems[format].callbacks = Arr.filter(formatChangeItems[format].callbacks, (c) => {
      return c !== callback;
    });

    if (formatChangeItems[format].callbacks.length === 0) {
      delete formatChangeItems[format];
    }
  });
Example #11
0
 const filteredItemGroups = Arr.map(defaultToolbar, (group) => {
   const items = Arr.filter(group.items, (subItem) => {
     return Obj.has(buttons, subItem) || Obj.has(bespokeButtons as any, subItem);
   });
   return {
     name: group.name,
     items
   };
 });
Example #12
0
 return new Promise((resolve) => {
   const filteredItems = Arr.filter([ 'two', 'three' ], (number) => number.indexOf(pattern) !== -1);
   resolve(
     Arr.map(filteredItems, (number) => ({
       value: `${number}`,
       text: `${number}`,
       icon: '='
     }))
   );
 });
Example #13
0
  const removeByUri = function (blobUri: string) {
    cache = Arr.filter(cache, function (blobInfo) {
      if (blobInfo.blobUri() === blobUri) {
        URL.revokeObjectURL(blobInfo.blobUri());
        return false;
      }

      return true;
    });
  };
Example #14
0
const addToHistory = function (url: string, fileType: string) {
  if (!isHttpUrl(url)) {
    return;
  }
  const history = getAllHistory();
  const items = Object.prototype.hasOwnProperty.call(history, fileType) ? history[fileType] : [];
  const itemsWithoutUrl = Arr.filter(items, (item) => item !== url);
  history[fileType] = [url].concat(itemsWithoutUrl).slice(0, HISTORY_LENGTH);
  setAllHistory(history);
};
Example #15
0
const getWrapElements = function (rootNode, rng) {
  const commonAnchorContainer = Element.fromDom(rng.commonAncestorContainer);
  const parents = Parents.parentsAndSelf(commonAnchorContainer, rootNode);
  const wrapElements = Arr.filter(parents, function (elm) {
    return ElementType.isInline(elm) || ElementType.isHeading(elm);
  });
  const listWrappers = getFullySelectedListWrappers(parents, rng);
  const allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer));
  return Arr.map(allWrappers, Replication.shallow);
};
Example #16
0
 const closeDialog = function <T>(dialog: InstanceApi<T>) {
   fireCloseEvent(dialog);
   dialogs = Arr.filter(dialogs, function (otherDialog) {
     return otherDialog !== dialog;
   });
   // Move focus back to editor when the last window is closed
   if (dialogs.length === 0) {
     editor.focus();
   }
 };
Example #17
0
const deleteFromCallbackMap = (callbackMap, selector, callback) => {
  if (callbackMap && callbackMap.hasOwnProperty(selector)) {
    const newCallbacks = Arr.filter(callbackMap[selector], (cb) => cb !== callback);

    if (newCallbacks.length === 0) {
      delete callbackMap[selector];
    } else {
      callbackMap[selector] = newCallbacks;
    }
  }
};
Example #18
0
  const collect = (checkPosFn, node) => {
    let lineRects;

    lineRects = Arr.filter(getClientRects([node]), function (clientRect) {
      return !checkPosFn(clientRect, targetNodeRect);
    });

    clientRects = clientRects.concat(lineRects);

    return lineRects.length === 0;
  };
const renderInsideInlineCaret = function (isInlineTarget, editor, caret, elms) {
  if (editor.selection.isCollapsed()) {
    const inlines = Arr.filter(elms, isInlineTarget);
    Arr.each(inlines, function (inline) {
      const pos = CaretPosition.fromRangeStart(editor.selection.getRng());
      BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), pos).bind(function (location) {
        return renderCaretLocation(editor, caret, location);
      });
    });
  }
};
Example #20
0
const removeUnusedDefaults = (buttons) => {
  const filteredItemGroups = Arr.map(defaultToolbar, (group) => {
    const items = Arr.filter(group.items, (subItem) => {
      return Obj.has(buttons, subItem) || Obj.has(bespokeButtons as any, subItem);
    });
    return {
      name: group.name,
      items
    };
  });
  return Arr.filter(filteredItemGroups, (group) => group.items.length > 0);
};
Example #21
0
const deleteLastPosition = function (forward, editor, target, parentInlines) {
  const isFormatElement = Fun.curry(CaretFormat.isFormatElement, editor);
  const formatNodes = Arr.map(Arr.filter(parentInlines, isFormatElement), function (elm) {
    return elm.dom();
  });

  if (formatNodes.length === 0) {
    DeleteElement.deleteElement(editor, forward, target);
  } else {
    const pos = CaretFormat.replaceWithCaretFormat(target.dom(), formatNodes);
    editor.selection.setRng(pos.toRange());
  }
};
Example #22
0
const isAtBlockBoundary = (forward: boolean, root: Element, pos: CaretPosition) => {
  const parentBlocks = Arr.filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), ElementType.isBlock);
  return Arr.head(parentBlocks).fold(
    () => {
      return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall((newPos) => {
        return isInSameBlock(newPos, pos, root.dom()) === false;
      });
    },
    (parent) => {
      return navigateIgnoreEmptyTextNodes(forward, parent.dom(), pos).isNone();
    }
  );
};
Example #23
0
const identifyMenus = (editor: Editor, registry: MenuRegistry): MenubarItemSpec[] => {
  const rawMenuData = Merger.merge(defaultMenus, registry.menus);
  const userDefinedMenus = Obj.keys(registry.menus).length > 0;

  const menubar: string[] = registry.menubar === undefined || registry.menubar === true ? parseItemsString(defaultMenubar) : parseItemsString(registry.menubar === false ? '' : registry.menubar);
  const validMenus = Arr.filter(menubar, (menuName) => {

    return userDefinedMenus ? ((registry.menus.hasOwnProperty(menuName) && registry.menus[menuName].hasOwnProperty('items')
      || defaultMenus.hasOwnProperty(menuName)))
      : defaultMenus.hasOwnProperty(menuName);
  });

  const menus: MenubarItemSpec[] = Arr.map(validMenus, (menuName) => {
    const menuData = rawMenuData[menuName];
    return make({ title: menuData.title, items: parseItemsString(menuData.items) }, registry, editor);
  });

  return Arr.filter(menus, (menu) => {
    // Filter out menus that have no items, or only separators
    const isNotSeparator = (item) => item.type !== 'separator';
    return menu.getItems().length > 0 && Arr.exists(menu.getItems(), isNotSeparator);
  });
};
Example #24
0
const deleteCaret = function (editor, forward) {
  const rootElm = Element.fromDom(editor.getBody());
  const startElm = Element.fromDom(editor.selection.getStart());
  const parentInlines = Arr.filter(getParentInlines(rootElm, startElm), hasOnlyOneChild);

  return Arr.last(parentInlines).map(function (target) {
    const fromPos = CaretPosition.fromRangeStart(editor.selection.getRng());
    if (DeleteUtils.willDeleteLastPositionInElement(forward, fromPos, target.dom())) {
      deleteLastPosition(forward, editor, target, parentInlines);
      return true;
    } else {
      return false;
    }
  }).getOr(false);
};
Example #25
0
const closestCaret = (root: HTMLElement, clientX: number, clientY: number): CaretInfo => {
  let closestNodeRect;

  const contentEditableFalseNodeRects = getClientRects(getFakeCaretTargets(root));
  const targetNodeRects = Arr.filter(contentEditableFalseNodeRects, (rect) => clientY >= rect.top && clientY <= rect.bottom);

  closestNodeRect = findClosestClientRect(targetNodeRects, clientX);
  if (closestNodeRect) {
    closestNodeRect = findClosestClientRect(findLineNodeRects(root, closestNodeRect), clientX);
    if (closestNodeRect && isFakeCaretTarget(closestNodeRect.node)) {
      return caretInfo(closestNodeRect, clientX);
    }
  }

  return null;
};
Example #26
0
const identifyButtons = (editor: Editor, toolbarConfig: Partial<RenderUiConfig>, extras: Extras, prefixes: Option<string[]>): ToolbarGroup[] => {
  const toolbarGroups = createToolbar(toolbarConfig);
  const groups = Arr.map(toolbarGroups, (group) => {
    const items = Arr.bind(group.items, (toolbarItem) => {
      return toolbarItem.trim().length === 0 ? [] : lookupButton(editor, toolbarConfig.buttons, toolbarItem, extras, prefixes).toArray();
    });
    return {
      title: Option.from(editor.translate(group.name)),
      items
    };
  });

  return Arr.filter(groups, (group) => {
    return group.items.length > 0;
  });
};
Example #27
0
  const fromHistoryMenuItems = function (history) {
    const historyItems = history.hasOwnProperty(fileType) ? history[fileType] : [ ];
    const uniqueHistory = Arr.filter(historyItems, function (url) {
      return isUniqueUrl(url, targets);
    });

    return Tools.map(uniqueHistory, function (url) {
      return {
        title: url,
        value: {
          title: url,
          url,
          attach: Fun.noop
        }
      };
    });
  };
Example #28
0
UnitTest.test('SizeInputConvertTest', () => {

  const check = (expected: Option<number>, size: Size, unit: SizeUnit) => {
    const result = convertUnit(size, unit);
    assert.eq(
      true, expected.equals(result),
      'Expected conversion of ' + JSON.stringify(size) +
      ' to ' + unit + ' = ' + result.toString()
    );
  };

  check(Option.some(12), nuSize(12, 'mm'), 'mm');
  check(Option.some(16848), nuSize(234, 'in'), 'pt');
  check(Option.some(75.59055118110236), nuSize(2, 'cm'), 'px');
  check(Option.none(), nuSize(2, 'cm'), 'ch');

  Jsc.property(
    'All units can convert to themselves',
    Jsc.number(0, largeSensible), Jsc.oneof(Jsc.elements(units)),
    function (value: number, unit: SizeUnit) {
      const outValue = convertUnit(nuSize(value, unit), unit).getOrNull();
      return Jsc.eq(value, outValue);
    }
  );

  const approxEq = (value, outValue) => Math.abs(value - outValue) < 0.000001;
  Jsc.property(
    'All convertable units should convert back and forth',
    Jsc.number(0, largeSensible), Jsc.oneof(Jsc.elements(convertableUnits)), Jsc.oneof(Jsc.elements(convertableUnits)),
    function (value: number, unit1: SizeUnit, unit2: SizeUnit) {
      const outValue = convertUnit(nuSize(value, unit1), unit2).bind(
        (unit2Value) => convertUnit(nuSize(unit2Value, unit2), unit1)
      ).getOrNull();
      return outValue !== null && approxEq(value, outValue);
    }
  );

  const nonConvertable = Arr.filter(units, (unit) => !Arr.contains(convertableUnits, unit));
  Jsc.property(
    'All non-convertable units can only convert to themselves',
    Jsc.number(0, largeSensible), Jsc.oneof(Jsc.elements(nonConvertable)), Jsc.oneof(Jsc.elements(units)),
    function (value: number, unit1: SizeUnit, unit2: SizeUnit) {
      return Jsc.eq(unit1 === unit2, convertUnit(nuSize(value, unit1), unit2).isSome());
    }
  );
});
Example #29
0
        TableLookup.table(cell).each((table) => {

          const elements = Arr.filter(Elements.fromHtml(e.content), function (content) {
            return Node.name(content) !== 'meta';
          });

          if (elements.length === 1 && Node.name(elements[0]) === 'table') {
            e.preventDefault();

            const doc = Element.fromDom(editor.getDoc());
            const generators = TableFill.paste(doc);
            const targets = TableTargets.paste(cell, elements[0], generators);
            actions.pasteCells(table, targets).each(function (rng) {
              editor.selection.setRng(rng);
              editor.focus();
              cellSelection.clear(table);
            });
          }
        });
Example #30
0
    return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function (result) {
      result = Arr.filter(result, function (resultItem) {
        // ImageScanner internally converts images that it finds, but it may fail to do so if image source is inaccessible.
        // In such case resultItem will contain appropriate text error message, instead of image data.
        if (typeof resultItem === 'string') {
          ErrorReporter.displayError(editor, resultItem);
          return false;
        }
        return true;
      });

      Arr.each(result, function (resultItem) {
        replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());
        resultItem.image.src = resultItem.blobInfo.blobUri();
        resultItem.image.removeAttribute('data-mce-src');
      });

      return result;
    }));