PageSourceSearch

https://actionnetwork.org/includes/js/codemirror/htmlmixed.js?v=1

js actionnetwork.org collected 2026-09-24 07:04:01 UTC 5,359 bytes, 150 lines download raw bytes

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 && 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);
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});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.