Files
react-native-devtools-frontend/node_modules/micromark/lib/tokenize/attention.mjs
T
Tim van der Lippe cc71b28ac4 Update stylelint to 13.10.0
DISABLE_THIRD_PARTY_CHECK=NPM update
R=jacktfranklin@chromium.org

Bug: none
Change-Id: I41b7006f336b9465677cc7434abd70a732c58221
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2692907
Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
2021-02-15 14:11:00 +00:00

208 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var attention = {
name: 'attention',
tokenize: tokenizeAttention,
resolveAll: resolveAllAttention
}
export default attention
import assert from 'assert'
import codes from '../character/codes.mjs'
import constants from '../constant/constants.mjs'
import types from '../constant/types.mjs'
import chunkedPush from '../util/chunked-push.mjs'
import chunkedSplice from '../util/chunked-splice.mjs'
import classifyCharacter from '../util/classify-character.mjs'
import movePoint from '../util/move-point.mjs'
import resolveAll from '../util/resolve-all.mjs'
import shallow from '../util/shallow.mjs'
// Take all events and resolve attention to emphasis or strong.
function resolveAllAttention(events, context) {
var index = -1
var open
var group
var text
var openingSequence
var closingSequence
var use
var nextEvents
var offset
// Walk through all events.
//
// Note: performance of this is fine on an mb of normal markdown, but it’s
// a bottleneck for malicious stuff.
while (++index < events.length) {
// Find a token that can close.
if (
events[index][0] === 'enter' &&
events[index][1].type === 'attentionSequence' &&
events[index][1]._close
) {
open = index
// Now walk back to find an opener.
while (open--) {
// Find a token that can open the closer.
if (
events[open][0] === 'exit' &&
events[open][1].type === 'attentionSequence' &&
events[open][1]._open &&
// If the markers are the same:
context.sliceSerialize(events[open][1]).charCodeAt(0) ===
context.sliceSerialize(events[index][1]).charCodeAt(0)
) {
// If the opening can close or the closing can open,
// and the close size *is not* a multiple of three,
// but the sum of the opening and closing size *is* multiple of three,
// then don’t match.
if (
(events[open][1]._close || events[index][1]._open) &&
(events[index][1].end.offset - events[index][1].start.offset) % 3 &&
!(
(events[open][1].end.offset -
events[open][1].start.offset +
events[index][1].end.offset -
events[index][1].start.offset) %
3
)
) {
continue
}
// Number of markers to use from the sequence.
use =
events[open][1].end.offset - events[open][1].start.offset > 1 &&
events[index][1].end.offset - events[index][1].start.offset > 1
? 2
: 1
openingSequence = {
type: use > 1 ? types.strongSequence : types.emphasisSequence,
start: movePoint(shallow(events[open][1].end), -use),
end: shallow(events[open][1].end)
}
closingSequence = {
type: use > 1 ? types.strongSequence : types.emphasisSequence,
start: shallow(events[index][1].start),
end: movePoint(shallow(events[index][1].start), use)
}
text = {
type: use > 1 ? types.strongText : types.emphasisText,
start: shallow(events[open][1].end),
end: shallow(events[index][1].start)
}
group = {
type: use > 1 ? types.strong : types.emphasis,
start: shallow(openingSequence.start),
end: shallow(closingSequence.end)
}
events[open][1].end = shallow(openingSequence.start)
events[index][1].start = shallow(closingSequence.end)
nextEvents = []
// If there are more markers in the opening, add them before.
if (events[open][1].end.offset - events[open][1].start.offset) {
nextEvents = chunkedPush(nextEvents, [
['enter', events[open][1], context],
['exit', events[open][1], context]
])
}
// Opening.
nextEvents = chunkedPush(nextEvents, [
['enter', group, context],
['enter', openingSequence, context],
['exit', openingSequence, context],
['enter', text, context]
])
// Between.
nextEvents = chunkedPush(
nextEvents,
resolveAll(
context.parser.constructs.insideSpan.null,
events.slice(open + 1, index),
context
)
)
// Closing.
nextEvents = chunkedPush(nextEvents, [
['exit', text, context],
['enter', closingSequence, context],
['exit', closingSequence, context],
['exit', group, context]
])
// If there are more markers in the closing, add them after.
if (events[index][1].end.offset - events[index][1].start.offset) {
offset = 2
nextEvents = chunkedPush(nextEvents, [
['enter', events[index][1], context],
['exit', events[index][1], context]
])
} else {
offset = 0
}
chunkedSplice(events, open - 1, index - open + 3, nextEvents)
index = open + nextEvents.length - offset - 2
break
}
}
}
}
// Remove remaining sequences.
index = -1
while (++index < events.length) {
if (events[index][1].type === 'attentionSequence') {
events[index][1].type = 'data'
}
}
return events
}
function tokenizeAttention(effects, ok) {
var before = classifyCharacter(this.previous)
var marker
return start
function start(code) {
assert(
code === codes.asterisk || code === codes.underscore,
'expected asterisk or underscore'
)
effects.enter('attentionSequence')
marker = code
return sequence(code)
}
function sequence(code) {
var token
var after
var open
var close
if (code === marker) {
effects.consume(code)
return sequence
}
token = effects.exit('attentionSequence')
after = classifyCharacter(code)
open = !after || (after === constants.characterGroupPunctuation && before)
close = !before || (before === constants.characterGroupPunctuation && after)
token._open = marker === codes.asterisk ? open : open && (before || !close)
token._close = marker === codes.asterisk ? close : close && (after || !open)
return ok(code)
}
}