How to use startsWithEndTagOpen method in Playwright Internal

Best JavaScript code snippet using playwright-internal

guild-mini-vue.cjs.js

Source:guild-mini-vue.cjs.js Github

copy

Full Screen

...1127 let s = context.source;1128 if (s.startsWith("</")) {1129 for (let i = ancestors.length - 1; i >= 0; i--) {1130 const tag = ancestors[i].tag;1131 if (startsWithEndTagOpen(s, tag)) {1132 return true;1133 }1134 }1135 }1136 // if(parentTag && s.startsWith(`</${parentTag}>`)){1137 // return true1138 // }1139 return !s;1140}1141function parseInterpolation(context) {1142 // {{message}}1143 // 将变化点几种在一起,保证的代码的可复用性1144 const openDelimiter = "{{";1145 const closeDelimiter = "}}";1146 const closeIndex = context.source.indexOf(closeDelimiter, openDelimiter.length);1147 // console.log('closeIndex', closeIndex);1148 advanceBy(context, openDelimiter.length);1149 const rawContentLength = closeIndex - openDelimiter.length;1150 const rawContent = parseTextData(context, rawContentLength);1151 const content = rawContent.trim();1152 advanceBy(context, closeDelimiter.length);1153 return {1154 type: 0 /* INTERPOLATION */,1155 content: {1156 type: 1 /* SIMPLE_EXPRESSION */,1157 content: content1158 }1159 };1160}1161// advanceBy指针不断前移,不断解析文本的过程1162function advanceBy(context, length) {1163 context.source = context.source.slice(length);1164}1165function createRoot(children) {1166 return {1167 children,1168 type: 4 /* ROOT */1169 };1170}1171function createParserContext(content) {1172 return {1173 source: content1174 };1175}1176function parseElement(context, ancestors) {1177 // 1.解析tag1178 const element = parseTag(context, 0 /* Start */);1179 ancestors.push(element);1180 element.children = parseChildren(context, ancestors);1181 ancestors.pop();1182 // console.log(element.tag);1183 // console.log(context.source);1184 if (startsWithEndTagOpen(context.source, element.tag)) {1185 parseTag(context, 1 /* End */);1186 }1187 else {1188 throw new Error(`缺少结束标签:${element.tag}`);1189 }1190 // console.log('------',context.source)1191 return element;1192}1193function startsWithEndTagOpen(source, tag) {1194 return source.startsWith('</') && source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase();1195}1196function parseTag(context, type) {1197 const match = /^<\/?([a-z]*)/i.exec(context.source);1198 // console.log(match);1199 const tag = match[1];1200 // 2.删除处理完成的代码1201 advanceBy(context, match[0].length);1202 // console.log('parseTag',context.source)1203 advanceBy(context, 1);1204 if (type === 1 /* End */)1205 return;1206 return {1207 type: 2 /* ELEMENT */,...

Full Screen

Full Screen

guide-mini-vue.cjs.js

Source:guide-mini-vue.cjs.js Github

copy

Full Screen

...988 const s = context.source;989 if (s.startsWith("</")) {990 for (let i = ancestors.length - 1; i >= 0; i--) {991 const tag = ancestors[i].tag;992 if (startsWithEndTagOpen(s, tag)) {993 return true;994 }995 }996 }997 return !s;998}999function parseText(context) {1000 let endIndex = context.source.length;1001 let endTokens = ["<", "{{"];1002 for (let i = 0; i < endTokens.length; i++) {1003 const index = context.source.indexOf(endTokens[i]);1004 if (index !== -1 && endIndex > index) {1005 endIndex = index;1006 }1007 }1008 const content = parseTextData(context, endIndex);1009 return {1010 type: 3 /* TEXT */,1011 content,1012 };1013}1014function parseTextData(context, length) {1015 const content = context.source.slice(0, length);1016 advanceBy(context, length);1017 return content;1018}1019function parseElement(context, ancestors) {1020 const element = parseTag(context, 0 /* Start */);1021 ancestors.push(element);1022 element.children = parseChildren(context, ancestors);1023 ancestors.pop();1024 if (startsWithEndTagOpen(context.source, element.tag)) {1025 parseTag(context, 1 /* End */);1026 }1027 else {1028 throw new Error(`缺少结束标签:${element.tag}`);1029 }1030 return element;1031}1032function startsWithEndTagOpen(source, tag) {1033 return (source.startsWith("</") &&1034 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase());1035}1036function parseTag(context, type) {1037 const match = /^<\/?([a-z]*)/i.exec(context.source);1038 const tag = match[1];1039 advanceBy(context, match[0].length);1040 advanceBy(context, 1);1041 if (type === 1 /* End */)1042 return;1043 return {1044 type: 2 /* ELEMENT */,1045 tag,1046 };...

Full Screen

Full Screen

guide-mini-vue.esm.js

Source:guide-mini-vue.esm.js Github

copy

Full Screen

...986 const s = context.source;987 if (s.startsWith("</")) {988 for (let i = ancestors.length - 1; i >= 0; i--) {989 const tag = ancestors[i].tag;990 if (startsWithEndTagOpen(s, tag)) {991 return true;992 }993 }994 }995 return !s;996}997function parseText(context) {998 let endIndex = context.source.length;999 let endTokens = ["<", "{{"];1000 for (let i = 0; i < endTokens.length; i++) {1001 const index = context.source.indexOf(endTokens[i]);1002 if (index !== -1 && endIndex > index) {1003 endIndex = index;1004 }1005 }1006 const content = parseTextData(context, endIndex);1007 return {1008 type: 3 /* TEXT */,1009 content,1010 };1011}1012function parseTextData(context, length) {1013 const content = context.source.slice(0, length);1014 advanceBy(context, length);1015 return content;1016}1017function parseElement(context, ancestors) {1018 const element = parseTag(context, 0 /* Start */);1019 ancestors.push(element);1020 element.children = parseChildren(context, ancestors);1021 ancestors.pop();1022 if (startsWithEndTagOpen(context.source, element.tag)) {1023 parseTag(context, 1 /* End */);1024 }1025 else {1026 throw new Error(`缺少结束标签:${element.tag}`);1027 }1028 return element;1029}1030function startsWithEndTagOpen(source, tag) {1031 return (source.startsWith("</") &&1032 source.slice(2, 2 + tag.length).toLowerCase() === tag.toLowerCase());1033}1034function parseTag(context, type) {1035 const match = /^<\/?([a-z]*)/i.exec(context.source);1036 const tag = match[1];1037 advanceBy(context, match[0].length);1038 advanceBy(context, 1);1039 if (type === 1 /* End */)1040 return;1041 return {1042 type: 2 /* ELEMENT */,1043 tag,1044 };...

Full Screen

Full Screen

parse.simple.js

Source:parse.simple.js Github

copy

Full Screen

...87 case TextModes.DATA:88 if (startsWith(s, '</')) {89 //TODO: probably bad performance90 for (let i = ancestors.length - 1; i >= 0; --i) {91 if (startsWithEndTagOpen(s, ancestors[i].tag)) {92 return true93 }94 }95 }96 break97 case TextModes.RCDATA:98 case TextModes.RAWTEXT: {99 const parent = last(ancestors)100 if (parent && startsWithEndTagOpen(s, parent.tag)) {101 return true102 }103 break104 }105 case TextModes.CDATA:106 if (startsWith(s, ']]>')) {107 return true108 }109 break110 }111 return !s112}113function parseChildren( context, mode, ancestors ) {114 const parent = last(ancestors)115 const ns = parent ? parent.ns : Namespaces.HTML116 const nodes = []117 console.log(1111)118 while (!isEnd(context, mode, ancestors)) {119 120 __DEV__ && assert(context.source.length > 0)121 const s = context.source122 let node = undefined123 if (!context.inPre && startsWith(s, context.options.delimiters[0])) {124 // '{{'125 node = parseInterpolation(context, mode)126 } else if (mode === TextModes.DATA && s[0] === '<') {127 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state128 if (s.length === 1) {129 emitError(context, ErrorCodes.EOF_BEFORE_TAG_NAME, 1)130 } else if (s[1] === '!') {131 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state132 if (startsWith(s, '<!--')) {133 node = parseComment(context)134 } else if (startsWith(s, '<!DOCTYPE')) {135 // Ignore DOCTYPE by a limitation.136 node = parseBogusComment(context)137 } else if (startsWith(s, '<![CDATA[')) {138 if (ns !== Namespaces.HTML) {139 node = parseCDATA(context, ancestors)140 } else {141 emitError(context, ErrorCodes.CDATA_IN_HTML_CONTENT)142 node = parseBogusComment(context)143 }144 } else {145 emitError(context, ErrorCodes.INCORRECTLY_OPENED_COMMENT)146 node = parseBogusComment(context)147 }148 } else if (s[1] === '/') {149 // console.log(99999, s)150 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state151 if (s.length === 2) {152 // console.log(' > 1')153 emitError(context, ErrorCodes.EOF_BEFORE_TAG_NAME, 2)154 } else if (s[2] === '>') {155 // console.log(' > 2')156 emitError(context, ErrorCodes.MISSING_END_TAG_NAME, 2)157 advanceBy(context, 3)158 continue159 } else if (/[a-z]/i.test(s[2])) {160 // console.log(' > 3')161 emitError(context, ErrorCodes.X_INVALID_END_TAG)162 parseTag(context, TagType.End, parent)163 continue164 } else {165 // console.log(' > 4')166 emitError(context, ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME, 2)167 node = parseBogusComment(context)168 }169 } else if (/[a-z]/i.test(s[1])) {170 node = parseElement(context, ancestors)171 } else if (s[1] === '?') {172 emitError(173 context,174 ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME,175 1176 )177 node = parseBogusComment(context)178 } else {179 emitError(context, ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME, 1)180 }181 }182 if (!node) {183 node = parseText(context, mode)184 }185 if (Array.isArray(node)) {186 for (let i = 0; i < node.length; i++) {187 pushNode(nodes, node[i])188 }189 } else {190 pushNode(nodes, node)191 }192 }193 // Whitespace management for more efficient output194 // 这里是对一些空白节点的过滤195 // (same as v2 whitespance: 'condense')196 let removedWhitespace = false197 if (!parent || !context.options.isPreTag(parent.tag)) {198 for (let i = 0; i < nodes.length; i++) {199 const node = nodes[i]200 if (node.type === NodeTypes.TEXT) {201 if (!node.content.trim()) {202 const prev = nodes[i - 1]203 const next = nodes[i + 1]204 // If:205 // - the whitespace is the first or last node, or:206 // - the whitespace is adjacent to a comment, or:207 // - the whitespace is between two elements AND contains newline208 // Then the whitespace is ignored.209 if (210 !prev ||211 !next ||212 prev.type === NodeTypes.COMMENT ||213 next.type === NodeTypes.COMMENT ||214 (prev.type === NodeTypes.ELEMENT &&215 next.type === NodeTypes.ELEMENT &&216 /[\r\n]/.test(node.content))217 ) {218 removedWhitespace = true219 nodes[i] = null220 } else {221 // Otherwise, condensed consecutive whitespace inside the text down to222 // a single space223 node.content = ' '224 }225 } else {226 node.content = node.content.replace(/\s+/g, ' ')227 }228 }229 }230 }231 return removedWhitespace ? nodes.filter(node => node !== null) : nodes232}233function parseText(context, mode) {234 __DEV__ && assert(context.source.length > 0)235 const [open] = context.options.delimiters236 // TODO could probably use some perf optimization237 const endIndex = Math.min(238 ...[239 context.source.indexOf('<', 1),240 context.source.indexOf(open, 1),241 mode === TextModes.CDATA ? context.source.indexOf(']]>') : -1,242 context.source.length243 ].filter(n => n !== -1)244 )245 __DEV__ && assert(endIndex > 0)246 const start = getCursor(context)247 const content = parseTextData(context, endIndex, mode)248 return {249 type: NodeTypes.TEXT,250 content,251 loc: getSelection(context, start)252 }253}254function parseTextData(255 context,256 length,257 mode258) {259 if (mode === TextModes.RAWTEXT || mode === TextModes.CDATA) {260 const text = context.source.slice(0, length)261 advanceBy(context, length)262 return text263 }264 // DATA or RCDATA. Entity decoding required.265 const end = context.offset + length266 let text = ''267 while (context.offset < end) {268 const head = /&(?:#x?)?/i.exec(context.source)269 if (!head || context.offset + head.index >= end) {270 const remaining = end - context.offset271 text += context.source.slice(0, remaining)272 advanceBy(context, remaining)273 break274 }275 // Advance to the "&".276 text += context.source.slice(0, head.index)277 advanceBy(context, head.index)278 if (head[0] === '&') {279 // Named character reference.280 let name = '',281 value = undefined282 if (/[0-9a-z]/i.test(context.source[1])) {283 for (284 let length = context.maxCRNameLength;285 !value && length > 0;286 --length287 ) {288 name = context.source.substr(1, length)289 value = context.options.namedCharacterReferences[name]290 }291 if (value) {292 const semi = name.endsWith(';')293 if (294 mode === TextModes.ATTRIBUTE_VALUE &&295 !semi &&296 /[=a-z0-9]/i.test(context.source[1 + name.length] || '')297 ) {298 text += '&'299 text += name300 advanceBy(context, 1 + name.length)301 } else {302 text += value303 advanceBy(context, 1 + name.length)304 if (!semi) {305 emitError(306 context,307 ErrorCodes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE308 )309 }310 }311 } else {312 emitError(context, ErrorCodes.UNKNOWN_NAMED_CHARACTER_REFERENCE)313 text += '&'314 text += name315 advanceBy(context, 1 + name.length)316 }317 } else {318 text += '&'319 advanceBy(context, 1)320 }321 } else {322 // Numeric character reference.323 const hex = head[0] === '&#x'324 const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/325 const body = pattern.exec(context.source)326 if (!body) {327 text += head[0]328 emitError(329 context,330 ErrorCodes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE331 )332 advanceBy(context, head[0].length)333 } else {334 // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state335 let cp = Number.parseInt(body[1], hex ? 16 : 10)336 if (cp === 0) {337 emitError(context, ErrorCodes.NULL_CHARACTER_REFERENCE)338 cp = 0xfffd339 } else if (cp > 0x10ffff) {340 emitError(341 context,342 ErrorCodes.CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE343 )344 cp = 0xfffd345 } else if (cp >= 0xd800 && cp <= 0xdfff) {346 emitError(context, ErrorCodes.SURROGATE_CHARACTER_REFERENCE)347 cp = 0xfffd348 } else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) {349 emitError(context, ErrorCodes.NONCHARACTER_CHARACTER_REFERENCE)350 } else if (351 (cp >= 0x01 && cp <= 0x08) ||352 cp === 0x0b ||353 (cp >= 0x0d && cp <= 0x1f) ||354 (cp >= 0x7f && cp <= 0x9f)355 ) {356 emitError(context, ErrorCodes.CONTROL_CHARACTER_REFERENCE)357 cp = CCR_REPLACEMENTS[cp] || cp358 }359 text += String.fromCodePoint(cp)360 advanceBy(context, body[0].length)361 if (!body[0].endsWith(';')) {362 emitError(363 context,364 ErrorCodes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE365 )366 }367 }368 }369 }370 return text371}372function advanceBy(context, numberOfCharacters) {373 const { source } = context374 __DEV__ && assert(numberOfCharacters <= source.length)375 advancePositionWithMutation(context, source, numberOfCharacters)376 context.source = source.slice(numberOfCharacters)377}378function getSelection(379 context,380 start,381 end382) {383 end = end || getCursor(context)384 return {385 start,386 end,387 source: context.originalSource.slice(start.offset, end.offset)388 }389}390function pushNode(nodes, node) {391 // ignore comments in production392 /* istanbul ignore next */393 if (!__DEV__ && node.type === NodeTypes.COMMENT) {394 return395 }396 if (node.type === NodeTypes.TEXT) {397 const prev = last(nodes)398 // Merge if both this and the previous node are text and those are399 // consecutive. This happens for cases like "a < b".400 if (401 prev &&402 prev.type === NodeTypes.TEXT &&403 prev.loc.end.offset === node.loc.start.offset404 ) {405 prev.content += node.content406 prev.loc.end = node.loc.end407 prev.loc.source += node.loc.source408 return409 }410 }411 nodes.push(node)412}413function parseElement(414 context,415 ancestors416) {417 __DEV__ && assert(/^<[a-z]/i.test(context.source))418 // Start tag.419 const wasInPre = context.inPre420 const parent = last(ancestors)421 const element = parseTag(context, TagType.Start, parent)422 const isPreBoundary = context.inPre && !wasInPre423 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {424 return element425 }426 // Children.427 ancestors.push(element)428 console.log('>>> ', ancestors.length)429 const mode = context.options.getTextMode(element.tag, element.ns)430 const children = parseChildren(context, mode, ancestors)431 432 ancestors.pop()433 element.children = children434 // End tag.435 if (startsWithEndTagOpen(context.source, element.tag)) {436 parseTag(context, TagType.End, parent)437 } else {438 emitError(context, ErrorCodes.X_MISSING_END_TAG)439 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {440 const first = children[0]441 if (first && startsWith(first.loc.source, '<!--')) {442 emitError(context, ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT)443 }444 }445 }446 element.loc = getSelection(context, element.loc.start)447 if (isPreBoundary) {448 context.inPre = false449 }450 return element451}452function parseTag(453 context,454 type,455 parent456) {457 __DEV__ && assert(/^<\/?[a-z]/i.test(context.source))458 __DEV__ &&459 assert(460 type === (startsWith(context.source, '</') ? TagType.End : TagType.Start)461 )462 // Tag open.463 const start = getCursor(context)464 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);465 const tag = match[1]466 const ns = context.options.getNamespace(tag, parent)467 advanceBy(context, match[0].length)468 advanceSpaces(context)469 // save current state in case we need to re-parse attributes with v-pre470 const cursor = getCursor(context)471 const currentSource = context.source472 // Attributes.473 let props = parseAttributes(context, type)474 // check v-pre475 if (476 !context.inPre &&477 props.some(p => p.type === NodeTypes.DIRECTIVE && p.name === 'pre')478 ) {479 context.inPre = true480 // reset context481 extend(context, cursor)482 context.source = currentSource483 // re-parse attrs and filter out v-pre itself484 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre')485 }486 // Tag close.487 let isSelfClosing = false488 if (context.source.length === 0) {489 emitError(context, ErrorCodes.EOF_IN_TAG)490 } else {491 isSelfClosing = startsWith(context.source, '/>')492 if (type === TagType.End && isSelfClosing) {493 emitError(context, ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS)494 }495 advanceBy(context, isSelfClosing ? 2 : 1)496 }497 let tagType = ElementTypes.ELEMENT498 if (!context.inPre && !context.options.isCustomElement(tag)) {499 if (context.options.isNativeTag) {500 if (!context.options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT501 } else {502 if (/^[A-Z]/.test(tag)) tagType = ElementTypes.COMPONENT503 }504 if (tag === 'slot') tagType = ElementTypes.SLOT505 else if (tag === 'template') tagType = ElementTypes.TEMPLATE506 else if (tag === 'portal' || tag === 'Portal') tagType = ElementTypes.PORTAL507 else if (tag === 'suspense' || tag === 'Suspense')508 tagType = ElementTypes.SUSPENSE509 }510 return {511 type: NodeTypes.ELEMENT,512 ns,513 tag,514 tagType,515 props,516 isSelfClosing,517 children: [],518 loc: getSelection(context, start),519 codegenNode: undefined // to be created during transform phase520 }521}522function advanceSpaces(context) {523 const match = /^[\t\r\n\f ]+/.exec(context.source)524 if (match) {525 advanceBy(context, match[0].length)526 }527}528function parseAttributes(529 context,530 type531) {532 const props = []533 const attributeNames = new Set()534 while (535 context.source.length > 0 &&536 !startsWith(context.source, '>') &&537 !startsWith(context.source, '/>')538 ) {539 if (startsWith(context.source, '/')) {540 emitError(context, ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG)541 advanceBy(context, 1)542 advanceSpaces(context)543 continue544 }545 if (type === TagType.End) {546 emitError(context, ErrorCodes.END_TAG_WITH_ATTRIBUTES)547 }548 const attr = parseAttribute(context, attributeNames)549 if (type === TagType.Start) {550 props.push(attr)551 }552 if (/^[^\t\r\n\f />]/.test(context.source)) {553 emitError(context, ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES)554 }555 advanceSpaces(context)556 }557 return props558}559function parseAttribute(560 context,561 nameSet562) {563 __DEV__ && assert(/^[^\t\r\n\f />]/.test(context.source))564 // Name.565 const start = getCursor(context)566 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);567 const name = match[0]568 if (nameSet.has(name)) {569 emitError(context, ErrorCodes.DUPLICATE_ATTRIBUTE)570 }571 nameSet.add(name)572 if (name[0] === '=') {573 emitError(context, ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME)574 }575 {576 const pattern = /["'<]/g577 let m578 while ((m = pattern.exec(name)) !== null) {579 emitError(580 context,581 ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,582 m.index583 )584 }585 }586 advanceBy(context, name.length)587 // Value588 let value = undefined589 if (/^[\t\r\n\f ]*=/.test(context.source)) {590 advanceSpaces(context)591 advanceBy(context, 1)592 advanceSpaces(context)593 value = parseAttributeValue(context)594 if (!value) {595 emitError(context, ErrorCodes.MISSING_ATTRIBUTE_VALUE)596 }597 }598 const loc = getSelection(context, start)599 if (!context.inPre && /^(v-|:|@|#)/.test(name)) {600 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)([^\.]+))?(.+)?$/i.exec(name);601 let arg602 if (match[2]) {603 const startOffset = name.split(match[2], 2).shift().length;604 const loc = getSelection(605 context,606 getNewPosition(context, start, startOffset),607 getNewPosition(context, start, startOffset + match[2].length)608 )609 let content = match[2]610 let isStatic = true611 if (content.startsWith('[')) {612 isStatic = false613 if (!content.endsWith(']')) {614 emitError(615 context,616 ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END617 )618 }619 content = content.substr(1, content.length - 2)620 }621 arg = {622 type: NodeTypes.SIMPLE_EXPRESSION,623 content,624 isStatic,625 isConstant: isStatic,626 loc627 }628 }629 if (value && value.isQuoted) {630 const valueLoc = value.loc631 valueLoc.start.offset++632 valueLoc.start.column++633 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content)634 valueLoc.source = valueLoc.source.slice(1, -1)635 }636 return {637 type: NodeTypes.DIRECTIVE,638 name:639 match[1] ||640 (startsWith(name, ':')641 ? 'bind'642 : startsWith(name, '@')643 ? 'on'644 : 'slot'),645 exp: value && {646 type: NodeTypes.SIMPLE_EXPRESSION,647 content: value.content,648 isStatic: false,649 // Treat as non-constant by default. This can be potentially set to650 // true by `transformExpression` to make it eligible for hoisting.651 isConstant: false,652 loc: value.loc653 },654 arg,655 modifiers: match[3] ? match[3].substr(1).split('.') : [],656 loc657 }658 }659 return {660 type: NodeTypes.ATTRIBUTE,661 name,662 value: value && {663 type: NodeTypes.TEXT,664 content: value.content,665 loc: value.loc666 },667 loc668 }669}670function parseAttributeValue(671 context672){673 const start = getCursor(context)674 let content675 const quote = context.source[0]676 const isQuoted = quote === `"` || quote === `'`677 if (isQuoted) {678 // Quoted value.679 advanceBy(context, 1)680 const endIndex = context.source.indexOf(quote)681 if (endIndex === -1) {682 content = parseTextData(683 context,684 context.source.length,685 TextModes.ATTRIBUTE_VALUE686 )687 } else {688 content = parseTextData(context, endIndex, TextModes.ATTRIBUTE_VALUE)689 advanceBy(context, 1)690 }691 } else {692 // Unquoted693 const match = /^[^\t\r\n\f >]+/.exec(context.source)694 if (!match) {695 return undefined696 }697 let unexpectedChars = /["'<=`]/g698 let m699 while ((m = unexpectedChars.exec(match[0])) !== null) {700 emitError(701 context,702 ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,703 m.index704 )705 }706 content = parseTextData(context, match[0].length, TextModes.ATTRIBUTE_VALUE)707 }708 return { content, isQuoted, loc: getSelection(context, start) }709}710function getNewPosition(711 context,712 start,713 numberOfCharacters714) {715 return advancePositionWithClone(716 start,717 context.originalSource.slice(start.offset, numberOfCharacters),718 numberOfCharacters719 )720}721function startsWithEndTagOpen(source, tag) {722 return (723 startsWith(source, '</') &&724 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&725 /[\t\n\f />]/.test(source[2 + tag.length] || '>')726 )727}728function parseComment(context) {729 __DEV__ && assert(startsWith(context.source, '<!--'))730 const start = getCursor(context)731 let content732 // Regular comment.733 const match = /--(\!)?>/.exec(context.source)734 if (!match) {735 content = context.source.slice(4)...

Full Screen

Full Screen

——————parse.js

Source:——————parse.js Github

copy

Full Screen

...82 case TextModes.DATA:83 if (startsWith(s, '</')) {84 //TODO: probably bad performance85 for (let i = ancestors.length - 1; i >= 0; --i) {86 if (startsWithEndTagOpen(s, ancestors[i].tag)) {87 return true88 }89 }90 }91 break92 case TextModes.RCDATA:93 case TextModes.RAWTEXT: {94 const parent = last(ancestors)95 if (parent && startsWithEndTagOpen(s, parent.tag)) {96 return true97 }98 break99 }100 case TextModes.CDATA:101 if (startsWith(s, ']]>')) {102 return true103 }104 break105 }106 return !s107}108function parseChildren( context, mode, ancestors ) {109 const parent = last(ancestors)110 const ns = parent ? parent.ns : Namespaces.HTML111 const nodes = []112 console.log(1111)113 while (!isEnd(context, mode, ancestors)) {114 115 __DEV__ && assert(context.source.length > 0)116 const s = context.source117 let node = undefined118 if (!context.inPre && startsWith(s, context.options.delimiters[0])) {119 // '{{'120 node = parseInterpolation(context, mode)121 } else if (mode === TextModes.DATA && s[0] === '<') {122 // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state123 if (s.length === 1) {124 emitError(context, ErrorCodes.EOF_BEFORE_TAG_NAME, 1)125 } else if (s[1] === '!') {126 // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state127 if (startsWith(s, '<!--')) {128 node = parseComment(context)129 } else if (startsWith(s, '<!DOCTYPE')) {130 // Ignore DOCTYPE by a limitation.131 node = parseBogusComment(context)132 } else if (startsWith(s, '<![CDATA[')) {133 if (ns !== Namespaces.HTML) {134 node = parseCDATA(context, ancestors)135 } else {136 emitError(context, ErrorCodes.CDATA_IN_HTML_CONTENT)137 node = parseBogusComment(context)138 }139 } else {140 emitError(context, ErrorCodes.INCORRECTLY_OPENED_COMMENT)141 node = parseBogusComment(context)142 }143 } else if (s[1] === '/') {144 // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state145 if (s.length === 2) {146 emitError(context, ErrorCodes.EOF_BEFORE_TAG_NAME, 2)147 } else if (s[2] === '>') {148 emitError(context, ErrorCodes.MISSING_END_TAG_NAME, 2)149 advanceBy(context, 3)150 continue151 } else if (/[a-z]/i.test(s[2])) {152 emitError(context, ErrorCodes.X_INVALID_END_TAG)153 parseTag(context, TagType.End, parent)154 continue155 } else {156 emitError(context, ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME, 2)157 node = parseBogusComment(context)158 }159 } else if (/[a-z]/i.test(s[1])) {160 node = parseElement(context, ancestors)161 } else if (s[1] === '?') {162 emitError(163 context,164 ErrorCodes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME,165 1166 )167 node = parseBogusComment(context)168 } else {169 emitError(context, ErrorCodes.INVALID_FIRST_CHARACTER_OF_TAG_NAME, 1)170 }171 }172 if (!node) {173 node = parseText(context, mode)174 }175 if (Array.isArray(node)) {176 for (let i = 0; i < node.length; i++) {177 pushNode(nodes, node[i])178 }179 } else {180 pushNode(nodes, node)181 }182 }183 // Whitespace management for more efficient output184 // 这里是对一些空白节点的过滤185 // (same as v2 whitespance: 'condense')186 let removedWhitespace = false187 if (!parent || !context.options.isPreTag(parent.tag)) {188 for (let i = 0; i < nodes.length; i++) {189 const node = nodes[i]190 if (node.type === NodeTypes.TEXT) {191 if (!node.content.trim()) {192 const prev = nodes[i - 1]193 const next = nodes[i + 1]194 // If:195 // - the whitespace is the first or last node, or:196 // - the whitespace is adjacent to a comment, or:197 // - the whitespace is between two elements AND contains newline198 // Then the whitespace is ignored.199 if (200 !prev ||201 !next ||202 prev.type === NodeTypes.COMMENT ||203 next.type === NodeTypes.COMMENT ||204 (prev.type === NodeTypes.ELEMENT &&205 next.type === NodeTypes.ELEMENT &&206 /[\r\n]/.test(node.content))207 ) {208 removedWhitespace = true209 nodes[i] = null210 } else {211 // Otherwise, condensed consecutive whitespace inside the text down to212 // a single space213 node.content = ' '214 }215 } else {216 node.content = node.content.replace(/\s+/g, ' ')217 }218 }219 }220 }221 return removedWhitespace ? nodes.filter(node => node !== null) : nodes222}223function parseText(context, mode) {224 __DEV__ && assert(context.source.length > 0)225 const [open] = context.options.delimiters226 // TODO could probably use some perf optimization227 const endIndex = Math.min(228 ...[229 context.source.indexOf('<', 1),230 context.source.indexOf(open, 1),231 mode === TextModes.CDATA ? context.source.indexOf(']]>') : -1,232 context.source.length233 ].filter(n => n !== -1)234 )235 __DEV__ && assert(endIndex > 0)236 const start = getCursor(context)237 const content = parseTextData(context, endIndex, mode)238 return {239 type: NodeTypes.TEXT,240 content,241 loc: getSelection(context, start)242 }243}244function parseTextData(245 context,246 length,247 mode248) {249 if (mode === TextModes.RAWTEXT || mode === TextModes.CDATA) {250 const text = context.source.slice(0, length)251 advanceBy(context, length)252 return text253 }254 // DATA or RCDATA. Entity decoding required.255 const end = context.offset + length256 let text = ''257 while (context.offset < end) {258 const head = /&(?:#x?)?/i.exec(context.source)259 if (!head || context.offset + head.index >= end) {260 const remaining = end - context.offset261 text += context.source.slice(0, remaining)262 advanceBy(context, remaining)263 break264 }265 // Advance to the "&".266 text += context.source.slice(0, head.index)267 advanceBy(context, head.index)268 if (head[0] === '&') {269 // Named character reference.270 let name = '',271 value = undefined272 if (/[0-9a-z]/i.test(context.source[1])) {273 for (274 let length = context.maxCRNameLength;275 !value && length > 0;276 --length277 ) {278 name = context.source.substr(1, length)279 value = context.options.namedCharacterReferences[name]280 }281 if (value) {282 const semi = name.endsWith(';')283 if (284 mode === TextModes.ATTRIBUTE_VALUE &&285 !semi &&286 /[=a-z0-9]/i.test(context.source[1 + name.length] || '')287 ) {288 text += '&'289 text += name290 advanceBy(context, 1 + name.length)291 } else {292 text += value293 advanceBy(context, 1 + name.length)294 if (!semi) {295 emitError(296 context,297 ErrorCodes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE298 )299 }300 }301 } else {302 emitError(context, ErrorCodes.UNKNOWN_NAMED_CHARACTER_REFERENCE)303 text += '&'304 text += name305 advanceBy(context, 1 + name.length)306 }307 } else {308 text += '&'309 advanceBy(context, 1)310 }311 } else {312 // Numeric character reference.313 const hex = head[0] === '&#x'314 const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/315 const body = pattern.exec(context.source)316 if (!body) {317 text += head[0]318 emitError(319 context,320 ErrorCodes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE321 )322 advanceBy(context, head[0].length)323 } else {324 // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state325 let cp = Number.parseInt(body[1], hex ? 16 : 10)326 if (cp === 0) {327 emitError(context, ErrorCodes.NULL_CHARACTER_REFERENCE)328 cp = 0xfffd329 } else if (cp > 0x10ffff) {330 emitError(331 context,332 ErrorCodes.CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE333 )334 cp = 0xfffd335 } else if (cp >= 0xd800 && cp <= 0xdfff) {336 emitError(context, ErrorCodes.SURROGATE_CHARACTER_REFERENCE)337 cp = 0xfffd338 } else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) {339 emitError(context, ErrorCodes.NONCHARACTER_CHARACTER_REFERENCE)340 } else if (341 (cp >= 0x01 && cp <= 0x08) ||342 cp === 0x0b ||343 (cp >= 0x0d && cp <= 0x1f) ||344 (cp >= 0x7f && cp <= 0x9f)345 ) {346 emitError(context, ErrorCodes.CONTROL_CHARACTER_REFERENCE)347 cp = CCR_REPLACEMENTS[cp] || cp348 }349 text += String.fromCodePoint(cp)350 advanceBy(context, body[0].length)351 if (!body[0].endsWith(';')) {352 emitError(353 context,354 ErrorCodes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE355 )356 }357 }358 }359 }360 return text361}362function advanceBy(context, numberOfCharacters) {363 const { source } = context364 __DEV__ && assert(numberOfCharacters <= source.length)365 advancePositionWithMutation(context, source, numberOfCharacters)366 context.source = source.slice(numberOfCharacters)367}368function getSelection(369 context,370 start,371 end372) {373 end = end || getCursor(context)374 return {375 start,376 end,377 source: context.originalSource.slice(start.offset, end.offset)378 }379}380function pushNode(nodes, node) {381 // ignore comments in production382 /* istanbul ignore next */383 if (!__DEV__ && node.type === NodeTypes.COMMENT) {384 return385 }386 if (node.type === NodeTypes.TEXT) {387 const prev = last(nodes)388 // Merge if both this and the previous node are text and those are389 // consecutive. This happens for cases like "a < b".390 if (391 prev &&392 prev.type === NodeTypes.TEXT &&393 prev.loc.end.offset === node.loc.start.offset394 ) {395 prev.content += node.content396 prev.loc.end = node.loc.end397 prev.loc.source += node.loc.source398 return399 }400 }401 nodes.push(node)402}403function parseElement(404 context,405 ancestors406) {407 __DEV__ && assert(/^<[a-z]/i.test(context.source))408 // Start tag.409 const wasInPre = context.inPre410 const parent = last(ancestors)411 const element = parseTag(context, TagType.Start, parent)412 const isPreBoundary = context.inPre && !wasInPre413 if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {414 return element415 }416 JSON.stringify()417 // Children.418 ancestors.push(element)419 console.log('>>> ', ancestors.length)420 const mode = context.options.getTextMode(element.tag, element.ns)421 const children = parseChildren(context, mode, ancestors)422 423 ancestors.pop()424 element.children = children425 // End tag.426 if (startsWithEndTagOpen(context.source, element.tag)) {427 parseTag(context, TagType.End, parent)428 } else {429 emitError(context, ErrorCodes.X_MISSING_END_TAG)430 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {431 const first = children[0]432 if (first && startsWith(first.loc.source, '<!--')) {433 emitError(context, ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT)434 }435 }436 }437 element.loc = getSelection(context, element.loc.start)438 if (isPreBoundary) {439 context.inPre = false440 }441 return element442}443function parseTag(444 context,445 type,446 parent447) {448 __DEV__ && assert(/^<\/?[a-z]/i.test(context.source))449 __DEV__ &&450 assert(451 type === (startsWith(context.source, '</') ? TagType.End : TagType.Start)452 )453 // Tag open.454 const start = getCursor(context)455 const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);456 const tag = match[1]457 const ns = context.options.getNamespace(tag, parent)458 advanceBy(context, match[0].length)459 advanceSpaces(context)460 // save current state in case we need to re-parse attributes with v-pre461 const cursor = getCursor(context)462 const currentSource = context.source463 // Attributes.464 let props = parseAttributes(context, type)465 // check v-pre466 if (467 !context.inPre &&468 props.some(p => p.type === NodeTypes.DIRECTIVE && p.name === 'pre')469 ) {470 context.inPre = true471 // reset context472 extend(context, cursor)473 context.source = currentSource474 // re-parse attrs and filter out v-pre itself475 props = parseAttributes(context, type).filter(p => p.name !== 'v-pre')476 }477 // Tag close.478 let isSelfClosing = false479 if (context.source.length === 0) {480 emitError(context, ErrorCodes.EOF_IN_TAG)481 } else {482 isSelfClosing = startsWith(context.source, '/>')483 if (type === TagType.End && isSelfClosing) {484 emitError(context, ErrorCodes.END_TAG_WITH_TRAILING_SOLIDUS)485 }486 advanceBy(context, isSelfClosing ? 2 : 1)487 }488 let tagType = ElementTypes.ELEMENT489 if (!context.inPre && !context.options.isCustomElement(tag)) {490 if (context.options.isNativeTag) {491 if (!context.options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT492 } else {493 if (/^[A-Z]/.test(tag)) tagType = ElementTypes.COMPONENT494 }495 if (tag === 'slot') tagType = ElementTypes.SLOT496 else if (tag === 'template') tagType = ElementTypes.TEMPLATE497 else if (tag === 'portal' || tag === 'Portal') tagType = ElementTypes.PORTAL498 else if (tag === 'suspense' || tag === 'Suspense')499 tagType = ElementTypes.SUSPENSE500 }501 return {502 type: NodeTypes.ELEMENT,503 ns,504 tag,505 tagType,506 props,507 isSelfClosing,508 children: [],509 loc: getSelection(context, start),510 codegenNode: undefined // to be created during transform phase511 }512}513function advanceSpaces(context) {514 const match = /^[\t\r\n\f ]+/.exec(context.source)515 if (match) {516 advanceBy(context, match[0].length)517 }518}519function parseAttributes(520 context,521 type522) {523 const props = []524 const attributeNames = new Set()525 while (526 context.source.length > 0 &&527 !startsWith(context.source, '>') &&528 !startsWith(context.source, '/>')529 ) {530 if (startsWith(context.source, '/')) {531 emitError(context, ErrorCodes.UNEXPECTED_SOLIDUS_IN_TAG)532 advanceBy(context, 1)533 advanceSpaces(context)534 continue535 }536 if (type === TagType.End) {537 emitError(context, ErrorCodes.END_TAG_WITH_ATTRIBUTES)538 }539 const attr = parseAttribute(context, attributeNames)540 if (type === TagType.Start) {541 props.push(attr)542 }543 if (/^[^\t\r\n\f />]/.test(context.source)) {544 emitError(context, ErrorCodes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES)545 }546 advanceSpaces(context)547 }548 return props549}550function parseAttribute(551 context,552 nameSet553) {554 __DEV__ && assert(/^[^\t\r\n\f />]/.test(context.source))555 // Name.556 const start = getCursor(context)557 const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);558 const name = match[0]559 if (nameSet.has(name)) {560 emitError(context, ErrorCodes.DUPLICATE_ATTRIBUTE)561 }562 nameSet.add(name)563 if (name[0] === '=') {564 emitError(context, ErrorCodes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME)565 }566 {567 const pattern = /["'<]/g568 let m569 while ((m = pattern.exec(name)) !== null) {570 emitError(571 context,572 ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,573 m.index574 )575 }576 }577 advanceBy(context, name.length)578 // Value579 let value = undefined580 if (/^[\t\r\n\f ]*=/.test(context.source)) {581 advanceSpaces(context)582 advanceBy(context, 1)583 advanceSpaces(context)584 value = parseAttributeValue(context)585 if (!value) {586 emitError(context, ErrorCodes.MISSING_ATTRIBUTE_VALUE)587 }588 }589 const loc = getSelection(context, start)590 if (!context.inPre && /^(v-|:|@|#)/.test(name)) {591 const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)([^\.]+))?(.+)?$/i.exec(name);592 let arg593 if (match[2]) {594 const startOffset = name.split(match[2], 2).shift().length;595 const loc = getSelection(596 context,597 getNewPosition(context, start, startOffset),598 getNewPosition(context, start, startOffset + match[2].length)599 )600 let content = match[2]601 let isStatic = true602 if (content.startsWith('[')) {603 isStatic = false604 if (!content.endsWith(']')) {605 emitError(606 context,607 ErrorCodes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END608 )609 }610 content = content.substr(1, content.length - 2)611 }612 arg = {613 type: NodeTypes.SIMPLE_EXPRESSION,614 content,615 isStatic,616 isConstant: isStatic,617 loc618 }619 }620 if (value && value.isQuoted) {621 const valueLoc = value.loc622 valueLoc.start.offset++623 valueLoc.start.column++624 valueLoc.end = advancePositionWithClone(valueLoc.start, value.content)625 valueLoc.source = valueLoc.source.slice(1, -1)626 }627 return {628 type: NodeTypes.DIRECTIVE,629 name:630 match[1] ||631 (startsWith(name, ':')632 ? 'bind'633 : startsWith(name, '@')634 ? 'on'635 : 'slot'),636 exp: value && {637 type: NodeTypes.SIMPLE_EXPRESSION,638 content: value.content,639 isStatic: false,640 // Treat as non-constant by default. This can be potentially set to641 // true by `transformExpression` to make it eligible for hoisting.642 isConstant: false,643 loc: value.loc644 },645 arg,646 modifiers: match[3] ? match[3].substr(1).split('.') : [],647 loc648 }649 }650 return {651 type: NodeTypes.ATTRIBUTE,652 name,653 value: value && {654 type: NodeTypes.TEXT,655 content: value.content,656 loc: value.loc657 },658 loc659 }660}661function parseAttributeValue(662 context663){664 const start = getCursor(context)665 let content666 const quote = context.source[0]667 const isQuoted = quote === `"` || quote === `'`668 if (isQuoted) {669 // Quoted value.670 advanceBy(context, 1)671 const endIndex = context.source.indexOf(quote)672 if (endIndex === -1) {673 content = parseTextData(674 context,675 context.source.length,676 TextModes.ATTRIBUTE_VALUE677 )678 } else {679 content = parseTextData(context, endIndex, TextModes.ATTRIBUTE_VALUE)680 advanceBy(context, 1)681 }682 } else {683 // Unquoted684 const match = /^[^\t\r\n\f >]+/.exec(context.source)685 if (!match) {686 return undefined687 }688 let unexpectedChars = /["'<=`]/g689 let m690 while ((m = unexpectedChars.exec(match[0])) !== null) {691 emitError(692 context,693 ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,694 m.index695 )696 }697 content = parseTextData(context, match[0].length, TextModes.ATTRIBUTE_VALUE)698 }699 return { content, isQuoted, loc: getSelection(context, start) }700}701function getNewPosition(702 context,703 start,704 numberOfCharacters705) {706 return advancePositionWithClone(707 start,708 context.originalSource.slice(start.offset, numberOfCharacters),709 numberOfCharacters710 )711}712function startsWithEndTagOpen(source, tag) {713 return (714 startsWith(source, '</') &&715 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&716 /[\t\n\f />]/.test(source[2 + tag.length] || '>')717 )718}719function parseComment(context) {720 __DEV__ && assert(startsWith(context.source, '<!--'))721 const start = getCursor(context)722 let content723 // Regular comment.724 const match = /--(\!)?>/.exec(context.source)725 if (!match) {726 content = context.source.slice(4)...

Full Screen

Full Screen

parse2.js

Source:parse2.js Github

copy

Full Screen

...25 ancestors.pop()26 // 添加到 children 属性中27 element.children = children28 // 结束标签29 if (startsWithEndTagOpen(context.source, element.tag)) {30 // 解析结束标签,并前进代码到结束标签后31 parseTag(context, 1 /* End */, parent)32 }33 else {34 emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);35 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {36 const first = children[0];37 if (first && startsWith(first.loc.source, '<!--')) {38 emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */)39 }40 }41 }42 // 更新标签节点的代码位置,结束位置到结束标签后43 element.loc = getSelection(context, element.loc.start)...

Full Screen

Full Screen

parse.js

Source:parse.js Github

copy

Full Screen

...131 case TextModes.DATA:132 if (startsWith(s, '</')) {133 //TODO: probably bad performance134 for (let i = ancestors.length - 1; i >= 0; --i) {135 if (startsWithEndTagOpen(s, ancestors[i].tag)) {136 return true137 }138 }139 }140 break141 case TextModes.RCDATA:142 case TextModes.RAWTEXT: {143 const parent = last(ancestors)144 if (parent && startsWithEndTagOpen(s, parent.tag)) {145 return true146 }147 break148 }149 case TextModes.CDATA:150 if (startsWith(s, ']]>')) {151 return true152 }153 break154 155 default:156 break157 }158 return !s159}160function startsWith(source, searchString) {161 return source.startsWith(searchString)162}163function startsWithEndTagOpen(source, tag) {164 return (165 startsWith(source, '</') &&166 source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&167 /[\t\n\f />]/.test(source[2 + tag.length] || '>')168 )169}170/**171 * 用来过滤属性,返回字符对应行数172 * @context {*} ParseContext173 */174function getCursor(context) {175 const {column, line, offset} = context176 return {column, line, offset}177}...

Full Screen

Full Screen

03-parseElement.js

Source:03-parseElement.js Github

copy

Full Screen

...30const children = parseChildren(context, mode, ancestors)31ancestors.pop()32element.children = children33// End tag.34if (startsWithEndTagOpen(context.source, element.tag)) {35 parseTag(context, TagType.End, parent)36} else {37 emitError(context, ErrorCodes.X_MISSING_END_TAG, 0, element.loc.start)38 if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {39 const first = children[0]40 if (first && startsWith(first.loc.source, '<!--')) {41 emitError(context, ErrorCodes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT)42 }43 }44}45element.loc = getSelection(context, element.loc.start)46if (isPreBoundary) {47 context.inPre = false48}...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { startsWithEndTagOpen } = require('playwright-core/lib/utils/htmlParser');2const { startsWithEndTagOpen } = require('puppeteer/lib/JSHandle');3const { startsWithEndTagOpen } = require('chrome-remote-interface/lib/protocol/helper');4const { startsWithEndTagOpen } = require('playwright-core/lib/utils/htmlParser');5const { startsWithEndTagOpen } = require('puppeteer/lib/JSHandle');6const { startsWithEndTagOpen } = require('chrome-remote-interface/lib/protocol/helper');7const { startsWithEndTagOpen } = require('playwright-core/lib/utils/htmlParser');8const { startsWithEndTagOpen } = require('puppeteer/lib/JSHandle');9const { startsWithEndTagOpen } = require('chrome-remote-interface/lib/protocol/helper');10const { startsWithEndTagOpen } = require('playwright-core/lib/utils/htmlParser');11const { startsWithEndTagOpen } = require('puppeteer/lib/JSHandle');12const { startsWithEndTagOpen } = require('chrome-remote-interface/lib/protocol/helper');13const { startsWithEndTagOpen } = require('playwright-core/lib/utils/htmlParser');14const { startsWithEndTagOpen } = require('puppeteer/lib/JSHandle');15const { starts

Full Screen

Using AI Code Generation

copy

Full Screen

1const { parse } = require('playwright/lib/server/supplements/recorder/recorderUtils');2const { startsWithEndTagOpen } = parse;3console.log(startsWithEndTagOpen('div>'));4console.log(startsWithEndTagOpen('div'));5console.log(startsWithEndTagOpen('div/>'));6console.log(startsWithEndTagOpen('div>'));7console.log(startsWithEndTagOpen('div> '));8console.log(startsWithEndTagOpen('div> <'));9const { parse } = require('playwright/lib/server/supplements/recorder/recorderUtils');10const { endsWithStartTagClose } = parse;11console.log(endsWithStartTagClose('div>'));12console.log(endsWithStartTagClose('div'));13console.log(endsWithStartTagClose('div/>'));14console.log(endsWithStartTagClose('div>'));15console.log(endsWithStartTagClose('div> '));16console.log(endsWithStartTagClose('div> <'));17const { parse } = require('playwright/lib/server/supplements/recorder/recorderUtils');18const { endsWithEndTagClose } = parse;19console.log(endsWithEndTagClose('div>'));20console.log(endsWithEndTagClose('div'));21console.log(endsWithEndTagClose('div/>'));22console.log(endsWithEndTagClose('div>'));23console.log(endsWithEndTagClose('div> '));24console.log(endsWithEndTagClose('div> <'));

Full Screen

Using AI Code Generation

copy

Full Screen

1const { parseHTML } = require('playwright/lib/server/common/html');2const html = '<div id="foo">bar</div>';3const document = parseHTML(html);4const div = document.childNodes[0];5console.log(div.nodeName);6console.log(div.attributes);7console.log(div.childNodes[0].nodeValue);8[Apache 2.0](LICENSE)

Full Screen

Using AI Code Generation

copy

Full Screen

1const htmlParser = require('playwright/lib/server/common/htmlParser');2const parser = htmlParser.create(html);3parser.startsWithEndTagOpen();4const htmlParser = require('playwright/lib/server/common/htmlParser');5const parser = htmlParser.create(html);6parser.startsWithEndTagOpen();7const htmlParser = require('playwright/lib/server/common/htmlParser');8const parser = htmlParser.create(html);9parser.startsWithEndTagOpen();10const htmlParser = require('playwright/lib/server/common/htmlParser');11const parser = htmlParser.create(html);12parser.startsWithEndTagOpen();13const htmlParser = require('playwright/lib/server/common/htmlParser');14const parser = htmlParser.create(html);15parser.startsWithEndTagOpen();16const htmlParser = require('playwright/lib/server/common/htmlParser');17const parser = htmlParser.create(html);18parser.startsWithEndTagOpen();19const htmlParser = require('playwright/lib/server/common/htmlParser');20const parser = htmlParser.create(html);21parser.startsWithEndTagOpen();22const htmlParser = require('playwright/lib/server/common/htmlParser');

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful