コード例 #1
0
UnitTest.asynctest('browser.tinymce.core.selection.SelectionUtilsTest', function () {
  const success = arguments[arguments.length - 2];
  const failure = arguments[arguments.length - 1];
  const viewBlock = ViewBlock();

  const cSetHtml = function (html) {
    return Chain.op(function () {
      viewBlock.update(html);
    });
  };

  const cHasAllContentsSelected = function (startPath, startOffset, endPath, endOffset) {
    return Chain.mapper(function (viewBlock) {
      const sc = Hierarchy.follow(Element.fromDom(viewBlock.get()), startPath).getOrDie();
      const ec = Hierarchy.follow(Element.fromDom(viewBlock.get()), endPath).getOrDie();
      const rng = document.createRange();

      rng.setStart(sc.dom(), startOffset);
      rng.setEnd(ec.dom(), endOffset);

      return SelectionUtils.hasAllContentsSelected(Element.fromDom(viewBlock.get()), rng);
    });
  };

  viewBlock.attach();
  Pipeline.async({}, [
    Logger.t('All text is selected in paragraph', Chain.asStep(viewBlock, [
      cSetHtml('<p>a</p>'),
      cHasAllContentsSelected([0, 0], 0, [0, 0], 1),
      Assertions.cAssertEq('Should be true since all contents is selected', true)
    ])),
    Logger.t('All text is selected in paragraph', Chain.asStep(viewBlock, [
      cSetHtml('<p>ab</p>'),
      cHasAllContentsSelected([0, 0], 0, [0, 0], 2),
      Assertions.cAssertEq('Should be true since all contents is selected', true)
    ])),
    Logger.t('All text is selected in paragraph and sub element', Chain.asStep(viewBlock, [
      cSetHtml('<p>a<b>b</b></p>'),
      cHasAllContentsSelected([0, 0], 0, [0, 1, 0], 1),
      Assertions.cAssertEq('Should be true since all contents is selected', true)
    ])),
    Logger.t('All text is selected in paragraph and with traling br', Chain.asStep(viewBlock, [
      cSetHtml('<p>a<br></p>'),
      cHasAllContentsSelected([0, 0], 0, [0, 0], 1),
      Assertions.cAssertEq('Should be true since all contents is selected', true)
    ])),
    Logger.t('Collapsed range in paragraph', Chain.asStep(viewBlock, [
      cSetHtml('<p>a</p>'),
      cHasAllContentsSelected([0, 0], 0, [0, 0], 0),
      Assertions.cAssertEq('Should be false since only some contents is selected', false)
    ])),
    Logger.t('Partial text selection in paragraph', Chain.asStep(viewBlock, [
      cSetHtml('<p>ab</p>'),
      cHasAllContentsSelected([0, 0], 0, [0, 0], 1),
      Assertions.cAssertEq('Should be false since only some contents is selected', false)
    ])),
    Logger.t('Partial text selection in paragraph', Chain.asStep(viewBlock, [
      cSetHtml('<p>ab</p>'),
      cHasAllContentsSelected([0, 0], 1, [0, 0], 2),
      Assertions.cAssertEq('Should be false since only some contents is selected', false)
    ])),
    Logger.t('Partial mixed selection in paragraph', Chain.asStep(viewBlock, [
      cSetHtml('<p>a<b>bc</b></p>'),
      cHasAllContentsSelected([0, 0], 1, [0, 1, 0], 1),
      Assertions.cAssertEq('Should be false since only some contents is selected', false)
    ]))
  ], function () {
    viewBlock.detach();
    success();
  }, failure);
});
コード例 #2
0
ファイル: InsertNewLineTest.ts プロジェクト: tinymce/tinymce
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const body = Element.fromDom(editor.getBody());

    Pipeline.async({}, [
      tinyApis.sFocus,
      Logger.t('Enter in paragraph', GeneralSteps.sequence([
        Logger.t('Insert block before', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>ab</p>'),
          tinyApis.sSetCursor([0, 0], 0),
          sInsertNewline(editor, { }),
          tinyApis.sAssertContent('<p>&nbsp;</p><p>ab</p>'),
          tinyApis.sAssertSelection([1, 0], 0, [1, 0], 0)
        ])),
        Logger.t('Split block in the middle', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>ab</p>'),
          tinyApis.sSetCursor([0, 0], 1),
          sInsertNewline(editor, { }),
          tinyApis.sAssertContent('<p>a</p><p>b</p>'),
          tinyApis.sAssertSelection([1, 0], 0, [1, 0], 0)
        ])),
        Logger.t('Insert block after', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>ab</p>'),
          tinyApis.sSetCursor([0, 0], 2),
          sInsertNewline(editor, { }),
          tinyApis.sAssertContent('<p>ab</p><p>&nbsp;</p>'),
          tinyApis.sAssertSelection([1], 0, [1], 0)
        ])),
        Logger.t('Insert block after bookmark', GeneralSteps.sequence([
          tinyApis.sSetRawContent(`<p>${bookmarkSpan}<br data-mce-bogus="1"></p>`),
          tinyApis.sSetCursor([0], 1),
          sInsertNewline(editor, { }),
          Assertions.sAssertStructure('Content should only have one bookmark span', ApproxStructure.build((s, str) => {
            return s.element('body', {
              children: [
                s.element('p', {
                  children: [
                    ApproxStructure.fromHtml(bookmarkSpan),
                    s.element('br', {
                      attrs: {
                        'data-mce-bogus': str.is('1')
                      }
                    })
                  ]
                }),
                s.element('p', {
                  children: [
                    s.element('br', {
                      attrs: {
                        'data-mce-bogus': str.is('1')
                      }
                    })
                  ]
                })
              ]
            });
          }), body),
          tinyApis.sAssertSelection([1], 0, [1], 0)
        ]))
      ])),
      Logger.t('br_newline_selector', GeneralSteps.sequence([
        tinyApis.sSetSetting('br_newline_selector', 'p,div.test'),
        Logger.t('Insert newline where br is forced', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>ab</p>'),
          tinyApis.sSetCursor([0, 0], 1),
          sInsertNewline(editor, { }),
          tinyApis.sNodeChanged,
          tinyApis.sAssertContent('<p>a<br />b</p>')
        ])),
        Logger.t('Insert newline where br is forced', GeneralSteps.sequence([
          tinyApis.sSetContent('<div class="test">ab</div>'),
          tinyApis.sSetCursor([0, 0], 1),
          sInsertNewline(editor, { }),
          tinyApis.sNodeChanged,
          tinyApis.sAssertContent('<div class="test">a<br />b</div>')
        ])),
        Logger.t('Insert newline where br is not forced', GeneralSteps.sequence([
          tinyApis.sSetContent('<div>ab</div>'),
          tinyApis.sSetCursor([0, 0], 1),
          sInsertNewline(editor, { }),
          tinyApis.sNodeChanged,
          tinyApis.sAssertContent('<div>a</div><div>b</div>')
        ])),
        tinyApis.sDeleteSetting('br_newline_selector')
      ])),
      Logger.t('no_newline_selector', GeneralSteps.sequence([
        tinyApis.sSetSetting('no_newline_selector', [ 'p,div.test' ]),
        Logger.t('Insert newline where newline is blocked', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>ab</p>'),
          tinyApis.sSetCursor([0, 0], 1),
          sInsertNewline(editor, { }),
          tinyApis.sNodeChanged,
          tinyApis.sAssertContent('<p>ab</p>')
        ])),
        Logger.t('Insert newline where newline is blocked', GeneralSteps.sequence([
          tinyApis.sSetContent('<div class="test">ab</div>'),
          tinyApis.sSetCursor([0, 0], 1),
          sInsertNewline(editor, { }),
          tinyApis.sNodeChanged,
          tinyApis.sAssertContent('<div class="test">ab</div>')
        ])),
        Logger.t('Insert newline where newline is not blocked', GeneralSteps.sequence([
          tinyApis.sSetContent('<div>ab</div>'),
          tinyApis.sSetCursor([0, 0], 1),
          sInsertNewline(editor, { }),
          tinyApis.sNodeChanged,
          tinyApis.sAssertContent('<div>a</div><div>b</div>')
        ])),
        tinyApis.sDeleteSetting('no_newline_selector')
      ])),
      Logger.t('Insert newline before image in link', GeneralSteps.sequence([
        tinyApis.sSetContent('<p><a href="#">a<img src="about:blank" /></a></p>'),
        tinyApis.sSetCursor([0, 0], 1),
        sInsertNewline(editor, { }),
        tinyApis.sAssertContent('<p><a href="#">a</a></p><p><a href="#"><img src="about:blank" /></a></p>'),
        // For some bizarre IE issue getSelection().addRange() creates a zwsp from nowhere and moves the caret after it
        browser.isIE() ? tinyApis.sAssertSelection([1, 0, 0], 1, [1, 0, 0], 1) : tinyApis.sAssertSelection([1, 0], 0, [1, 0], 0)
      ]))
    ], onSuccess, onFailure);
  }, {
コード例 #3
0
ファイル: ImagePluginTest.ts プロジェクト: tinymce/tinymce
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const api = TinyApis(editor);
    const ui = TinyUi(editor);

    const sInitAndOpenDialog = (content: string, cursorPos: any) => {
      return GeneralSteps.sequence([
        api.sSetSetting('image_advtab', true),
        api.sSetSetting('image_dimensions', false),
        api.sSetContent(content),
        // api.sSetCursor([0], 1),
        api.sSetCursor(cursorPos.elementPath, cursorPos.offset),
        api.sExecCommand('mceImage', true),
        ui.sWaitForPopup('Wait for Image dialog', 'div[role="dialog"]'),
      ]);
    };

    const createTestWithContent = (name: string, content: string, cursorPos: any, data: Partial<ImageDialogData>, expectedContent: string) => {
      return Log.stepsAsStep('TBA', 'Image: ' + name, [
        sInitAndOpenDialog(content, cursorPos),
        Chain.asStep({}, [
          cFillActiveDialog(data, true)
        ]),
        ui.sClickOnUi('click save', 'div[role="dialog"] button:contains("Save")'),
        api.sAssertContent(expectedContent)
      ]);
    };

    const createTestOnEmptyEditor = (name: string, data: Partial<ImageDialogData>, expectedContent: string) => {
      return createTestWithContent(name, '', { elementPath: [0], offset: 0 }, data, expectedContent);
    };

    const createTestUpdatedStyle = (name: string, style: string, assertion: Step<any, any>) => {
      return Log.stepsAsStep('TBA', 'Image: ' + name, [
        sInitAndOpenDialog('', { elementPath: [0], offset: 0 }),
        ui.sClickOnUi('Switch to Advanced tab', '.tox-tab:contains("Advanced")'),
        Chain.asStep(Body.body(), [
          cSetInputValue(advancedTabSelectors.style, style)
        ]),
        assertion,
        ui.sClickOnUi('click save', 'div[role="dialog"] button:contains("Save")'),
      ]);
    };

    const suiteArr = [
      createTestOnEmptyEditor(
        'Advanced image dialog margin space options on empty editor',
        {
          alt: 'alt',
          hspace: '10',
          src: {
            value: 'src',
          },
          vspace: '10'
        },
        '<p><img style="margin: 10px;" src="src" alt="alt" /></p>'
      ),
      createTestOnEmptyEditor(
        'Advanced image dialog border style only options on empty editor',
        {
          alt: 'alt',
          src: {
            value: 'src'
          },
          style: 'border-width: 10px; border-style: solid;'
        },
        '<p><img style="border-width: 10px; border-style: solid;" src="src" alt="alt" /></p>'
      ),
      createTestOnEmptyEditor(
        'Advanced image dialog margin style only options on empty editor',
        {
          alt: 'alt',
          src: {
            value: 'src'
          },
          style: 'margin: 10px;'
        },
        '<p><img style="margin: 10px;" src="src" alt="alt" /></p>'
      ),
      createTestOnEmptyEditor(
        'Advanced image dialog overriden border style options on empty editor',
        {
          alt: 'alt',
          border: '10',
          src: {
            value: 'src'
          },
          style: 'border-width: 15px;'
        },
        '<p><img style="border-width: 10px;" src="src" alt="alt" /></p>'
      ),
      createTestOnEmptyEditor(
        'Advanced image dialog overriden margin style options on empty editor',
        {
          alt: 'alt',
          hspace: '10',
          src: {
            value: 'src'
          },
          style: 'margin-left: 15px; margin-top: 20px;',
          vspace: '10'
        },
        '<p><img style="margin: 10px;" src="src" alt="alt" /></p>'
      ),
      createTestWithContent(
        'Advanced image dialog border option on editor with content',
        '<p>a</p>',
        {
          elementPath: [0],
          offset: 1
        },
        {
          alt: 'alt',
          border: '10',
          borderstyle: 'dashed',
          src: {
            value: 'src'
          }
        },
        '<p>a<img style="border-width: 10px; border-style: dashed;" src="src" alt="alt" /></p>'),
      createTestUpdatedStyle(
        'Advanced image dialog non-shorthand horizontal margin style change test',
        'margin-left: 15px; margin-right: 15px;',
        Chain.asStep({}, [
          cAssertInputValue(advancedTabSelectors.vspace, ''),
          cAssertInputValue(advancedTabSelectors.hspace, '15'),
          cAssertInputValue(advancedTabSelectors.style, 'margin-left: 15px; margin-right: 15px;')
        ])
      ),
      createTestUpdatedStyle(
        'Advanced image dialog non-shorthand vertical margin style change test',
        'margin-top: 15px; margin-bottom: 15px;',
        Chain.asStep({}, [
          cAssertInputValue(advancedTabSelectors.vspace, '15'),
          cAssertInputValue(advancedTabSelectors.hspace, ''),
          cAssertInputValue(advancedTabSelectors.style, 'margin-top: 15px; margin-bottom: 15px;')
        ])
      ),
      createTestUpdatedStyle(
        'Advanced image dialog shorthand margin 1 value style change test',
        'margin: 5px;',
        Chain.asStep({}, [
          cAssertInputValue(advancedTabSelectors.vspace, '5'),
          cAssertInputValue(advancedTabSelectors.hspace, '5'),
          cAssertInputValue(advancedTabSelectors.style, 'margin: 5px;')
        ])
      ),
      createTestUpdatedStyle(
        'Advanced image dialog shorthand margin 2 value style change test',
        'margin: 5px 10px;',
        Chain.asStep({}, [
          cAssertInputValue(advancedTabSelectors.vspace, '5'),
          cAssertInputValue(advancedTabSelectors.hspace, '10'),
          cAssertInputValue(advancedTabSelectors.style, 'margin: 5px 10px 5px 10px;')
        ])
      ),
      createTestUpdatedStyle(
        'Advanced image dialog shorthand margin 3 value style change test',
        'margin: 5px 10px 15px;',
        Chain.asStep({}, [
          cAssertInputValue(advancedTabSelectors.vspace, ''),
          cAssertInputValue(advancedTabSelectors.hspace, '10'),
          cAssertInputValue(advancedTabSelectors.style, 'margin: 5px 10px 15px 10px;')
        ])
      ),
      createTestUpdatedStyle(
        'Advanced image dialog shorthand margin 4 value style change test',
        'margin: 5px 10px 15px 20px;',
        Chain.asStep({}, [
          cAssertInputValue(advancedTabSelectors.vspace, ''),
          cAssertInputValue(advancedTabSelectors.hspace, ''),
          cAssertInputValue(advancedTabSelectors.style, 'margin: 5px 10px 15px 20px;')
        ])
      ),
      createTestUpdatedStyle(
        'Advanced image dialog shorthand margin 4 value style change test',
        'margin: 5px 10px 15px 20px; margin-top: 15px;',
        Chain.asStep({}, [
          cAssertInputValue(advancedTabSelectors.vspace, '15'),
          cAssertInputValue(advancedTabSelectors.hspace, ''),
          cAssertInputValue(advancedTabSelectors.style, 'margin: 15px 10px 15px 20px;')
        ])
      )
    ];
    Pipeline.async({}, suiteArr, onSuccess, onFailure);
  }, {
コード例 #4
0
ファイル: ContentFormatsTest.ts プロジェクト: tinymce/tinymce
 TinyLoader.setup(function (editor, onSuccess, onFailure) {
   Pipeline.async({}, Log.steps('TBA', 'Media: Test media content formats', suite.toSteps(editor)), onSuccess, onFailure);
 }, {
コード例 #5
0
UnitTest.asynctest('browser.tinymce.core.dom.ElementTypeTest', function () {
  const success = arguments[arguments.length - 2];
  const failure = arguments[arguments.length - 1];

  const sCheckElement = function (name, predicate, expectedValue) {
    return Step.sync(function () {
      Assertions.assertEq('Should be the expected value for specified element', expectedValue, predicate(Element.fromTag(name)));
    });
  };

  const sCheckText = function (predicate) {
    return Step.sync(function () {
      Assertions.assertEq('Should be false for non element', false, predicate(Element.fromText('text')));
    });
  };

  Pipeline.async({}, [
    Logger.t('Check block elements', GeneralSteps.sequence([
      sCheckElement('p', ElementType.isBlock, true),
      sCheckElement('h1', ElementType.isBlock, true),
      sCheckElement('table', ElementType.isBlock, true),
      sCheckElement('span', ElementType.isBlock, false),
      sCheckElement('b', ElementType.isBlock, false),
      sCheckText(ElementType.isBlock)
    ])),
    Logger.t('Check inline elements', GeneralSteps.sequence([
      sCheckElement('b', ElementType.isInline, true),
      sCheckElement('span', ElementType.isInline, true),
      sCheckElement('p', ElementType.isInline, false),
      sCheckElement('h1', ElementType.isInline, false),
      sCheckText(ElementType.isInline)
    ])),
    Logger.t('Check heading elements', GeneralSteps.sequence([
      sCheckElement('h1', ElementType.isHeading, true),
      sCheckElement('h2', ElementType.isHeading, true),
      sCheckElement('span', ElementType.isHeading, false),
      sCheckElement('table', ElementType.isHeading, false),
      sCheckText(ElementType.isHeading)
    ])),
    Logger.t('Check text block elements', GeneralSteps.sequence([
      sCheckElement('p', ElementType.isTextBlock, true),
      sCheckElement('h1', ElementType.isTextBlock, true),
      sCheckElement('table', ElementType.isTextBlock, false),
      sCheckText(ElementType.isTextBlock)
    ])),
    Logger.t('Check void elements', GeneralSteps.sequence([
      sCheckElement('img', ElementType.isVoid, true),
      sCheckElement('hr', ElementType.isVoid, true),
      sCheckElement('h1', ElementType.isVoid, false),
      sCheckElement('span', ElementType.isVoid, false),
      sCheckText(ElementType.isVoid)
    ])),
    Logger.t('Check table cell elements', GeneralSteps.sequence([
      sCheckElement('th', ElementType.isTableCell, true),
      sCheckElement('td', ElementType.isTableCell, true),
      sCheckElement('h1', ElementType.isTableCell, false),
      sCheckElement('span', ElementType.isTableCell, false),
      sCheckText(ElementType.isTableCell)
    ])),
    Logger.t('Check br elements', GeneralSteps.sequence([
      sCheckElement('br', ElementType.isBr, true),
      sCheckElement('b', ElementType.isBr, false),
      sCheckText(ElementType.isBr)
    ])),
    Logger.t('Check list item elements', GeneralSteps.sequence([
      sCheckElement('br', ElementType.isListItem, false),
      sCheckElement('div', ElementType.isListItem, false),
      sCheckElement('li', ElementType.isListItem, true),
      sCheckElement('dd', ElementType.isListItem, true),
      sCheckElement('dt', ElementType.isListItem, true),
      sCheckText(ElementType.isListItem)
    ])),
    Logger.t('Check list elements', GeneralSteps.sequence([
      sCheckElement('br', ElementType.isList, false),
      sCheckElement('div', ElementType.isList, false),
      sCheckElement('ul', ElementType.isList, true),
      sCheckElement('ol', ElementType.isList, true),
      sCheckElement('dl', ElementType.isList, true),
      sCheckText(ElementType.isList)
    ])),
    Logger.t('Check table section elements', GeneralSteps.sequence([
      sCheckElement('br', ElementType.isTableSection, false),
      sCheckElement('div', ElementType.isTableSection, false),
      sCheckElement('thead', ElementType.isTableSection, true),
      sCheckElement('tbody', ElementType.isTableSection, true),
      sCheckElement('tfoot', ElementType.isTableSection, true),
      sCheckText(ElementType.isTableSection)
    ]))
  ], function () {
    success();
  }, failure);
});
コード例 #6
0
UnitTest.asynctest('browser.tinymce.core.dom.ParentsTest', function () {
  const success = arguments[arguments.length - 2];
  const failure = arguments[arguments.length - 1];

  const cCreateStructure = function (html) {
    return Chain.mapper(function (_) {
      return Element.fromHtml(html);
    });
  };

  const cParentsUntil = function (startPath, rootPath, predicate) {
    return Chain.mapper(function (structure) {
      const startNode = Hierarchy.follow(structure, startPath).getOrDie();
      const rootNode = Hierarchy.follow(structure, rootPath).getOrDie();
      return Parents.parentsUntil(startNode, rootNode, predicate);
    });
  };

  const cParents = function (startPath, rootPath) {
    return Chain.mapper(function (structure) {
      const startNode = Hierarchy.follow(structure, startPath).getOrDie();
      const rootNode = Hierarchy.follow(structure, rootPath).getOrDie();
      return Parents.parents(startNode, rootNode);
    });
  };

  const cParentsAndSelf = function (startPath, rootPath) {
    return Chain.mapper(function (structure) {
      const startNode = Hierarchy.follow(structure, startPath).getOrDie();
      const rootNode = Hierarchy.follow(structure, rootPath).getOrDie();
      return Parents.parentsAndSelf(startNode, rootNode);
    });
  };

  const cAssertElementNames = function (expectedNames) {
    return Chain.mapper(function (parents) {
      const names = Arr.map(parents, Node.name);
      Assertions.assertEq('Should be expected names', expectedNames, names);
      return {};
    });
  };

  const hasName = function (name) {
    return function (elm) {
      return Node.name(elm) === name;
    };
  };

  Pipeline.async({}, [
    Logger.t('parentsUntil', GeneralSteps.sequence([
      Logger.t('parentsUntil root', Chain.asStep({}, [
        cCreateStructure('<p><b>a</b></p>'),
        cParentsUntil([0, 0], [], hasName('p')),
        cAssertElementNames(['b'])
      ])),

      Logger.t('parentsUntil root on elm', Chain.asStep({}, [
        cCreateStructure('<p><b><i></i></b></p>'),
        cParentsUntil([0, 0], [], hasName('p')),
        cAssertElementNames(['b'])
      ])),

      Logger.t('parentsUntil root deeper', Chain.asStep({}, [
        cCreateStructure('<p><b><i><u>a</u></i></b></p>'),
        cParentsUntil([0, 0, 0, 0], [], hasName('p')),
        cAssertElementNames(['u', 'i', 'b'])
      ])),

      Logger.t('parentsUntil end at b', Chain.asStep({}, [
        cCreateStructure('<p><b><i><u>a</u></i></b></p>'),
        cParentsUntil([0, 0, 0, 0], [], hasName('b')),
        cAssertElementNames(['u', 'i'])
      ])),

      Logger.t('parentsUntil end at b', Chain.asStep({}, [
        cCreateStructure('<p><b>a</b></p>'),
        cParentsUntil([0, 0], [], hasName('b')),
        cAssertElementNames([])
      ])),

      Logger.t('parentsUntil root scope', Chain.asStep({}, [
        cCreateStructure('<p><b><i><u>a</u></i></b></p>'),
        cParentsUntil([0, 0, 0, 0], [0], hasName('p')),
        cAssertElementNames(['u', 'i'])
      ]))
    ])),

    Logger.t('parents', GeneralSteps.sequence([
      Logger.t('parents', Chain.asStep({}, [
        cCreateStructure('<p><b><i><u>a</u></i></b></p>'),
        cParents([0, 0, 0, 0], []),
        cAssertElementNames(['u', 'i', 'b'])
      ])),

      Logger.t('parents scoped', Chain.asStep({}, [
        cCreateStructure('<p><b><i><u>a</u></i></b></p>'),
        cParents([0, 0, 0, 0], [0]),
        cAssertElementNames(['u', 'i'])
      ]))
    ])),

    Logger.t('parentsAndSelf', GeneralSteps.sequence([
      Logger.t('parentsAndSelf', Chain.asStep({}, [
        cCreateStructure('<p><b><i><u>a</u></i></b></p>'),
        cParentsAndSelf([0, 0, 0, 0], []),
        cAssertElementNames(['#text', 'u', 'i', 'b'])
      ])),

      Logger.t('parentsAndSelf scoped', Chain.asStep({}, [
        cCreateStructure('<p><b><i><u>a</u></i></b></p>'),
        cParentsAndSelf([0, 0, 0, 0], [0]),
        cAssertElementNames(['#text', 'u', 'i'])
      ]))
    ]))
  ], function () {
    success();
  }, failure);
});
コード例 #7
0
ファイル: AddOnManagerTest.ts プロジェクト: tinymce/tinymce
UnitTest.asynctest('browser.tinymce.core.AddOnManagerTest', (success, failure) => {
  const suite = LegacyUnit.createSuite();
  let languagePackUrl;

  const patch = function (proto, name, patchFunc) {
    let originalFunc = proto[name];
    let originalFuncs = proto.__originalFuncs;

    if (!originalFuncs) {
      proto.__originalFuncs = originalFuncs = {};
    }

    if (!originalFuncs[name]) {
      originalFuncs[name] = originalFunc;
    } else {
      originalFunc = originalFuncs[name];
    }

    proto[name] = function () {
      const args = Array.prototype.slice.call(arguments);
      args.unshift(originalFunc);
      return patchFunc.apply(this, args);
    };
  };

  const unpatch = function (proto, name?) {
    const originalFuncs = proto.__originalFuncs;

    if (!originalFuncs) {
      return;
    }

    if (name) {
      proto[name] = originalFuncs[name];
      delete originalFuncs[name];
    } else {
      for (const key in originalFuncs) {
        proto[key] = originalFuncs[key];
      }

      delete proto.__originalFuncs;
    }
  };

  const getLanguagePackUrl = function (code, languages?) {
    languagePackUrl = null;
    I18n.setCode(code);
    PluginManager.requireLangPack('plugin', languages);
    return languagePackUrl;
  };

  suite.test('requireLangPack', function () {
    AddOnManager.PluginManager.urls.plugin = '/root';

    LegacyUnit.equal(getLanguagePackUrl('sv_SE'), '/root/langs/sv_SE.js');
    LegacyUnit.equal(getLanguagePackUrl('sv_SE', 'sv,en,us'), '/root/langs/sv.js');
    LegacyUnit.equal(getLanguagePackUrl('sv_SE', 'sv_SE,en_US'), '/root/langs/sv_SE.js');
    LegacyUnit.equal(getLanguagePackUrl('sv'), '/root/langs/sv.js');
    LegacyUnit.equal(getLanguagePackUrl('sv', 'sv'), '/root/langs/sv.js');
    LegacyUnit.equal(getLanguagePackUrl('sv', 'sv,en,us'), '/root/langs/sv.js');
    LegacyUnit.equal(getLanguagePackUrl('sv', 'en,sv,us'), '/root/langs/sv.js');
    LegacyUnit.equal(getLanguagePackUrl('sv', 'en,us,sv'), '/root/langs/sv.js');
    LegacyUnit.strictEqual(getLanguagePackUrl('sv', 'en,us'), null);

    AddOnManager.languageLoad = false;
    LegacyUnit.strictEqual(getLanguagePackUrl('sv', 'sv'), null);
  });

  patch(ScriptLoader.ScriptLoader, 'add', function (origFunc, url) {
    languagePackUrl = url;
  });

  Pipeline.async({}, suite.toSteps({}), function () {
    success();
    unpatch(ScriptLoader.ScriptLoader);
  }, failure);
});
コード例 #8
0
ファイル: SkinFalseTest.ts プロジェクト: abstask/tinymce
 TinyLoader.setup(function (editor, onSuccess, onFailure) {
   // This is a weird test that only checks that the skinloaded event is fired even if skin is set to false
   Pipeline.async({}, [
   ], onSuccess, onFailure);
 }, {
コード例 #9
0
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const tinyActions = TinyActions(editor);
    let count;

    // hijack editor.selection.normalize() to count how many times it will be invoked
    const backupNormalize = editor.selection.normalize;
    const normalize = function () {
      count = count === undefined ? 1 : count + 1;
      backupNormalize.apply(this, arguments);
    };
    editor.selection.normalize = normalize;

    const sResetNormalizeCounter = function () {
      return Step.sync(function () {
        count = 0;
      });
    };

    const sAssertNormalizeCounter = function (expected) {
      return Step.sync(function () {
        Assertions.assertEq('checking normalization counter', expected, count);
      });
    };

    const sClickBody = function (editor) {
      return Step.sync(function () {
        const target = editor.getBody();

        editor.fire('mousedown', { target });
        editor.fire('mouseup', { target });
        editor.fire('click', { target });
      });
    };

    Pipeline.async({}, [
      tinyApis.sFocus,

      Logger.t('Test normalization for floated images', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a<img src="about:blank" style="float: right"></p>'),
        tinyApis.sSetSelection([0], 1, [0], 2),
        Step.sync(function () {
          const selection = editor.selection.getSel();
          Assertions.assertEq('Anchor node should be the paragraph not the text node', 'P', selection.anchorNode.nodeName);
          Assertions.assertEq('Anchor offset should be the element index', 1, selection.anchorOffset);
        })
      ])),

      Logger.t('Normalize on key events when range is collapsed', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a</p><p>b</p>'),
        tinyApis.sSetSelection([], 1, [], 1),
        tinyActions.sContentKeystroke(Keys.escape(), {}),
        tinyApis.sAssertSelection([1, 0], 0, [1, 0], 0)
      ])),

      Logger.t('Normalize on mouse events when range is expanded', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a</p><p>b</p>'),
        tinyApis.sSetSelection([], 0, [], 1),
        sClickBody(editor),
        tinyApis.sAssertSelection([0, 0], 0, [0, 0], 1)
      ])),

      Logger.t('Normalize on mouse events when range is collapsed', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a</p><p>b</p>'),
        tinyApis.sSetSelection([], 1, [], 1),
        sClickBody(editor),
        tinyApis.sAssertSelection([1, 0], 0, [1, 0], 0)
      ])),

      Logger.t('Normalization during operations with modifier keys, should run only once in the end when user releases modifier key.', GeneralSteps.sequence([
        sResetNormalizeCounter(),
        tinyApis.sSetContent('<p><b>a</b><i>a</i></p>'),
        tinyApis.sSetSelection([0, 0, 0], 0, [0, 0], 0),
        Keyboard.sKeyup(Element.fromDom(editor.getDoc()), Keys.left(), { shift: true }),
        sAssertNormalizeCounter(0),
        Keyboard.sKeyup(Element.fromDom(editor.getDoc()), 17, {}), // single ctrl
        sAssertNormalizeCounter(1),
        tinyApis.sAssertSelection([0, 0], 0, [0, 0], 0)
      ]))
    ], onSuccess, onFailure);
  }, {
コード例 #10
0
  TinyLoader.setup(function (editor: Editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    const sTestAnnotationEvents = (label: string, start: number[], soffset: number, expected: Array<{ uid: string, name: string, state: boolean}>): any => {
      return GeneralSteps.sequence([
        tinyApis.sSetSelection(start, soffset, start, soffset),
        Waiter.sTryUntil(
          label,
          sAssertChanges('sTestAnnotationEvents.sAssertChanges', expected),
          10,
          1000
        ),
      ]);
    };

    const sTestChanges = GeneralSteps.sequence([
      // '<p>This |is the first paragraph</p><p>This is the second.</p><p>This is| the third.</p><p>Spanning |multiple</p><p>par||ag||raphs| now</p>'
      tinyApis.sSetContent([
        '<p>This is the first paragraph</p>',
        '<p>This is the second.</p>',
        '<p>This is the third.</p>',
        '<p>Spanning multiple</p>',
        '<p>paragraphs now</p>'
      ].join('')),
      tinyApis.sSetSelection([ 0, 0 ], 'This '.length, [ 0, 0 ], 'This is'.length),
      sAnnotate(editor, 'alpha', 'id-one', { anything: 'comment-1' }),

      tinyApis.sSetSelection([ 1, 0 ], 'T'.length, [ 1, 0 ], 'This is'.length),
      sAnnotate(editor, 'alpha', 'id-two', { anything: 'comment-two' }),

      tinyApis.sSetSelection([ 2, 0 ], 'This is the th'.length, [ 2, 0 ], 'This is the thir'.length),
      sAnnotate(editor, 'beta', 'id-three', { something: 'comment-three' }),

      tinyApis.sSetSelection([ 3, 0 ], 'Spanning '.length, [ 4, 0 ], 'paragraphs'.length),
      sAnnotate(editor, 'gamma', 'id-four', { something: 'comment-four' }),

      tinyApis.sSetSelection([ 4, 0, 0 ], 'par'.length, [ 4, 0, 0 ], 'parag'.length ),
      sAnnotate(editor, 'delta', 'id-five', { something: 'comment-five' }),

      Step.wait(1000),
      sClearChanges,

      sAssertHtmlContent(tinyApis, [
        `<p>This <span data-mce-annotation="alpha" data-test-anything="comment-1" data-mce-annotation-uid="id-one" class="mce-annotation">is</span> the first paragraph</p>`,

        `<p>T<span data-mce-annotation="alpha" data-test-anything="comment-two" data-mce-annotation-uid="id-two" class="mce-annotation">his is</span> the second.</p>`,

        `<p>This is the th<span data-mce-annotation="beta" data-test-something="comment-three" data-mce-annotation-uid="id-three" class="mce-annotation">ir</span>d.</p>`,

        `<p>Spanning <span data-mce-annotation="gamma" data-test-something="comment-four" data-mce-annotation-uid="id-four" class="mce-annotation">multiple</span></p>`,

        `<p><span data-mce-annotation="gamma" data-test-something="comment-four" data-mce-annotation-uid="id-four" class="mce-annotation">par` +
          `<span data-mce-annotation="delta" data-test-something="comment-five" data-mce-annotation-uid="id-five" class="mce-annotation delta-test">ag</span>` +
          `raphs</span> now</p>`
      ]),

      // Outside: p(0) > text(0) > "Th".length
      // Inside: p(0) > span(1) > text(0) > 'i'.length
      // Inside: p(1) > span(1) > text(0), 'hi'.length
      // Outside: p(1) > text(2) > ' the '.length

      Waiter.sTryUntil(
        'Waiting for no changes',
        sAssertChanges('Should be no changes', [ ]),
        10,
        1000
      ),

      sTestAnnotationEvents(
        'No annotation at cursor',
        [ 0, 0 ], 'Th'.length,
        [
          { state: false, name: 'delta', uid: null },
          { state: false, name: 'gamma', uid: null }
        ]
      ),

      sTestAnnotationEvents(
        'At annotation alpha, id = id-one',
        [ 0, 1, 0 ], 'i'.length,
        [
          { state: false, name: 'delta', uid: null },
          { state: false, name: 'gamma', uid: null },
          { state: true, name: 'alpha', uid: 'id-one' }
        ]
      ),

      sTestAnnotationEvents(
        'At annotation alpha, id = id-two',
        [ 1, 1, 0 ], 'hi'.length,
        [
          { state: false, name: 'delta', uid: null },
          { state: false, name: 'gamma', uid: null },
          { state: true, name: 'alpha', uid: 'id-one' },
          { state: true, name: 'alpha', uid: 'id-two' }
        ]
      ),

      tinyApis.sSetSelection([ 1, 1, 0 ], 'his'.length, [ 1, 1, 0 ], 'his'.length),
      // Give it time to throttle a node change.
      Step.wait(400),
      Waiter.sTryUntil(
        'Moving selection within the same marker (alpha id-two) ... shoud not fire change',
        sAssertChanges('checking changes',
          [
            { state: false, name: 'delta', uid: null },
            { state: false, name: 'gamma', uid: null },
            { state: true, name: 'alpha', uid: 'id-one' },
            { state: true, name: 'alpha', uid: 'id-two' }
          ]
        ),
        10,
        1000
      ),

      sTestAnnotationEvents(
        'Outside annotations again',
        [ 1, 2 ], ' the '.length,
        [
          { state: false, name: 'delta', uid: null },
          { state: false, name: 'gamma', uid: null },
          { state: true, name: 'alpha', uid: 'id-one' },
          { state: true, name: 'alpha', uid: 'id-two' },
          { state: false, name: 'alpha', uid: null }
        ]
      ),

      sTestAnnotationEvents(
        'Inside annotation beta, id = id-three',
        [ 2, 1, 0 ], 'i'.length,
        [
          { state: false, name: 'delta', uid: null },
          { state: false, name: 'gamma', uid: null },
          { state: true, name: 'alpha', uid: 'id-one' },
          { state: true, name: 'alpha', uid: 'id-two' },
          { state: false, name: 'alpha', uid: null },
          { state: true, name: 'beta', uid: 'id-three' }
        ]
      ),

      tinyApis.sSetSelection([ 2, 0 ], 'T'.length, [ 2, 0 ], 'T'.length),
      Waiter.sTryUntil(
        'Moving selection outside all annotations. Should fire null',
        sAssertChanges('checking changes',
          [
            { state: false, name: 'delta', uid: null },
            { state: false, name: 'gamma', uid: null },
            { state: true, name: 'alpha', uid: 'id-one' },
            { state: true, name: 'alpha', uid: 'id-two' },
            { state: false, name: 'alpha', uid: null },
            { state: true, name: 'beta', uid: 'id-three' },
            { state: false, name: 'beta', uid: null }
          ]
        ),
        10,
        1000
      ),

      tinyApis.sSetSelection([ 2, 2 ], 'd'.length, [ 2, 2 ], 'd'.length),
      // Give it time to throttle a node change.
      Step.wait(400),
      Waiter.sTryUntil(
        'Moving selection outside all annotations (again). Should NOT fire null because it already has',
        sAssertChanges('checking changes',
          [
            { state: false, name: 'delta', uid: null },
            { state: false, name: 'gamma', uid: null },
            { state: true, name: 'alpha', uid: 'id-one' },
            { state: true, name: 'alpha', uid: 'id-two' },
            { state: false, name: 'alpha', uid: null },
            { state: true, name: 'beta', uid: 'id-three' },
            { state: false, name: 'beta', uid: null }
          ]
        ),
        10,
        1000
      ),
      sClearChanges,

      tinyApis.sSetSelection([ 4, 0, 1, 0 ], 'a'.length, [ 4, 0, 1, 0 ], 'a'.length),
      // Give it time to throttle a node change.
      Step.wait(400),
      Waiter.sTryUntil(
        'Moving selection inside delta (which is inside gamma)',
        sAssertChanges('checking changes',
          [
            { state: true, name: 'delta', uid: 'id-five' },
            { state: true, name: 'gamma', uid: 'id-four' }
          ]
        ),
        10,
        1000
      ),

      tinyApis.sSetSelection([ 4, 0, 0 ], 'p'.length, [ 4, 0, 0 ], 'p'.length),
      // Give it time to throttle a node change.
      Step.wait(400),
      Waiter.sTryUntil(
        'Moving selection inside just gamma (but not delta)',
        sAssertChanges('checking changes',
          [
            { state: true, name: 'delta', uid: 'id-five' },
            { state: true, name: 'gamma', uid: 'id-four' },
            { state: false, name: 'delta', uid: null }
          ]
        ),
        10,
        1000
      ),
    ]);

    Pipeline.async({}, [
      tinyApis.sFocus,
      sTestChanges
    ], onSuccess, onFailure);
  }, {