Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
eee97b89
Commit
eee97b89
authored
Oct 22, 2021
by
GitLab Renovate
Committed by
Jacques Erasmus
Oct 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update Content Editor Packages
parent
52715b71
Changes
27
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
498 additions
and
387 deletions
+498
-387
app/assets/javascripts/content_editor/extensions/blockquote.js
...ssets/javascripts/content_editor/extensions/blockquote.js
+8
-4
app/assets/javascripts/content_editor/extensions/description_list.js
...javascripts/content_editor/extensions/description_list.js
+4
-5
app/assets/javascripts/content_editor/extensions/details.js
app/assets/javascripts/content_editor/extensions/details.js
+4
-5
app/assets/javascripts/content_editor/extensions/emoji.js
app/assets/javascripts/content_editor/extensions/emoji.js
+19
-17
app/assets/javascripts/content_editor/extensions/horizontal_rule.js
.../javascripts/content_editor/extensions/horizontal_rule.js
+3
-3
app/assets/javascripts/content_editor/extensions/html_marks.js
...ssets/javascripts/content_editor/extensions/html_marks.js
+7
-1
app/assets/javascripts/content_editor/extensions/inline_diff.js
...sets/javascripts/content_editor/extensions/inline_diff.js
+13
-5
app/assets/javascripts/content_editor/extensions/link.js
app/assets/javascripts/content_editor/extensions/link.js
+13
-5
app/assets/javascripts/content_editor/extensions/math_inline.js
...sets/javascripts/content_editor/extensions/math_inline.js
+3
-3
app/assets/javascripts/content_editor/extensions/subscript.js
...assets/javascripts/content_editor/extensions/subscript.js
+7
-1
app/assets/javascripts/content_editor/extensions/superscript.js
...sets/javascripts/content_editor/extensions/superscript.js
+7
-1
app/assets/javascripts/content_editor/extensions/table_of_contents.js
...avascripts/content_editor/extensions/table_of_contents.js
+11
-10
app/assets/javascripts/content_editor/extensions/word_break.js
...ssets/javascripts/content_editor/extensions/word_break.js
+3
-3
app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
...ontent_editor/services/track_input_rules_and_shortcuts.js
+13
-10
package.json
package.json
+21
-22
spec/frontend/content_editor/extensions/attachment_spec.js
spec/frontend/content_editor/extensions/attachment_spec.js
+4
-4
spec/frontend/content_editor/extensions/blockquote_spec.js
spec/frontend/content_editor/extensions/blockquote_spec.js
+32
-14
spec/frontend/content_editor/extensions/emoji_spec.js
spec/frontend/content_editor/extensions/emoji_spec.js
+4
-6
spec/frontend/content_editor/extensions/horizontal_rule_spec.js
...rontend/content_editor/extensions/horizontal_rule_spec.js
+34
-15
spec/frontend/content_editor/extensions/inline_diff_spec.js
spec/frontend/content_editor/extensions/inline_diff_spec.js
+38
-22
spec/frontend/content_editor/extensions/link_spec.js
spec/frontend/content_editor/extensions/link_spec.js
+38
-53
spec/frontend/content_editor/extensions/math_inline_spec.js
spec/frontend/content_editor/extensions/math_inline_spec.js
+2
-9
spec/frontend/content_editor/extensions/table_of_contents_spec.js
...ntend/content_editor/extensions/table_of_contents_spec.js
+16
-16
spec/frontend/content_editor/extensions/word_break_spec.js
spec/frontend/content_editor/extensions/word_break_spec.js
+35
-0
spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js
...t_editor/services/track_input_rules_and_shortcuts_spec.js
+2
-9
spec/frontend/content_editor/test_utils.js
spec/frontend/content_editor/test_utils.js
+23
-0
yarn.lock
yarn.lock
+134
-144
No files found.
app/assets/javascripts/content_editor/extensions/blockquote.js
View file @
eee97b89
import
{
Blockquote
}
from
'
@tiptap/extension-blockquote
'
;
import
{
wrappingInputRule
}
from
'
prosemirror-inputrules
'
;
import
{
wrappingInputRule
}
from
'
@tiptap/core
'
;
import
{
getParents
}
from
'
~/lib/utils/dom_utils
'
;
import
{
getMarkdownSource
}
from
'
../services/markdown_sourcemap
'
;
export
const
multilineInputRegex
=
/^
\s
*>>>
\s
$/gm
;
export
default
Blockquote
.
extend
({
addAttributes
()
{
return
{
...
...
@@ -25,9 +23,15 @@ export default Blockquote.extend({
},
addInputRules
()
{
const
multilineInputRegex
=
/^
\s
*>>>
\s
$/gm
;
return
[
...
this
.
parent
?.(),
wrappingInputRule
(
multilineInputRegex
,
this
.
type
,
()
=>
({
multiline
:
true
})),
wrappingInputRule
({
find
:
multilineInputRegex
,
type
:
this
.
type
,
getAttributes
:
()
=>
({
multiline
:
true
}),
}),
];
},
});
app/assets/javascripts/content_editor/extensions/description_list.js
View file @
eee97b89
import
{
Node
,
mergeAttributes
}
from
'
@tiptap/core
'
;
import
{
wrappingInputRule
}
from
'
prosemirror-inputrules
'
;
export
const
inputRegex
=
/^
\s
*
(
<dl>
)
$/
;
import
{
Node
,
mergeAttributes
,
wrappingInputRule
}
from
'
@tiptap/core
'
;
export
default
Node
.
create
({
name
:
'
descriptionList
'
,
...
...
@@ -18,6 +15,8 @@ export default Node.create({
},
addInputRules
()
{
return
[
wrappingInputRule
(
inputRegex
,
this
.
type
)];
const
inputRegex
=
/^
\s
*
(
<dl>
)
$/
;
return
[
wrappingInputRule
({
find
:
inputRegex
,
type
:
this
.
type
})];
},
});
app/assets/javascripts/content_editor/extensions/details.js
View file @
eee97b89
import
{
Node
}
from
'
@tiptap/core
'
;
import
{
Node
,
wrappingInputRule
}
from
'
@tiptap/core
'
;
import
{
VueNodeViewRenderer
}
from
'
@tiptap/vue-2
'
;
import
{
wrappingInputRule
}
from
'
prosemirror-inputrules
'
;
import
DetailsWrapper
from
'
../components/wrappers/details.vue
'
;
export
const
inputRegex
=
/^
\s
*
(
<details>
)
$/
;
export
default
Node
.
create
({
name
:
'
details
'
,
content
:
'
detailsContent+
'
,
...
...
@@ -24,7 +21,9 @@ export default Node.create({
},
addInputRules
()
{
return
[
wrappingInputRule
(
inputRegex
,
this
.
type
)];
const
inputRegex
=
/^
\s
*
(
<details>
)
$/
;
return
[
wrappingInputRule
({
find
:
inputRegex
,
type
:
this
.
type
})];
},
addCommands
()
{
...
...
app/assets/javascripts/content_editor/extensions/emoji.js
View file @
eee97b89
import
{
Node
}
from
'
@tiptap/core
'
;
import
{
InputRule
}
from
'
prosemirror-inputrules
'
;
import
{
Node
,
InputRule
}
from
'
@tiptap/core
'
;
import
{
initEmojiMap
,
getAllEmoji
}
from
'
~/emoji
'
;
export
const
emojiInputRegex
=
/
(?:
^|
\s)((?:
:
)((?:\w
+
))(?:
:
))
$/
;
export
default
Node
.
create
({
name
:
'
emoji
'
,
...
...
@@ -54,23 +51,28 @@ export default Node.create({
},
addInputRules
()
{
const
emojiInputRegex
=
/
(?:
^|
\s)(
:
(\w
+
)
:
)
$/
;
return
[
new
InputRule
(
emojiInputRegex
,
(
state
,
match
,
start
,
end
)
=>
{
const
[,
,
name
]
=
match
;
const
emojis
=
getAllEmoji
();
const
emoji
=
emojis
[
name
];
const
{
tr
}
=
state
;
new
InputRule
({
find
:
emojiInputRegex
,
handler
:
({
state
,
range
:
{
from
,
to
},
match
})
=>
{
const
[,
,
name
]
=
match
;
const
emojis
=
getAllEmoji
();
const
emoji
=
emojis
[
name
];
const
{
tr
}
=
state
;
if
(
emoji
)
{
tr
.
replaceWith
(
start
,
end
,
[
state
.
schema
.
text
(
'
'
),
this
.
type
.
create
({
name
,
moji
:
emoji
.
e
,
unicodeVersion
:
emoji
.
u
,
title
:
emoji
.
d
}),
]);
if
(
emoji
)
{
tr
.
replaceWith
(
from
,
to
,
[
state
.
schema
.
text
(
'
'
),
this
.
type
.
create
({
name
,
moji
:
emoji
.
e
,
unicodeVersion
:
emoji
.
u
,
title
:
emoji
.
d
}),
]);
return
tr
;
}
return
tr
;
}
return
null
;
return
null
;
},
}),
];
},
...
...
app/assets/javascripts/content_editor/extensions/horizontal_rule.js
View file @
eee97b89
import
{
nodeInputRule
}
from
'
@tiptap/core
'
;
import
{
HorizontalRule
}
from
'
@tiptap/extension-horizontal-rule
'
;
export
const
hrInputRuleRegExp
=
/^---$/
;
export
default
HorizontalRule
.
extend
({
addInputRules
()
{
return
[
nodeInputRule
(
hrInputRuleRegExp
,
this
.
type
)];
const
hrInputRuleRegExp
=
/^---$/
;
return
[
nodeInputRule
({
find
:
hrInputRuleRegExp
,
type
:
this
.
type
})];
},
});
app/assets/javascripts/content_editor/extensions/html_marks.js
View file @
eee97b89
...
...
@@ -60,7 +60,13 @@ export default marks.map((name) =>
},
addInputRules
()
{
return
[
markInputRule
(
markInputRegex
(
name
),
this
.
type
,
extractMarkAttributesFromMatch
)];
return
[
markInputRule
({
find
:
markInputRegex
(
name
),
type
:
this
.
type
,
getAttributes
:
extractMarkAttributesFromMatch
,
}),
];
},
}),
);
app/assets/javascripts/content_editor/extensions/inline_diff.js
View file @
eee97b89
import
{
Mark
,
markInputRule
,
mergeAttributes
}
from
'
@tiptap/core
'
;
export
const
inputRegexAddition
=
/
(\{\+(
.+
?)\+\})
$/gm
;
export
const
inputRegexDeletion
=
/
(\{
-
(
.+
?)
-
\})
$/gm
;
export
default
Mark
.
create
({
name
:
'
inlineDiff
'
,
...
...
@@ -38,9 +35,20 @@ export default Mark.create({
},
addInputRules
()
{
const
inputRegexAddition
=
/
(\{\+(
.+
?)\+\})
$/gm
;
const
inputRegexDeletion
=
/
(\{
-
(
.+
?)
-
\})
$/gm
;
return
[
markInputRule
(
inputRegexAddition
,
this
.
type
,
()
=>
({
type
:
'
addition
'
})),
markInputRule
(
inputRegexDeletion
,
this
.
type
,
()
=>
({
type
:
'
deletion
'
})),
markInputRule
({
find
:
inputRegexAddition
,
type
:
this
.
type
,
getAttributes
:
()
=>
({
type
:
'
addition
'
}),
}),
markInputRule
({
find
:
inputRegexDeletion
,
type
:
this
.
type
,
getAttributes
:
()
=>
({
type
:
'
deletion
'
}),
}),
];
},
});
app/assets/javascripts/content_editor/extensions/link.js
View file @
eee97b89
import
{
markInputRule
}
from
'
@tiptap/core
'
;
import
{
Link
}
from
'
@tiptap/extension-link
'
;
export
const
markdownLinkSyntaxInputRuleRegExp
=
/
(?:
^|
\s)\[([\w
|
\s
|-
]
+
)\]\((?<
href>.+
?)\)
$/gm
;
export
const
urlSyntaxRegExp
=
/
(?:
^|
\s)(?<
href>
(?:
https
?
:
\/\/
|www
\.)[\S]
+
)(?:\s
|
\n)
$/gim
;
const
extractHrefFromMatch
=
(
match
)
=>
{
return
{
href
:
match
.
groups
.
href
};
};
...
...
@@ -26,9 +23,20 @@ export default Link.extend({
openOnClick
:
false
,
},
addInputRules
()
{
const
markdownLinkSyntaxInputRuleRegExp
=
/
(?:
^|
\s)\[([\w
|
\s
|-
]
+
)\]\((?<
href>.+
?)\)
$/gm
;
const
urlSyntaxRegExp
=
/
(?:
^|
\s)(?<
href>
(?:
https
?
:
\/\/
|www
\.)[\S]
+
)(?:\s
|
\n)
$/gim
;
return
[
markInputRule
(
markdownLinkSyntaxInputRuleRegExp
,
this
.
type
,
extractHrefFromMarkdownLink
),
markInputRule
(
urlSyntaxRegExp
,
this
.
type
,
extractHrefFromMatch
),
markInputRule
({
find
:
markdownLinkSyntaxInputRuleRegExp
,
type
:
this
.
type
,
getAttributes
:
extractHrefFromMarkdownLink
,
}),
markInputRule
({
find
:
urlSyntaxRegExp
,
type
:
this
.
type
,
getAttributes
:
extractHrefFromMatch
,
}),
];
},
addAttributes
()
{
...
...
app/assets/javascripts/content_editor/extensions/math_inline.js
View file @
eee97b89
...
...
@@ -2,8 +2,6 @@ import { Mark, markInputRule } from '@tiptap/core';
import
{
__
}
from
'
~/locale
'
;
import
{
PARSE_HTML_PRIORITY_HIGHEST
}
from
'
../constants
'
;
export
const
inputRegex
=
/
(?:
^|
\s)\$
`
([^
`
]
+
)
`
\$
$/gm
;
export
default
Mark
.
create
({
name
:
'
mathInline
'
,
...
...
@@ -30,6 +28,8 @@ export default Mark.create({
},
addInputRules
()
{
return
[
markInputRule
(
inputRegex
,
this
.
type
)];
const
inputRegex
=
/
(?:
^|
\s)\$
`
([^
`
]
+
)
`
\$
$/gm
;
return
[
markInputRule
({
find
:
inputRegex
,
type
:
this
.
type
})];
},
});
app/assets/javascripts/content_editor/extensions/subscript.js
View file @
eee97b89
...
...
@@ -4,6 +4,12 @@ import { markInputRegex, extractMarkAttributesFromMatch } from '../services/mark
export
default
Subscript
.
extend
({
addInputRules
()
{
return
[
markInputRule
(
markInputRegex
(
'
sub
'
),
this
.
type
,
extractMarkAttributesFromMatch
)];
return
[
markInputRule
({
find
:
markInputRegex
(
'
sub
'
),
type
:
this
.
type
,
getAttributes
:
extractMarkAttributesFromMatch
,
}),
];
},
});
app/assets/javascripts/content_editor/extensions/superscript.js
View file @
eee97b89
...
...
@@ -4,6 +4,12 @@ import { markInputRegex, extractMarkAttributesFromMatch } from '../services/mark
export
default
Superscript
.
extend
({
addInputRules
()
{
return
[
markInputRule
(
markInputRegex
(
'
sup
'
),
this
.
type
,
extractMarkAttributesFromMatch
)];
return
[
markInputRule
({
find
:
markInputRegex
(
'
sup
'
),
type
:
this
.
type
,
getAttributes
:
extractMarkAttributesFromMatch
,
}),
];
},
});
app/assets/javascripts/content_editor/extensions/table_of_contents.js
View file @
eee97b89
import
{
Node
}
from
'
@tiptap/core
'
;
import
{
InputRule
}
from
'
prosemirror-inputrules
'
;
import
{
Node
,
InputRule
}
from
'
@tiptap/core
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
PARSE_HTML_PRIORITY_HIGHEST
}
from
'
../constants
'
;
export
const
inputRuleRegExps
=
[
/^
\[\[
_TOC_
\]\]
$/
,
/^
\[
TOC
\]
$/
];
export
default
Node
.
create
({
name
:
'
tableOfContents
'
,
...
...
@@ -34,17 +31,21 @@ export default Node.create({
addInputRules
()
{
const
{
type
}
=
this
;
const
inputRuleRegExps
=
[
/^
\[\[
_TOC_
\]\]
$/
,
/^
\[
TOC
\]
$/
];
return
inputRuleRegExps
.
map
(
(
regex
)
=>
new
InputRule
(
regex
,
(
state
,
match
,
start
,
end
)
=>
{
const
{
tr
}
=
state
;
new
InputRule
({
find
:
regex
,
handler
:
({
state
,
range
:
{
from
,
to
},
match
})
=>
{
const
{
tr
}
=
state
;
if
(
match
)
{
tr
.
replaceWith
(
start
-
1
,
end
,
type
.
create
());
}
if
(
match
)
{
tr
.
replaceWith
(
from
-
1
,
to
,
type
.
create
());
}
return
tr
;
return
tr
;
},
}),
);
},
...
...
app/assets/javascripts/content_editor/extensions/word_break.js
View file @
eee97b89
import
{
Node
,
mergeAttributes
,
nodeInputRule
}
from
'
@tiptap/core
'
;
export
const
inputRegex
=
/^<wbr>$/
;
export
default
Node
.
create
({
name
:
'
wordBreak
'
,
inline
:
true
,
...
...
@@ -24,6 +22,8 @@ export default Node.create({
},
addInputRules
()
{
return
[
nodeInputRule
(
inputRegex
,
this
.
type
)];
const
inputRegex
=
/^<wbr>$/
;
return
[
nodeInputRule
({
find
:
inputRegex
,
type
:
this
.
type
})];
},
});
app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
View file @
eee97b89
import
{
mapValues
}
from
'
lodash
'
;
import
{
InputRule
}
from
'
prosemirror-inputrules
'
;
import
{
InputRule
}
from
'
@tiptap/core
'
;
import
{
ENTER_KEY
,
BACKSPACE_KEY
}
from
'
~/lib/utils/keys
'
;
import
Tracking
from
'
~/tracking
'
;
import
{
...
...
@@ -17,17 +17,20 @@ const trackKeyboardShortcut = (contentType, commandFn, shortcut) => () => {
};
const
trackInputRule
=
(
contentType
,
inputRule
)
=>
{
return
new
InputRule
(
inputRule
.
match
,
(...
args
)
=>
{
const
result
=
inputRule
.
handler
(...
args
);
return
new
InputRule
({
find
:
inputRule
.
find
,
handler
:
(...
args
)
=>
{
const
result
=
inputRule
.
handler
(...
args
);
if
(
result
)
{
Tracking
.
event
(
undefined
,
INPUT_RULE_TRACKING_ACTION
,
{
label
:
CONTENT_EDITOR_TRACKING_LABEL
,
property
:
contentType
,
});
}
if
(
result
!==
null
)
{
Tracking
.
event
(
undefined
,
INPUT_RULE_TRACKING_ACTION
,
{
label
:
CONTENT_EDITOR_TRACKING_LABEL
,
property
:
contentType
,
});
}
return
result
;
return
result
;
},
});
};
...
...
package.json
View file @
eee97b89
...
...
@@ -63,36 +63,36 @@
"
@rails/ujs
"
:
"
6.1.4-1
"
,
"
@sentry/browser
"
:
"
5.30.0
"
,
"
@sourcegraph/code-host-integration
"
:
"
0.0.60
"
,
"
@tiptap/core
"
:
"
^2.0.0-beta.1
18
"
,
"
@tiptap/extension-blockquote
"
:
"
^2.0.0-beta.1
5
"
,
"
@tiptap/extension-bold
"
:
"
^2.0.0-beta.1
5
"
,
"
@tiptap/extension-bullet-list
"
:
"
^2.0.0-beta.1
5
"
,
"
@tiptap/extension-code
"
:
"
^2.0.0-beta.
16
"
,
"
@tiptap/extension-code-block-lowlight
"
:
"
2.0.0-beta.4
1
"
,
"
@tiptap/core
"
:
"
^2.0.0-beta.1
25
"
,
"
@tiptap/extension-blockquote
"
:
"
^2.0.0-beta.1
9
"
,
"
@tiptap/extension-bold
"
:
"
^2.0.0-beta.1
9
"
,
"
@tiptap/extension-bullet-list
"
:
"
^2.0.0-beta.1
8
"
,
"
@tiptap/extension-code
"
:
"
^2.0.0-beta.
20
"
,
"
@tiptap/extension-code-block-lowlight
"
:
"
2.0.0-beta.4
7
"
,
"
@tiptap/extension-document
"
:
"
^2.0.0-beta.13
"
,
"
@tiptap/extension-dropcursor
"
:
"
^2.0.0-beta.19
"
,
"
@tiptap/extension-gapcursor
"
:
"
^2.0.0-beta.2
4
"
,
"
@tiptap/extension-hard-break
"
:
"
^2.0.0-beta.2
1
"
,
"
@tiptap/extension-heading
"
:
"
^2.0.0-beta.1
5
"
,
"
@tiptap/extension-gapcursor
"
:
"
^2.0.0-beta.2
7
"
,
"
@tiptap/extension-hard-break
"
:
"
^2.0.0-beta.2
4
"
,
"
@tiptap/extension-heading
"
:
"
^2.0.0-beta.1
8
"
,
"
@tiptap/extension-history
"
:
"
^2.0.0-beta.16
"
,
"
@tiptap/extension-horizontal-rule
"
:
"
^2.0.0-beta.2
1
"
,
"
@tiptap/extension-image
"
:
"
^2.0.0-beta.1
5
"
,
"
@tiptap/extension-italic
"
:
"
^2.0.0-beta.1
5
"
,
"
@tiptap/extension-link
"
:
"
^2.0.0-beta.2
0
"
,
"
@tiptap/extension-horizontal-rule
"
:
"
^2.0.0-beta.2
4
"
,
"
@tiptap/extension-image
"
:
"
^2.0.0-beta.1
9
"
,
"
@tiptap/extension-italic
"
:
"
^2.0.0-beta.1
9
"
,
"
@tiptap/extension-link
"
:
"
^2.0.0-beta.2
3
"
,
"
@tiptap/extension-list-item
"
:
"
^2.0.0-beta.14
"
,
"
@tiptap/extension-ordered-list
"
:
"
^2.0.0-beta.1
6
"
,
"
@tiptap/extension-ordered-list
"
:
"
^2.0.0-beta.1
9
"
,
"
@tiptap/extension-paragraph
"
:
"
^2.0.0-beta.17
"
,
"
@tiptap/extension-strike
"
:
"
^2.0.0-beta.
17
"
,
"
@tiptap/extension-strike
"
:
"
^2.0.0-beta.
21
"
,
"
@tiptap/extension-subscript
"
:
"
^2.0.0-beta.4
"
,
"
@tiptap/extension-superscript
"
:
"
^2.0.0-beta.4
"
,
"
@tiptap/extension-table
"
:
"
^2.0.0-beta.3
1
"
,
"
@tiptap/extension-table
"
:
"
^2.0.0-beta.3
4
"
,
"
@tiptap/extension-table-cell
"
:
"
^2.0.0-beta.15
"
,
"
@tiptap/extension-table-header
"
:
"
^2.0.0-beta.17
"
,
"
@tiptap/extension-table-row
"
:
"
^2.0.0-beta.14
"
,
"
@tiptap/extension-task-item
"
:
"
^2.0.0-beta.
18
"
,
"
@tiptap/extension-task-list
"
:
"
^2.0.0-beta.1
7
"
,
"
@tiptap/extension-task-item
"
:
"
^2.0.0-beta.
21
"
,
"
@tiptap/extension-task-list
"
:
"
^2.0.0-beta.1
8
"
,
"
@tiptap/extension-text
"
:
"
^2.0.0-beta.13
"
,
"
@tiptap/vue-2
"
:
"
^2.0.0-beta.
57
"
,
"
@tiptap/vue-2
"
:
"
^2.0.0-beta.
60
"
,
"
@toast-ui/editor
"
:
"
^2.5.2
"
,
"
@toast-ui/vue-editor
"
:
"
^2.5.2
"
,
"
apollo-cache-inmemory
"
:
"
^1.6.6
"
,
...
...
@@ -159,12 +159,11 @@
"
popper.js
"
:
"
^1.16.1
"
,
"
portal-vue
"
:
"
^2.1.7
"
,
"
prismjs
"
:
"
^1.21.0
"
,
"
prosemirror-inputrules
"
:
"
^1.1.3
"
,
"
prosemirror-markdown
"
:
"
^1.6.0
"
,
"
prosemirror-model
"
:
"
^1.14.3
"
,
"
prosemirror-state
"
:
"
^1.3.4
"
,
"
prosemirror-tables
"
:
"
^1.1.1
"
,
"
prosemirror-view
"
:
"
^1.20.
2
"
,
"
prosemirror-view
"
:
"
^1.20.
3
"
,
"
raphael
"
:
"
^2.2.7
"
,
"
raw-loader
"
:
"
^4.0.2
"
,
"
scrollparent
"
:
"
^2.0.1
"
,
...
...
@@ -246,7 +245,7 @@
"
prettier
"
:
"
2.2.1
"
,
"
prosemirror-schema-basic
"
:
"
^1.1.2
"
,
"
prosemirror-schema-list
"
:
"
^1.1.6
"
,
"
prosemirror-test-builder
"
:
"
^1.0.
4
"
,
"
prosemirror-test-builder
"
:
"
^1.0.
5
"
,
"
purgecss
"
:
"
^4.0.3
"
,
"
purgecss-from-html
"
:
"
^4.0.3
"
,
"
readdir-enhanced
"
:
"
^2.2.4
"
,
...
...
spec/frontend/content_editor/extensions/attachment_spec.js
View file @
eee97b89
...
...
@@ -74,10 +74,10 @@ describe('content_editor/extensions/attachment', () => {
});
it
.
each
`
eventType | propName | eventData | output
${
'
paste
'
}
|
${
'
handlePaste
'
}
|
${{
clipboardData
:
{
files
:
[
attachmentFile
]
}
}} |
${
true
}
${
'
paste
'
}
|
${
'
handlePaste
'
}
|
${{
clipboardData
:
{
files
:
[]
}
}} |
${
undefined
}
${
'
drop
'
}
|
${
'
handleDrop
'
}
|
${{
dataTransfer
:
{
files
:
[
attachmentFile
]
}
}} |
${
true
}
eventType | propName | eventData
| output
${
'
paste
'
}
|
${
'
handlePaste
'
}
|
${{
clipboardData
:
{
getData
:
jest
.
fn
(),
files
:
[
attachmentFile
]
}
}} |
${
true
}
${
'
paste
'
}
|
${
'
handlePaste
'
}
|
${{
clipboardData
:
{
getData
:
jest
.
fn
(),
files
:
[]
}
}} |
${
undefined
}
${
'
drop
'
}
|
${
'
handleDrop
'
}
|
${{
dataTransfer
:
{
getData
:
jest
.
fn
(),
files
:
[
attachmentFile
]
}
}} |
${
true
}
`
(
'
handles $eventType properly
'
,
({
eventType
,
propName
,
eventData
,
output
})
=>
{
const
event
=
Object
.
assign
(
new
Event
(
eventType
),
eventData
);
const
handled
=
tiptapEditor
.
view
.
someProp
(
propName
,
(
eventHandler
)
=>
{
...
...
spec/frontend/content_editor/extensions/blockquote_spec.js
View file @
eee97b89
import
{
multilineInputRegex
}
from
'
~/content_editor/extensions/blockquote
'
;
import
Blockquote
from
'
~/content_editor/extensions/blockquote
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerNodeInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/blockquote
'
,
()
=>
{
describe
.
each
`
input | matches
${
'
>>>
'
}
|
${
true
}
${
'
>>>
'
}
|
${
true
}
${
'
\t
>>>
'
}
|
${
true
}
${
'
>>
'
}
|
${
false
}
${
'
>>>x
'
}
|
${
false
}
${
'
>
'
}
|
${
false
}
`
(
'
multilineInputRegex
'
,
({
input
,
matches
})
=>
{
it
(
`
${
matches
?
'
matches
'
:
'
does not match
'
}
: "
${
input
}
"`
,
()
=>
{
const
match
=
new
RegExp
(
multilineInputRegex
).
test
(
input
);
let
tiptapEditor
;
let
doc
;
let
p
;
let
blockquote
;
expect
(
match
).
toBe
(
matches
);
});
beforeEach
(()
=>
{
tiptapEditor
=
createTestEditor
({
extensions
:
[
Blockquote
]
});
({
builders
:
{
doc
,
p
,
blockquote
},
}
=
createDocBuilder
({
tiptapEditor
,
names
:
{
blockquote
:
{
nodeType
:
Blockquote
.
name
},
},
}));
});
it
.
each
`
input | insertedNode
${
'
>>>
'
}
|
${()
=>
blockquote
({
multiline
:
true
},
p
())}
${
'
>
'
}
|
${()
=>
blockquote
(
p
())}
${
'
>>>
'
}
|
${()
=>
blockquote
({
multiline
:
true
},
p
())}
${
'
>>
'
}
|
${()
=>
p
()}
${
'
>>>x
'
}
|
${()
=>
p
()}
`
(
'
with input=$input, then should insert a $insertedNode
'
,
({
input
,
insertedNode
})
=>
{
const
expectedDoc
=
doc
(
insertedNode
());
triggerNodeInputRule
({
tiptapEditor
,
inputRuleText
:
input
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
});
spec/frontend/content_editor/extensions/emoji_spec.js
View file @
eee97b89
import
{
initEmojiMock
}
from
'
helpers/emoji
'
;
import
Emoji
from
'
~/content_editor/extensions/emoji
'
;
import
{
createTestEditor
,
createDocBuilder
}
from
'
../test_utils
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerNodeInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/emoji
'
,
()
=>
{
let
tiptapEditor
;
...
...
@@ -28,18 +28,16 @@ describe('content_editor/extensions/emoji', () => {
describe
(
'
when typing a valid emoji input rule
'
,
()
=>
{
it
(
'
inserts an emoji node
'
,
()
=>
{
const
{
view
}
=
tiptapEditor
;
const
{
selection
}
=
view
.
state
;
const
expectedDoc
=
doc
(
p
(
'
'
,
emoji
({
moji
:
'
❤
'
,
name
:
'
heart
'
,
title
:
'
heavy black heart
'
,
unicodeVersion
:
'
1.1
'
}),
),
);
// Triggers the event handler that input rules listen to
view
.
someProp
(
'
handleTextInput
'
,
(
f
)
=>
f
(
view
,
selection
.
from
,
selection
.
to
,
'
:heart:
'
));
expect
(
eq
(
tiptapEditor
.
state
.
doc
,
expectedDoc
)).
toBe
(
true
);
triggerNodeInputRule
({
tiptapEditor
,
inputRuleText
:
'
:heart:
'
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
});
...
...
spec/frontend/content_editor/extensions/horizontal_rule_spec.js
View file @
eee97b89
import
{
hrInputRuleRegExp
}
from
'
~/content_editor/extensions/horizontal_rule
'
;
import
HorizontalRule
from
'
~/content_editor/extensions/horizontal_rule
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerNodeInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/horizontal_rule
'
,
()
=>
{
describe
.
each
`
input | matches
${
'
---
'
}
|
${
true
}
${
'
--
'
}
|
${
false
}
${
'
---x
'
}
|
${
false
}
${
'
---x
'
}
|
${
false
}
${
'
---
'
}
|
${
false
}
${
'
x---x
'
}
|
${
false
}
${
'
x---
'
}
|
${
false
}
`
(
'
hrInputRuleRegExp
'
,
({
input
,
matches
})
=>
{
it
(
`
${
matches
?
'
matches
'
:
'
does not match
'
}
: "
${
input
}
"`
,
()
=>
{
const
match
=
new
RegExp
(
hrInputRuleRegExp
).
test
(
input
);
let
tiptapEditor
;
let
doc
;
let
p
;
let
horizontalRule
;
expect
(
match
).
toBe
(
matches
);
});
beforeEach
(()
=>
{
tiptapEditor
=
createTestEditor
({
extensions
:
[
HorizontalRule
]
});
({
builders
:
{
doc
,
p
,
horizontalRule
},
}
=
createDocBuilder
({
tiptapEditor
,
names
:
{
horizontalRule
:
{
nodeType
:
HorizontalRule
.
name
},
},
}));
});
it
.
each
`
input | insertedNodes
${
'
---
'
}
|
${()
=>
[
p
(),
horizontalRule
()]}
${
'
--
'
}
|
${()
=>
[
p
()]}
${
'
---x
'
}
|
${()
=>
[
p
()]}
${
'
---x
'
}
|
${()
=>
[
p
()]}
${
'
---
'
}
|
${()
=>
[
p
()]}
${
'
x---x
'
}
|
${()
=>
[
p
()]}
${
'
x---
'
}
|
${()
=>
[
p
()]}
`
(
'
with input=$input, then should insert a $insertedNode
'
,
({
input
,
insertedNodes
})
=>
{
const
expectedDoc
=
doc
(...
insertedNodes
());
triggerNodeInputRule
({
tiptapEditor
,
inputRuleText
:
input
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
});
spec/frontend/content_editor/extensions/inline_diff_spec.js
View file @
eee97b89
import
{
inputRegexAddition
,
inputRegexDeletion
}
from
'
~/content_editor/extensions/inline_diff
'
;
import
InlineDiff
from
'
~/content_editor/extensions/inline_diff
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerMarkInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/inline_diff
'
,
()
=>
{
describe
.
each
`
inputRegex | description | input | matches
${
inputRegexAddition
}
|
${
'
inputRegexAddition
'
}
|
${
'
hello{+world+}
'
}
|
${
true
}
${
inputRegexAddition
}
|
${
'
inputRegexAddition
'
}
|
${
'
hello{+ world +}
'
}
|
${
true
}
${
inputRegexAddition
}
|
${
'
inputRegexAddition
'
}
|
${
'
hello {+ world+}
'
}
|
${
true
}
${
inputRegexAddition
}
|
${
'
inputRegexAddition
'
}
|
${
'
{+hello world +}
'
}
|
${
true
}
${
inputRegexAddition
}
|
${
'
inputRegexAddition
'
}
|
${
'
{+hello with
\n
newline+}
'
}
|
${
false
}
${
inputRegexAddition
}
|
${
'
inputRegexAddition
'
}
|
${
'
{+open only
'
}
|
${
false
}
${
inputRegexAddition
}
|
${
'
inputRegexAddition
'
}
|
${
'
close only+}
'
}
|
${
false
}
${
inputRegexDeletion
}
|
${
'
inputRegexDeletion
'
}
|
${
'
hello{-world-}
'
}
|
${
true
}
${
inputRegexDeletion
}
|
${
'
inputRegexDeletion
'
}
|
${
'
hello{- world -}
'
}
|
${
true
}
${
inputRegexDeletion
}
|
${
'
inputRegexDeletion
'
}
|
${
'
hello {- world-}
'
}
|
${
true
}
${
inputRegexDeletion
}
|
${
'
inputRegexDeletion
'
}
|
${
'
{-hello world -}
'
}
|
${
true
}
${
inputRegexDeletion
}
|
${
'
inputRegexDeletion
'
}
|
${
'
{+hello with
\n
newline+}
'
}
|
${
false
}
${
inputRegexDeletion
}
|
${
'
inputRegexDeletion
'
}
|
${
'
{-open only
'
}
|
${
false
}
${
inputRegexDeletion
}
|
${
'
inputRegexDeletion
'
}
|
${
'
close only-}
'
}
|
${
false
}
`
(
'
$description
'
,
({
inputRegex
,
input
,
matches
})
=>
{
it
(
`
${
matches
?
'
matches
'
:
'
does not match
'
}
: "
${
input
}
"`
,
()
=>
{
const
match
=
new
RegExp
(
inputRegex
).
test
(
input
);
let
tiptapEditor
;
let
doc
;
let
p
;
let
inlineDiff
;
expect
(
match
).
toBe
(
matches
);
});
beforeEach
(()
=>
{
tiptapEditor
=
createTestEditor
({
extensions
:
[
InlineDiff
]
});
({
builders
:
{
doc
,
p
,
inlineDiff
},
}
=
createDocBuilder
({
tiptapEditor
,
names
:
{
inlineDiff
:
{
markType
:
InlineDiff
.
name
},
},
}));
});
it
.
each
`
input | insertedNode
${
'
hello{+world+}
'
}
|
${()
=>
p
(
'
hello
'
,
inlineDiff
(
'
world
'
))}
${
'
hello{+ world +}
'
}
|
${()
=>
p
(
'
hello
'
,
inlineDiff
(
'
world
'
))}
${
'
{+hello with
\n
newline+}
'
}
|
${()
=>
p
(
'
{+hello with newline+}
'
)}
${
'
{+open only
'
}
|
${()
=>
p
(
'
{+open only
'
)}
${
'
close only+}
'
}
|
${()
=>
p
(
'
close only+}
'
)}
${
'
hello{-world-}
'
}
|
${()
=>
p
(
'
hello
'
,
inlineDiff
({
type
:
'
deletion
'
},
'
world
'
))}
${
'
hello{- world -}
'
}
|
${()
=>
p
(
'
hello
'
,
inlineDiff
({
type
:
'
deletion
'
},
'
world
'
))}
${
'
hello {- world-}
'
}
|
${()
=>
p
(
'
hello
'
,
inlineDiff
({
type
:
'
deletion
'
},
'
world
'
))}
${
'
{-hello world -}
'
}
|
${()
=>
p
(
inlineDiff
({
type
:
'
deletion
'
},
'
hello world
'
))}
${
'
{-hello with
\n
newline-}
'
}
|
${()
=>
p
(
'
{-hello with newline-}
'
)}
${
'
{-open only
'
}
|
${()
=>
p
(
'
{-open only
'
)}
${
'
close only-}
'
}
|
${()
=>
p
(
'
close only-}
'
)}
`
(
'
with input=$input, then should insert a $insertedNode
'
,
({
input
,
insertedNode
})
=>
{
const
expectedDoc
=
doc
(
insertedNode
());
triggerMarkInputRule
({
tiptapEditor
,
inputRuleText
:
input
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
});
spec/frontend/content_editor/extensions/link_spec.js
View file @
eee97b89
import
{
markdownLinkSyntaxInputRuleRegExp
,
urlSyntaxRegExp
,
extractHrefFromMarkdownLink
,
}
from
'
~/content_editor/extensions/link
'
;
import
Link
from
'
~/content_editor/extensions/link
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerMarkInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/link
'
,
()
=>
{
describe
.
each
`
input | matches
${
'
[gitlab](https://gitlab.com)
'
}
|
${
true
}
${
'
[documentation](readme.md)
'
}
|
${
true
}
${
'
[link 123](readme.md)
'
}
|
${
true
}
${
'
[link 123](read me.md)
'
}
|
${
true
}
${
'
text
'
}
|
${
false
}
${
'
documentation](readme.md
'
}
|
${
false
}
${
'
https://www.google.com
'
}
|
${
false
}
`
(
'
markdownLinkSyntaxInputRuleRegExp
'
,
({
input
,
matches
})
=>
{
it
(
`
${
matches
?
'
matches
'
:
'
does not match
'
}
${
input
}
`
,
()
=>
{
const
match
=
new
RegExp
(
markdownLinkSyntaxInputRuleRegExp
).
exec
(
input
);
expect
(
Boolean
(
match
?.
groups
.
href
)).
toBe
(
matches
);
});
let
tiptapEditor
;
let
doc
;
let
p
;
let
link
;
beforeEach
(()
=>
{
tiptapEditor
=
createTestEditor
({
extensions
:
[
Link
]
});
({
builders
:
{
doc
,
p
,
link
},
}
=
createDocBuilder
(
{
tiptapEditor
,
names
:
{
link
:
{
markType
:
Link
.
name
},
},
})
)
;
});
describe
.
each
`
input | matches
${
'
http://example.com
'
}
|
${
true
}
${
'
https://example.com
'
}
|
${
true
}
${
'
www.example.com
'
}
|
${
true
}
${
'
example.com/ab.html
'
}
|
${
false
}
${
'
text
'
}
|
${
false
}
${
'
http://example.com
'
}
|
${
true
}
${
'
https://www.google.com
'
}
|
${
true
}
`
(
'
urlSyntaxRegExp
'
,
({
input
,
matches
})
=>
{
it
(
`
${
matches
?
'
matches
'
:
'
does not match
'
}
${
input
}
`
,
()
=>
{
const
match
=
new
RegExp
(
urlSyntaxRegExp
).
exec
(
input
);
expect
(
Boolean
(
match
?.
groups
.
href
)).
toBe
(
matches
);
});
afterEach
(()
=>
{
tiptapEditor
.
destroy
();
});
describe
(
'
extractHrefFromMarkdownLink
'
,
()
=>
{
const
input
=
'
[gitlab](https://gitlab.com)
'
;
const
href
=
'
https://gitlab.com
'
;
let
match
;
let
result
;
beforeEach
(()
=>
{
match
=
new
RegExp
(
markdownLinkSyntaxInputRuleRegExp
).
exec
(
input
);
result
=
extractHrefFromMarkdownLink
(
match
);
});
it
(
'
extracts the url from a markdown link captured by markdownLinkSyntaxInputRuleRegExp
'
,
()
=>
{
expect
(
result
).
toEqual
({
href
});
});
it
(
'
makes sure that url text is the last capture group
'
,
()
=>
{
expect
(
match
[
match
.
length
-
1
]).
toEqual
(
'
gitlab
'
);
});
it
.
each
`
input | insertedNode
${
'
[gitlab](https://gitlab.com)
'
}
|
${()
=>
p
(
link
({
href
:
'
https://gitlab.com
'
},
'
gitlab
'
))}
${
'
[documentation](readme.md)
'
}
|
${()
=>
p
(
link
({
href
:
'
readme.md
'
},
'
documentation
'
))}
${
'
[link 123](readme.md)
'
}
|
${()
=>
p
(
link
({
href
:
'
readme.md
'
},
'
link 123
'
))}
${
'
[link 123](read me.md)
'
}
|
${()
=>
p
(
link
({
href
:
'
read me.md
'
},
'
link 123
'
))}
${
'
text
'
}
|
${()
=>
p
(
'
text
'
)}
${
'
documentation](readme.md
'
}
|
${()
=>
p
(
'
documentation](readme.md
'
)}
${
'
http://example.com
'
}
|
${()
=>
p
(
link
({
href
:
'
http://example.com
'
},
'
http://example.com
'
))}
${
'
https://example.com
'
}
|
${()
=>
p
(
link
({
href
:
'
https://example.com
'
},
'
https://example.com
'
))}
${
'
www.example.com
'
}
|
${()
=>
p
(
link
({
href
:
'
www.example.com
'
},
'
www.example.com
'
))}
${
'
example.com/ab.html
'
}
|
${()
=>
p
(
'
example.com/ab.html
'
)}
${
'
https://www.google.com
'
}
|
${()
=>
p
(
link
({
href
:
'
https://www.google.com
'
},
'
https://www.google.com
'
))}
`
(
'
with input=$input, then should insert a $insertedNode
'
,
({
input
,
insertedNode
})
=>
{
const
expectedDoc
=
doc
(
insertedNode
());
triggerMarkInputRule
({
tiptapEditor
,
inputRuleText
:
input
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
});
spec/frontend/content_editor/extensions/math_inline_spec.js
View file @
eee97b89
import
MathInline
from
'
~/content_editor/extensions/math_inline
'
;
import
{
createTestEditor
,
createDocBuilder
}
from
'
../test_utils
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerMarkInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/math_inline
'
,
()
=>
{
let
tiptapEditor
;
...
...
@@ -26,16 +26,9 @@ describe('content_editor/extensions/math_inline', () => {
${
'
$`a^2`
'
}
|
${()
=>
p
(
'
$`a^2`
'
)}
${
'
`a^2`$
'
}
|
${()
=>
p
(
'
`a^2`$
'
)}
`
(
'
with input=$input, then should insert a $insertedNode
'
,
({
input
,
insertedNode
})
=>
{
const
{
view
}
=
tiptapEditor
;
const
expectedDoc
=
doc
(
insertedNode
());
tiptapEditor
.
chain
().
setContent
(
input
).
setTextSelection
(
0
).
run
();
const
{
state
}
=
tiptapEditor
;
const
{
selection
}
=
state
;
// Triggers the event handler that input rules listen to
view
.
someProp
(
'
handleTextInput
'
,
(
f
)
=>
f
(
view
,
selection
.
from
,
input
.
length
+
1
,
input
));
triggerMarkInputRule
({
tiptapEditor
,
inputRuleText
:
input
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
...
...
spec/frontend/content_editor/extensions/table_of_contents_spec.js
View file @
eee97b89
import
TableOfContents
from
'
~/content_editor/extensions/table_of_contents
'
;
import
{
createTestEditor
,
createDocBuilder
}
from
'
../test_utils
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerNodeInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/
emoji
'
,
()
=>
{
describe
(
'
content_editor/extensions/
table_of_contents
'
,
()
=>
{
let
tiptapEditor
;
let
builders
;
let
doc
;
let
tableOfContents
;
let
p
;
beforeEach
(()
=>
{
tiptapEditor
=
createTestEditor
({
extensions
:
[
TableOfContents
]
});
({
builders
}
=
createDocBuilder
({
({
builders
:
{
doc
,
p
,
tableOfContents
},
}
=
createDocBuilder
({
tiptapEditor
,
names
:
{
tableOfContents
:
{
nodeType
:
TableOfContents
.
name
}
},
}));
...
...
@@ -15,20 +19,16 @@ describe('content_editor/extensions/emoji', () => {
it
.
each
`
input | insertedNode
${
'
[[_TOC_]]
'
}
|
${
'
tableOfContents
'
}
${
'
[TOC]
'
}
|
${
'
tableOfContents
'
}
${
'
[toc]
'
}
|
${
'
p
'
}
${
'
TOC
'
}
|
${
'
p
'
}
${
'
[_TOC_]
'
}
|
${
'
p
'
}
${
'
[[TOC]]
'
}
|
${
'
p
'
}
${
'
[[_TOC_]]
'
}
|
${
()
=>
tableOfContents
()
}
${
'
[TOC]
'
}
|
${
()
=>
tableOfContents
()
}
${
'
[toc]
'
}
|
${
()
=>
p
()
}
${
'
TOC
'
}
|
${
()
=>
p
()
}
${
'
[_TOC_]
'
}
|
${
()
=>
p
()
}
${
'
[[TOC]]
'
}
|
${
()
=>
p
()
}
`
(
'
with input=$input, then should insert a $insertedNode
'
,
({
input
,
insertedNode
})
=>
{
const
{
doc
}
=
builders
;
const
{
view
}
=
tiptapEditor
;
const
{
selection
}
=
view
.
state
;
const
expectedDoc
=
doc
(
builders
[
insertedNode
]());
const
expectedDoc
=
doc
(
insertedNode
());
// Triggers the event handler that input rules listen to
view
.
someProp
(
'
handleTextInput
'
,
(
f
)
=>
f
(
view
,
selection
.
from
,
selection
.
to
,
input
));
triggerNodeInputRule
({
tiptapEditor
,
inputRuleText
:
input
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
...
...
spec/frontend/content_editor/extensions/word_break_spec.js
0 → 100644
View file @
eee97b89
import
WordBreak
from
'
~/content_editor/extensions/word_break
'
;
import
{
createTestEditor
,
createDocBuilder
,
triggerNodeInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/extensions/word_break
'
,
()
=>
{
let
tiptapEditor
;
let
doc
;
let
p
;
let
wordBreak
;
beforeEach
(()
=>
{
tiptapEditor
=
createTestEditor
({
extensions
:
[
WordBreak
]
});
({
builders
:
{
doc
,
p
,
wordBreak
},
}
=
createDocBuilder
({
tiptapEditor
,
names
:
{
wordBreak
:
{
nodeType
:
WordBreak
.
name
},
},
}));
});
it
.
each
`
input | insertedNode
${
'
<wbr>
'
}
|
${()
=>
p
(
wordBreak
())}
${
'
<wbr
'
}
|
${()
=>
p
()}
${
'
wbr>
'
}
|
${()
=>
p
()}
`
(
'
with input=$input, then should insert a $insertedNode
'
,
({
input
,
insertedNode
})
=>
{
const
expectedDoc
=
doc
(
insertedNode
());
triggerNodeInputRule
({
tiptapEditor
,
inputRuleText
:
input
});
expect
(
tiptapEditor
.
getJSON
()).
toEqual
(
expectedDoc
.
toJSON
());
});
});
spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js
View file @
eee97b89
...
...
@@ -10,7 +10,7 @@ import Heading from '~/content_editor/extensions/heading';
import
ListItem
from
'
~/content_editor/extensions/list_item
'
;
import
trackInputRulesAndShortcuts
from
'
~/content_editor/services/track_input_rules_and_shortcuts
'
;
import
{
ENTER_KEY
,
BACKSPACE_KEY
}
from
'
~/lib/utils/keys
'
;
import
{
createTestEditor
}
from
'
../test_utils
'
;
import
{
createTestEditor
,
triggerNodeInputRule
}
from
'
../test_utils
'
;
describe
(
'
content_editor/services/track_input_rules_and_shortcuts
'
,
()
=>
{
let
trackingSpy
;
...
...
@@ -70,14 +70,7 @@ describe('content_editor/services/track_input_rules_and_shortcuts', () => {
describe
(
'
when creating a heading using an input rule
'
,
()
=>
{
it
(
'
sends a tracking event indicating that a heading was created using an input rule
'
,
async
()
=>
{
const
nodeName
=
Heading
.
name
;
const
{
view
}
=
editor
;
const
{
selection
}
=
view
.
state
;
// Triggers the event handler that input rules listen to
view
.
someProp
(
'
handleTextInput
'
,
(
f
)
=>
f
(
view
,
selection
.
from
,
selection
.
to
,
'
##
'
));
editor
.
chain
().
insertContent
(
HEADING_TEXT
).
run
();
triggerNodeInputRule
({
tiptapEditor
:
editor
,
inputRuleText
:
'
##
'
});
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
undefined
,
INPUT_RULE_TRACKING_ACTION
,
{
label
:
CONTENT_EDITOR_TRACKING_LABEL
,
property
:
`
${
nodeName
}
`
,
...
...
spec/frontend/content_editor/test_utils.js
View file @
eee97b89
...
...
@@ -119,3 +119,26 @@ export const createTestContentEditorExtension = ({ commands = [] } = {}) => {
},
};
};
export
const
triggerNodeInputRule
=
({
tiptapEditor
,
inputRuleText
})
=>
{
const
{
view
}
=
tiptapEditor
;
const
{
state
}
=
tiptapEditor
;
const
{
selection
}
=
state
;
// Triggers the event handler that input rules listen to
view
.
someProp
(
'
handleTextInput
'
,
(
f
)
=>
f
(
view
,
selection
.
from
,
selection
.
to
,
inputRuleText
));
};
export
const
triggerMarkInputRule
=
({
tiptapEditor
,
inputRuleText
})
=>
{
const
{
view
}
=
tiptapEditor
;
tiptapEditor
.
chain
().
setContent
(
inputRuleText
).
setTextSelection
(
0
).
run
();
const
{
state
}
=
tiptapEditor
;
const
{
selection
}
=
state
;
// Triggers the event handler that input rules listen to
view
.
someProp
(
'
handleTextInput
'
,
(
f
)
=>
f
(
view
,
selection
.
from
,
inputRuleText
.
length
+
1
,
inputRuleText
),
);
};
yarn.lock
View file @
eee97b89
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment