|
44 | 44 | return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"); |
45 | 45 | } |
46 | 46 |
|
47 | | - function getAttrValue(stream, attr) { |
48 | | - var pos = stream.pos, match; |
49 | | - while (pos >= 0 && stream.string.charAt(pos) !== "<") pos--; |
50 | | - if (pos < 0) return pos; |
51 | | - if (match = stream.string.slice(pos, stream.pos).match(getAttrRegexp(attr))) |
52 | | - return match[2]; |
53 | | - return ""; |
| 47 | + function getAttrValue(text, attr) { |
| 48 | + var match = text.match(getAttrRegexp(attr)) |
| 49 | + return match ? match[2] : "" |
54 | 50 | } |
55 | 51 |
|
56 | 52 | function getTagRegexp(tagName, anchored) { |
|
66 | 62 | } |
67 | 63 | } |
68 | 64 |
|
69 | | - function findMatchingMode(tagInfo, stream) { |
| 65 | + function findMatchingMode(tagInfo, tagText) { |
70 | 66 | for (var i = 0; i < tagInfo.length; i++) { |
71 | 67 | var spec = tagInfo[i]; |
72 | | - if (!spec[0] || spec[1].test(getAttrValue(stream, spec[0]))) return spec[2]; |
| 68 | + if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2]; |
73 | 69 | } |
74 | 70 | } |
75 | 71 |
|
|
89 | 85 | tags.script.unshift(["type", configScript[i].matches, configScript[i].mode]) |
90 | 86 |
|
91 | 87 | function html(stream, state) { |
92 | | - var tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase(); |
93 | | - var tagInfo = tagName && tags.hasOwnProperty(tagName) && tags[tagName]; |
94 | | - |
95 | | - var style = htmlMode.token(stream, state.htmlState), modeSpec; |
96 | | - |
97 | | - if (tagInfo && /\btag\b/.test(style) && stream.current() === ">" && |
98 | | - (modeSpec = findMatchingMode(tagInfo, stream))) { |
99 | | - var mode = CodeMirror.getMode(config, modeSpec); |
100 | | - var endTagA = getTagRegexp(tagName, true), endTag = getTagRegexp(tagName, false); |
| 88 | + var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName |
| 89 | + if (tag && !/[<>\s\/]/.test(stream.current()) && |
| 90 | + (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) && |
| 91 | + tags.hasOwnProperty(tagName)) { |
| 92 | + state.inTag = tagName + " " |
| 93 | + } else if (state.inTag && tag && />$/.test(stream.current())) { |
| 94 | + var inTag = /^([\S]+) (.*)/.exec(state.inTag) |
| 95 | + state.inTag = null |
| 96 | + var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2]) |
| 97 | + var mode = CodeMirror.getMode(config, modeSpec) |
| 98 | + var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false); |
101 | 99 | state.token = function (stream, state) { |
102 | 100 | if (stream.match(endTagA, false)) { |
103 | 101 | state.token = html; |
|
108 | 106 | }; |
109 | 107 | state.localMode = mode; |
110 | 108 | state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "")); |
| 109 | + } else if (state.inTag) { |
| 110 | + state.inTag += stream.current() |
| 111 | + if (stream.eol()) state.inTag += " " |
111 | 112 | } |
112 | 113 | return style; |
113 | 114 | }; |
114 | 115 |
|
115 | 116 | return { |
116 | 117 | startState: function () { |
117 | 118 | var state = htmlMode.startState(); |
118 | | - return {token: html, localMode: null, localState: null, htmlState: state}; |
| 119 | + return {token: html, inTag: null, localMode: null, localState: null, htmlState: state}; |
119 | 120 | }, |
120 | 121 |
|
121 | 122 | copyState: function (state) { |
122 | 123 | var local; |
123 | 124 | if (state.localState) { |
124 | 125 | local = CodeMirror.copyState(state.localMode, state.localState); |
125 | 126 | } |
126 | | - return {token: state.token, localMode: state.localMode, localState: local, |
| 127 | + return {token: state.token, inTag: state.inTag, |
| 128 | + localMode: state.localMode, localState: local, |
127 | 129 | htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; |
128 | 130 | }, |
129 | 131 |
|
|
0 commit comments