clike.js
10 years ago
codemirror.css
10 years ago
codemirror.js
10 years ago
htmlmixed.js
10 years ago
javascript.js
10 years ago
matchbrackets.js
10 years ago
php.js
10 years ago
xml.js
10 years ago
htmlmixed.js
151 lines
| 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others |
| 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE |
| 3 | |
| 4 | (function(mod) { |
| 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS |
| 6 | mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css")); |
| 7 | else if (typeof define == "function" && define.amd) // AMD |
| 8 | define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod); |
| 9 | else // Plain browser env |
| 10 | mod(CodeMirror); |
| 11 | })(function(CodeMirror) { |
| 12 | "use strict"; |
| 13 | |
| 14 | var defaultTags = { |
| 15 | script: [ |
| 16 | ["lang", /(javascript|babel)/i, "javascript"], |
| 17 | ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"], |
| 18 | ["type", /./, "text/plain"], |
| 19 | [null, null, "javascript"] |
| 20 | ], |
| 21 | style: [ |
| 22 | ["lang", /^css$/i, "css"], |
| 23 | ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"], |
| 24 | ["type", /./, "text/plain"], |
| 25 | [null, null, "css"] |
| 26 | ] |
| 27 | }; |
| 28 | |
| 29 | function maybeBackup(stream, pat, style) { |
| 30 | var cur = stream.current(), close = cur.search(pat); |
| 31 | if (close > -1) { |
| 32 | stream.backUp(cur.length - close); |
| 33 | } else if (cur.match(/<\/?$/)) { |
| 34 | stream.backUp(cur.length); |
| 35 | if (!stream.match(pat, false)) stream.match(cur); |
| 36 | } |
| 37 | return style; |
| 38 | } |
| 39 | |
| 40 | var attrRegexpCache = {}; |
| 41 | function getAttrRegexp(attr) { |
| 42 | var regexp = attrRegexpCache[attr]; |
| 43 | if (regexp) return regexp; |
| 44 | return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"); |
| 45 | } |
| 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 ""; |
| 54 | } |
| 55 | |
| 56 | function getTagRegexp(tagName, anchored) { |
| 57 | return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i"); |
| 58 | } |
| 59 | |
| 60 | function addTags(from, to) { |
| 61 | for (var tag in from) { |
| 62 | var dest = to[tag] || (to[tag] = []); |
| 63 | var source = from[tag]; |
| 64 | for (var i = source.length - 1; i >= 0; i--) |
| 65 | dest.unshift(source[i]) |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | function findMatchingMode(tagInfo, stream) { |
| 70 | for (var i = 0; i < tagInfo.length; i++) { |
| 71 | var spec = tagInfo[i]; |
| 72 | if (!spec[0] || spec[1].test(getAttrValue(stream, spec[0]))) return spec[2]; |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | CodeMirror.defineMode("htmlmixed", function (config, parserConfig) { |
| 77 | var htmlMode = CodeMirror.getMode(config, { |
| 78 | name: "xml", |
| 79 | htmlMode: true, |
| 80 | multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, |
| 81 | multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag |
| 82 | }); |
| 83 | |
| 84 | var tags = {}; |
| 85 | var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes; |
| 86 | addTags(defaultTags, tags); |
| 87 | if (configTags) addTags(configTags, tags); |
| 88 | if (configScript) for (var i = configScript.length - 1; i >= 0; i--) |
| 89 | tags.script.unshift(["type", configScript[i].matches, configScript[i].mode]) |
| 90 | |
| 91 | function html(stream, state) { |
| 92 | var tagName = state.htmlState.tagName; |
| 93 | var tagInfo = tagName && tags[tagName.toLowerCase()]; |
| 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); |
| 101 | state.token = function (stream, state) { |
| 102 | if (stream.match(endTagA, false)) { |
| 103 | state.token = html; |
| 104 | state.localState = state.localMode = null; |
| 105 | return null; |
| 106 | } |
| 107 | return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); |
| 108 | }; |
| 109 | state.localMode = mode; |
| 110 | state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "")); |
| 111 | } |
| 112 | return style; |
| 113 | }; |
| 114 | |
| 115 | return { |
| 116 | startState: function () { |
| 117 | var state = htmlMode.startState(); |
| 118 | return {token: html, localMode: null, localState: null, htmlState: state}; |
| 119 | }, |
| 120 | |
| 121 | copyState: function (state) { |
| 122 | var local; |
| 123 | if (state.localState) { |
| 124 | local = CodeMirror.copyState(state.localMode, state.localState); |
| 125 | } |
| 126 | return {token: state.token, localMode: state.localMode, localState: local, |
| 127 | htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; |
| 128 | }, |
| 129 | |
| 130 | token: function (stream, state) { |
| 131 | return state.token(stream, state); |
| 132 | }, |
| 133 | |
| 134 | indent: function (state, textAfter) { |
| 135 | if (!state.localMode || /^\s*<\//.test(textAfter)) |
| 136 | return htmlMode.indent(state.htmlState, textAfter); |
| 137 | else if (state.localMode.indent) |
| 138 | return state.localMode.indent(state.localState, textAfter); |
| 139 | else |
| 140 | return CodeMirror.Pass; |
| 141 | }, |
| 142 | |
| 143 | innerMode: function (state) { |
| 144 | return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; |
| 145 | } |
| 146 | }; |
| 147 | }, "xml", "javascript", "css"); |
| 148 | |
| 149 | CodeMirror.defineMIME("text/html", "htmlmixed"); |
| 150 | }); |
| 151 |