执行过npm install命令的vue-element-admin源码
康凯
2022-05-20 aa4c235a8ca67ea8b731f90c951a465e92c0a865
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
import { operation, runInOp } from "../display/operations.js"
import { prepareSelection } from "../display/selection.js"
import { applyTextInput, copyableRanges, handlePaste, hiddenTextarea, setLastCopied } from "./input.js"
import { cursorCoords, posFromMouse } from "../measurement/position_measurement.js"
import { eventInWidget } from "../measurement/widgets.js"
import { simpleSelection } from "../model/selection.js"
import { selectAll, setSelection } from "../model/selection_updates.js"
import { captureRightClick, ie, ie_version, ios, mac, mobile, presto, webkit } from "../util/browser.js"
import { activeElt, removeChildrenAndAdd, selectInput } from "../util/dom.js"
import { e_preventDefault, e_stop, off, on, signalDOMEvent } from "../util/event.js"
import { hasSelection } from "../util/feature_detection.js"
import { Delayed, sel_dontScroll } from "../util/misc.js"
 
// TEXTAREA INPUT STYLE
 
export default class TextareaInput {
  constructor(cm) {
    this.cm = cm
    // See input.poll and input.reset
    this.prevInput = ""
 
    // Flag that indicates whether we expect input to appear real soon
    // now (after some event like 'keypress' or 'input') and are
    // polling intensively.
    this.pollingFast = false
    // Self-resetting timeout for the poller
    this.polling = new Delayed()
    // Used to work around IE issue with selection being forgotten when focus moves away from textarea
    this.hasSelection = false
    this.composing = null
  }
 
  init(display) {
    let input = this, cm = this.cm
    this.createField(display)
    const te = this.textarea
 
    display.wrapper.insertBefore(this.wrapper, display.wrapper.firstChild)
 
    // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
    if (ios) te.style.width = "0px"
 
    on(te, "input", () => {
      if (ie && ie_version >= 9 && this.hasSelection) this.hasSelection = null
      input.poll()
    })
 
    on(te, "paste", e => {
      if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return
 
      cm.state.pasteIncoming = +new Date
      input.fastPoll()
    })
 
    function prepareCopyCut(e) {
      if (signalDOMEvent(cm, e)) return
      if (cm.somethingSelected()) {
        setLastCopied({lineWise: false, text: cm.getSelections()})
      } else if (!cm.options.lineWiseCopyCut) {
        return
      } else {
        let ranges = copyableRanges(cm)
        setLastCopied({lineWise: true, text: ranges.text})
        if (e.type == "cut") {
          cm.setSelections(ranges.ranges, null, sel_dontScroll)
        } else {
          input.prevInput = ""
          te.value = ranges.text.join("\n")
          selectInput(te)
        }
      }
      if (e.type == "cut") cm.state.cutIncoming = +new Date
    }
    on(te, "cut", prepareCopyCut)
    on(te, "copy", prepareCopyCut)
 
    on(display.scroller, "paste", e => {
      if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return
      if (!te.dispatchEvent) {
        cm.state.pasteIncoming = +new Date
        input.focus()
        return
      }
 
      // Pass the `paste` event to the textarea so it's handled by its event listener.
      const event = new Event("paste")
      event.clipboardData = e.clipboardData
      te.dispatchEvent(event)
    })
 
    // Prevent normal selection in the editor (we handle our own)
    on(display.lineSpace, "selectstart", e => {
      if (!eventInWidget(display, e)) e_preventDefault(e)
    })
 
    on(te, "compositionstart", () => {
      let start = cm.getCursor("from")
      if (input.composing) input.composing.range.clear()
      input.composing = {
        start: start,
        range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
      }
    })
    on(te, "compositionend", () => {
      if (input.composing) {
        input.poll()
        input.composing.range.clear()
        input.composing = null
      }
    })
  }
 
  createField(_display) {
    // Wraps and hides input textarea
    this.wrapper = hiddenTextarea()
    // The semihidden textarea that is focused when the editor is
    // focused, and receives input.
    this.textarea = this.wrapper.firstChild
  }
 
  prepareSelection() {
    // Redraw the selection and/or cursor
    let cm = this.cm, display = cm.display, doc = cm.doc
    let result = prepareSelection(cm)
 
    // Move the hidden textarea near the cursor to prevent scrolling artifacts
    if (cm.options.moveInputWithCursor) {
      let headPos = cursorCoords(cm, doc.sel.primary().head, "div")
      let wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect()
      result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
                                          headPos.top + lineOff.top - wrapOff.top))
      result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
                                           headPos.left + lineOff.left - wrapOff.left))
    }
 
    return result
  }
 
  showSelection(drawn) {
    let cm = this.cm, display = cm.display
    removeChildrenAndAdd(display.cursorDiv, drawn.cursors)
    removeChildrenAndAdd(display.selectionDiv, drawn.selection)
    if (drawn.teTop != null) {
      this.wrapper.style.top = drawn.teTop + "px"
      this.wrapper.style.left = drawn.teLeft + "px"
    }
  }
 
  // Reset the input to correspond to the selection (or to be empty,
  // when not typing and nothing is selected)
  reset(typing) {
    if (this.contextMenuPending || this.composing) return
    let cm = this.cm
    if (cm.somethingSelected()) {
      this.prevInput = ""
      let content = cm.getSelection()
      this.textarea.value = content
      if (cm.state.focused) selectInput(this.textarea)
      if (ie && ie_version >= 9) this.hasSelection = content
    } else if (!typing) {
      this.prevInput = this.textarea.value = ""
      if (ie && ie_version >= 9) this.hasSelection = null
    }
  }
 
  getField() { return this.textarea }
 
  supportsTouch() { return false }
 
  focus() {
    if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
      try { this.textarea.focus() }
      catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
    }
  }
 
  blur() { this.textarea.blur() }
 
  resetPosition() {
    this.wrapper.style.top = this.wrapper.style.left = 0
  }
 
  receivedFocus() { this.slowPoll() }
 
  // Poll for input changes, using the normal rate of polling. This
  // runs as long as the editor is focused.
  slowPoll() {
    if (this.pollingFast) return
    this.polling.set(this.cm.options.pollInterval, () => {
      this.poll()
      if (this.cm.state.focused) this.slowPoll()
    })
  }
 
  // When an event has just come in that is likely to add or change
  // something in the input textarea, we poll faster, to ensure that
  // the change appears on the screen quickly.
  fastPoll() {
    let missed = false, input = this
    input.pollingFast = true
    function p() {
      let changed = input.poll()
      if (!changed && !missed) {missed = true; input.polling.set(60, p)}
      else {input.pollingFast = false; input.slowPoll()}
    }
    input.polling.set(20, p)
  }
 
  // Read input from the textarea, and update the document to match.
  // When something is selected, it is present in the textarea, and
  // selected (unless it is huge, in which case a placeholder is
  // used). When nothing is selected, the cursor sits after previously
  // seen text (can be empty), which is stored in prevInput (we must
  // not reset the textarea when typing, because that breaks IME).
  poll() {
    let cm = this.cm, input = this.textarea, prevInput = this.prevInput
    // Since this is called a *lot*, try to bail out as cheaply as
    // possible when it is clear that nothing happened. hasSelection
    // will be the case when there is a lot of text in the textarea,
    // in which case reading its value would be expensive.
    if (this.contextMenuPending || !cm.state.focused ||
        (hasSelection(input) && !prevInput && !this.composing) ||
        cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
      return false
 
    let text = input.value
    // If nothing changed, bail.
    if (text == prevInput && !cm.somethingSelected()) return false
    // Work around nonsensical selection resetting in IE9/10, and
    // inexplicable appearance of private area unicode characters on
    // some key combos in Mac (#2689).
    if (ie && ie_version >= 9 && this.hasSelection === text ||
        mac && /[\uf700-\uf7ff]/.test(text)) {
      cm.display.input.reset()
      return false
    }
 
    if (cm.doc.sel == cm.display.selForContextMenu) {
      let first = text.charCodeAt(0)
      if (first == 0x200b && !prevInput) prevInput = "\u200b"
      if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") }
    }
    // Find the part of the input that is actually new
    let same = 0, l = Math.min(prevInput.length, text.length)
    while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same
 
    runInOp(cm, () => {
      applyTextInput(cm, text.slice(same), prevInput.length - same,
                     null, this.composing ? "*compose" : null)
 
      // Don't leave long text in the textarea, since it makes further polling slow
      if (text.length > 1000 || text.indexOf("\n") > -1) input.value = this.prevInput = ""
      else this.prevInput = text
 
      if (this.composing) {
        this.composing.range.clear()
        this.composing.range = cm.markText(this.composing.start, cm.getCursor("to"),
                                           {className: "CodeMirror-composing"})
      }
    })
    return true
  }
 
  ensurePolled() {
    if (this.pollingFast && this.poll()) this.pollingFast = false
  }
 
  onKeyPress() {
    if (ie && ie_version >= 9) this.hasSelection = null
    this.fastPoll()
  }
 
  onContextMenu(e) {
    let input = this, cm = input.cm, display = cm.display, te = input.textarea
    if (input.contextMenuPending) input.contextMenuPending()
    let pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop
    if (!pos || presto) return // Opera is difficult.
 
    // Reset the current text selection only if the click is done outside of the selection
    // and 'resetSelectionOnContextMenu' option is true.
    let reset = cm.options.resetSelectionOnContextMenu
    if (reset && cm.doc.sel.contains(pos) == -1)
      operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll)
 
    let oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText
    let wrapperBox = input.wrapper.offsetParent.getBoundingClientRect()
    input.wrapper.style.cssText = "position: static"
    te.style.cssText = `position: absolute; width: 30px; height: 30px;
      top: ${e.clientY - wrapperBox.top - 5}px; left: ${e.clientX - wrapperBox.left - 5}px;
      z-index: 1000; background: ${ie ? "rgba(255, 255, 255, .05)" : "transparent"};
      outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);`
    let oldScrollY
    if (webkit) oldScrollY = window.scrollY // Work around Chrome issue (#2712)
    display.input.focus()
    if (webkit) window.scrollTo(null, oldScrollY)
    display.input.reset()
    // Adds "Select all" to context menu in FF
    if (!cm.somethingSelected()) te.value = input.prevInput = " "
    input.contextMenuPending = rehide
    display.selForContextMenu = cm.doc.sel
    clearTimeout(display.detectingSelectAll)
 
    // Select-all will be greyed out if there's nothing to select, so
    // this adds a zero-width space so that we can later check whether
    // it got selected.
    function prepareSelectAllHack() {
      if (te.selectionStart != null) {
        let selected = cm.somethingSelected()
        let extval = "\u200b" + (selected ? te.value : "")
        te.value = "\u21da" // Used to catch context-menu undo
        te.value = extval
        input.prevInput = selected ? "" : "\u200b"
        te.selectionStart = 1; te.selectionEnd = extval.length
        // Re-set this, in case some other handler touched the
        // selection in the meantime.
        display.selForContextMenu = cm.doc.sel
      }
    }
    function rehide() {
      if (input.contextMenuPending != rehide) return
      input.contextMenuPending = false
      input.wrapper.style.cssText = oldWrapperCSS
      te.style.cssText = oldCSS
      if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos)
 
      // Try to detect the user choosing select-all
      if (te.selectionStart != null) {
        if (!ie || (ie && ie_version < 9)) prepareSelectAllHack()
        let i = 0, poll = () => {
          if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
              te.selectionEnd > 0 && input.prevInput == "\u200b") {
            operation(cm, selectAll)(cm)
          } else if (i++ < 10) {
            display.detectingSelectAll = setTimeout(poll, 500)
          } else {
            display.selForContextMenu = null
            display.input.reset()
          }
        }
        display.detectingSelectAll = setTimeout(poll, 200)
      }
    }
 
    if (ie && ie_version >= 9) prepareSelectAllHack()
    if (captureRightClick) {
      e_stop(e)
      let mouseup = () => {
        off(window, "mouseup", mouseup)
        setTimeout(rehide, 20)
      }
      on(window, "mouseup", mouseup)
    } else {
      setTimeout(rehide, 50)
    }
  }
 
  readOnlyChanged(val) {
    if (!val) this.reset()
    this.textarea.disabled = val == "nocursor"
  }
 
  setUneditable() {}
}
 
TextareaInput.prototype.needsContentAttribute = false