PageSourceSearch

https://tumentoday.ru/i/orphus/orphus.js?v=0.3

js tumentoday.ru collected 2026-10-02 05:01:39 UTC 11,067 bytes, 359 lines download raw bytes

1/*! Orphus.js | by Dmitry Koterov & Proger_XP | orphus.ru | proger.me */
2// uglifyjs -c -m --comments '/^!/' --source-map --warn orphus.js -o orphus-min.js
3;(function () {
4  "use strict";
5
6  var user = window.orphus || {}
7  var self = window.orphus = {}
8
9  self.opt = {
10    version:        '6.0.23',
11    // If prefixed with '!', the value is obfuscated by swapping every second
12    // character, e.g. '[email protected]' == '[email protected]'.
13    email:          '[email protected]',
14    homepage:       'https://github.com/ProgerXP/Orphus',
15    c_tag1:         '<!!!>',
16    c_tag2:         '<!!!>',
17    contextLength:  60,   // max length of ?c_pre and ?c_suf.
18    maxSelection:   256,  // max ?c_sel.
19    action:         '/orphus/',
20    maxWidth:       650,  // of <div id="orphusp">.
21    strings:        {     // localizable.
22	  alt:          'Выделите орфографическую ошибку мышью и нажмите Ctrl+Enter. Сделаем наши тексты чище!',
23	  badbrowser:   'Ваш браузер не поддерживает возможность перехвата выделенного текста или IFRAME. Возможно, он слишком старый, а, может быть, произошла какая-нибудь другая ошибка.',
24	  toobig:       'Вы выбрали слишком большой фрагмент текста.',
25	  subject:      'Сообщение от Orphus',
26	  intextmsg:    'Орфографическая ошибка в этом фрагменте:',
27	  ifsendmsg:    'Послать сообщение об ошибке авторам? Ваш браузер останется на этой же странице.',
28	  gohome:       'Или, может, вы хотите посетить домашнюю страницу Orphus (в новой вкладке)?',
29	  author:       'Дмитрий Котеров и Proger_XP',
30	  send:         'Отправить',
31	  cancel:       'Отмена',
32	  entercmnt:    'Ваш комментарий (необязательно):',
33	  submitex:     'Проблема при отправке сообщения:'
34    }
35  }
36
37  var assign = function (dest, src) {
38    for (var k in src) {
39      if (k == 'strings') {
40        assign(dest[k], src[k])
41      } else {
42        dest[k] = src[k]
43      }
44    }
45  }
46
47  assign(self.opt, user)
48
49  var docEl = document.documentElement
50  var body = document.body
51
52  self.iframe = null
53  self.submitted = false
54  self.lastComment = ''
55
56  self.deobfuscate = function (s) {
57    if (s.substr(0, 1) == '!') {
58      s = s.substr(1).replace(/(.)(.)/g, '$2$1')
59    }
60    return s
61  }
62
63  self.run = function () {
64    document.onkeypress = self.onkeypress
65  }
66
67  self.addOffScreen = function (node) {
68    node.style.position = 'absolute'
69    node.style.top = '-10000px'
70    body.lastChild
71      ? body.insertBefore(node, body.lastChild)
72      : body.appendChild(node)
73    return node
74  }
75
76  self.createIFrame = function (name) {
77    var div = document.createElement('DIV')
78    div.innerHTML = '<iframe name="' + name + '"></iframe>'
79    return self.addOffScreen(div)
80  }
81
82  self.submit = function (refURL, sel, comment) {
83    var name = 'orphus_ifr'
84    self.iframe = self.iframe || self.createIFrame(name)
85
86    var form = document.createElement('FORM')
87    form.action = self.opt.action
88    form.method = 'post'
89    form.target = name
90
91    var query = {
92      version:  self.opt.version,
93      email:    self.deobfuscate(self.opt.email),
94      to:       self.opt.strings.to,
95      subject:  self.opt.strings.subject,
96      ref:      refURL,
97      c_pre:    sel.pre,
98      c_sel:    sel.text,
99      c_suf:    sel.suf,
100      c_pos:    sel.pos,
101      c_tag1:   self.opt.c_tag1,
102      c_tag2:   self.opt.c_tag2,
103      charset:  document.charset || document.characterSet || '',
104      comment:  comment
105    }
106
107    for (var name in query) {
108      var input = document.createElement('INPUT')
109      input.type = 'hidden'
110      input.name = name
111      input.value = query[name]
112      form.appendChild(input)
113    }
114
115    self.addOffScreen(form)
116    form.submit()
117    form.parentNode.removeChild(form)
118  }
119
120  self.windowInfo = function () {
121    var width = 0
122    var height = 0
123
124    if (typeof window.innerWidth == 'number') {
125      width = window.innerWidth
126      height = window.innerHeight
127    } else if (docEl && (docEl.clientWidth || docEl.clientHeight)) {
128      width = docEl.clientWidth
129      height = docEl.clientHeight
130    } else if (body && (body.clientWidth || body.clientHeight)) {
131      width = body.clientWidth
132      height = body.clientHeight
133    }
134
135    var scrollLeft = 0
136    var scrollTop = 0
137
138    if (typeof window.pageYOffset == 'number') {
139      scrollTop = window.pageYOffset
140      scrollLeft = window.pageXOffset
141    } else if (body && (body.scrollLeft || body.scrollTop)) {
142      scrollTop = body.scrollTop
143      scrollLeft = body.scrollLeft
144    } else if (docEl && (docEl.scrollLeft || docEl.scrollTop)) {
145      scrollTop = docEl.scrollTop
146      scrollLeft = docEl.scrollLeft
147    }
148
149    return {
150      width:        width,
151      height:       height,
152      scrollLeft:   scrollLeft,
153      scrollTop:    scrollTop
154    }
155  }
156
157  self.showFor = function (context, submit) {
158    if (self.submitted) { return }
159
160    self.submitted = true
161    var div = document.createElement('DIV')
162    var width = Math.min(self.opt.maxWidth, body.clientWidth)
163
164    div.innerHTML =
165      '<div id="orphusp" style="width: ' + width + 'px">' +
166        '<a class="logo" href="' + self.opt.homepage + '" target="_blank">Orphus</a>' +
167        '<div class="legend">' + self.opt.strings.intextmsg + '</div>' +
168        '<div class="fragment">' +
169          context
170            .replace(self.opt.c_tag1, '<mark>')
171            .replace(self.opt.c_tag2, '</mark>') +
172        '</div>' +
173        '<div class="hint">' +
174          self.opt.strings.ifsendmsg.replace(/\r?\n/, '<br>') +
175        '</div>' +
176        '<form>' +
177          '<div class="comment">' + self.opt.strings.entercmnt + '</div>' +
178          '<input type="text" maxlength="250">' +
179          '<div class="buttons">' +
180            '<input type="submit" value="' + self.opt.strings.send + '">' +
181            '&nbsp;' +
182            '<input type="button" value="' + self.opt.strings.cancel + '">' +
183          '</div>' +
184        '</form>' +
185      '</div>'
186
187    self.addOffScreen(div)
188    var inputs = div.getElementsByTagName('input')
189    var forms = div.getElementsByTagName('form')
190    var commentInput = inputs[0]
191    var origOnKeyDown = null
192
193    var end = function () {
194      document.onkeydown = origOnKeyDown
195      origOnKeyDown = null
196      div.parentNode.removeChild(div)
197      self.submitted = false
198      self.lastComment = commentInput.value
199    }
200
201    setTimeout(function () {
202      var divWidth = div.clientWidth
203      var divHeight = div.clientHeight
204      var win = self.windowInfo()
205
206      var x = (win.width  - divWidth)  / 2 + win.scrollLeft
207      var y = (win.height - divHeight) / 2 + win.scrollTop
208      div.style.left = x + 'px'
209      div.style.top  = y + 'px'
210
211      commentInput.value = self.lastComment
212      commentInput.focus()
213      commentInput.select()
214      origOnKeyDown = document.onkeydown
215
216      document.onkeydown = function (e) {
217        e = e || window.event
218        if (e.keyCode == 27) { end() }
219      }
220
221      forms[0].onsubmit = function () {
222        try {
223          submit(commentInput.value)
224        } catch (e) {
225          alert(self.opt.strings.submitex + '\n\n' + e)
226        }
227        end()
228        self.lastComment = ''
229        return false
230      }
231
232      inputs[2].onclick = end
233    }, 10)
234  }
235
236  self.cleanString = function (s) {
237    return ('' + s).replace(/[\r\n]+/g, ' ').replace(/^\s+|\s+$/g, '')
238  }
239
240  self.getSelection = function () {
241    var docSel = null
242
243    if (window.getSelection) {
244      docSel = window.getSelection()
245    } else if (document.getSelection) {
246      docSel = document.getSelection()
247    } else {
248      docSel = document.selection
249    }
250
251    if (docSel == null) { throw 'null getSelection()' }
252
253    var pre = ''
254    var text = null
255    var suf = ''
256    var pos = -1
257
258    if (docSel.getRangeAt) {
259      if (!docSel.rangeCount) { return }
260      var range = docSel.getRangeAt(0)
261      text = range.toString()
262      var newRange = document.createRange()
263      newRange.setStartBefore(range.startContainer.ownerDocument.body)
264      newRange.setEnd(range.startContainer, range.startOffset)
265      pre = newRange.toString()
266      var newRange = range.cloneRange()
267      newRange.setStart(range.endContainer, range.endOffset)
268      newRange.setEndAfter(range.endContainer.ownerDocument.body)
269      suf = newRange.toString()
270    } else if (docSel.createRange) {
271      var range = docSel.createRange()
272      text = range.text
273      var newRange = docSel.createRange()
274      newRange.moveStart('character', -self.opt.contextLength)
275      newRange.moveEnd('character', -text.length)
276      pre = newRange.text
277      var newRange = docSel.createRange()
278      newRange.moveEnd('character', self.opt.contextLength)
279      newRange.moveStart('character', text.length)
280      suf = newRange.text
281    } else {
282      text = '' + docSel
283    }
284
285    var p
286    var s = (p = text.match(/^(\s*)/)) && p[0].length
287    var e = (p = text.match(/(\s*)$/)) && p[0].length
288    pre = pre + text.substring(0, s)
289    suf = text.substring(text.length - e, text.length) + suf
290    text = text.substring(s, text.length - e)
291
292    if (text != '') {
293      return {
294        pre:  pre,
295        text: text,
296        suf:  suf,
297        pos:  pos
298      }
299    }
300  }
301
302  self.show = function () {
303    try {
304      var sel = self.getSelection()
305    } catch (e) {
306      alert(self.opt.strings.badbrowser)
307      return
308    }
309
310    if (!sel) {
311      var msg = [
312        self.opt.strings.name + ' v' + self.opt.version,
313        self.opt.strings.author,
314        '',
315        self.opt.strings.alt,
316        '',
317        self.opt.strings.gohome,
318      ]
319
320      if (confirm(msg.join('\n'))) {
321        window.open(self.opt.homepage, '_blank')
322      }
323
324      return
325    }
326
327    sel.pre = sel.pre.substring(sel.pre.length - self.opt.contextLength, sel.pre.length).replace(/^\S{1,10}\s+/, '')
328    sel.suf = sel.suf.substring(0, self.opt.contextLength).replace(/\s+\S{1,10}$/, '')
329    var context = self.cleanString(sel.pre + self.opt.c_tag1 + sel.text + self.opt.c_tag2 + sel.suf)
330
331    if (context.length > self.opt.maxSelection) {
332      alert(self.opt.strings.toobig)
333    } else {
334      self.showFor(context, function (comment) {
335        self.submit(document.location.href, sel, comment)
336      })
337    }
338  }
339
340  self.onkeypress = function (e) {
341    var handle = false
342    var we = window.event
343
344    if (we) {
345      handle = we.keyCode == 10 || (we.keyCode == 13 && we.ctrlKey)
346    } else if (e) {
347      handle = (e.which == 10 && e.modifiers == 2) ||
348               (e.keyCode == 0 && e.charCode == 106 && e.ctrlKey) ||
349               (e.keyCode == 13 && e.ctrlKey)
350    }
351
352    if (handle) {
353      self.show()
354      return false
355    }
356  }
357
358  self.run()
359})();

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.