PageSourceSearch

https://www.fresh2refresh.com/wp-content/plugins/urvanov-syntax-hi…rvanov_syntax_highlighter.min.js?ver=2.8.28

js fresh2refresh.com collected 2026-09-25 14:27:25 UTC 64,826 bytes, 1,525 lines download raw bytes

1// To avoid duplicates conflicting
2var jQueryUrvanovSyntaxHighlighter = jQuery;
3
4(function ($) {
5
6    UrvanovSyntaxHighlighterUtil = new function () {
7
8        var base = this;
9        var settings = null;
10
11        base.init = function () {
12            settings = UrvanovSyntaxHighlighterSyntaxSettings;
13            base.initGET();
14        };
15
16        base.addPrefixToID = function (id) {
17            return id.replace(/^([#.])?(.*)$/, '$1' + settings.prefix + '$2');
18        };
19
20        base.removePrefixFromID = function (id) {
21            var re = new RegExp('^[#.]?' + settings.prefix, 'i');
22            return id.replace(re, '');
23        };
24
25        base.cssElem = function (id) {
26            return $(base.addPrefixToID(id));
27        };
28
29        base.setDefault = function (v, d) {
30            return (typeof v == 'undefined') ? d : v;
31        };
32
33        base.setMax = function (v, max) {
34            return v <= max ? v : max;
35        };
36
37        base.setMin = function (v, min) {
38            return v >= min ? v : min;
39        };
40
41        base.setRange = function (v, min, max) {
42            return base.setMax(base.setMin(v, min), max);
43        };
44
45        base.getExt = function (str) {
46            if (str.indexOf('.') == -1) {
47                return undefined;
48            }
49            var ext = str.split('.');
50            if (ext.length) {
51                ext = ext[ext.length - 1];
52            } else {
53                ext = '';
54            }
55            return ext;
56        };
57
58        base.initGET = function () {
59            // URLs
60            window.currentURL = window.location.protocol + '//' + window.location.host + window.location.pathname;
61            window.currentDir = window.currentURL.substring(0, window.currentURL.lastIndexOf('/'));
62
63            // http://stackoverflow.com/questions/439463
64            function getQueryParams(qs) {
65                qs = qs.split("+").join(" ");
66                var params = {}, tokens, re = /[?&]?([^=]+)=([^&]*)/g;
67                while (tokens = re.exec(qs)) {
68                    params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
69                }
70                return params;
71            }
72
73            window.GET = getQueryParams(document.location.search);
74        };
75
76        base.getAJAX = function (args, callback) {
77            args.version = settings.version;
78            $.get(settings.ajaxurl, args, callback);
79        };
80        
81        /**
82         * @param {String} HTML representing any number of sibling elements
83         * @return {NodeList} 
84         */
85        base.htmlToElements = function (html) {
86            return $.parseHTML(html, document, true);
87        }
88
89
90        base.postAJAX = function (args, callback) {
91            args.version = settings.version;
92            $.post(settings.ajaxurl, args, callback);
93        };
94
95        base.reload = function () {
96            var get = '?';
97            for (var i in window.GET) {
98                get += i + '=' + window.GET[i] + '&';
99            }
100            window.location = window.currentURL + get;
101        };
102
103        base.escape = function (string) {
104            if (typeof encodeURIComponent == 'function') {
105                return encodeURIComponent(string);
106            } else if (typeof escape != 'function') {
107                return escape(string);
108            } else {
109                return string;
110            }
111        };
112
113        base.log = function (string) {
114            if (typeof console != 'undefined' && settings && settings.debug) {
115                console.log(string);
116            }
117        };
118
119        base.decode_html = function (str) {
120            return String(str).replace(/&lt;/g, '<').replace(
121                /&gt;/g, '>').replace(/&amp;/g, '&');
122        };
123
124        base.encode_html = function (str) {
125            return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(
126                />/g, '&gt;');
127        };
128
129        /**
130         * Returns either black or white to ensure this color is distinguishable with the given RGB hex.
131         * This function can be used to create a readable foreground color given a background color, or vice versa.
132         * It forms a radius around white where black is returned. Outside this radius, white is returned.
133         *
134         * @param hex An RGB hex (e.g. "#FFFFFF")
135         * @requires jQuery and TinyColor
136         * @param args The argument object. Properties:
137         *      amount: a value in the range [0,1]. If the distance of the given hex from white exceeds this value,
138         *          white is returned. Otherwise, black is returned.
139         *      xMulti: a multiplier to the distance in the x-axis.
140         *      yMulti: a multiplier to the distance in the y-axis.
141         *      normalizeHue: either falsey or an [x,y] array range. If hex is a colour with hue in this range,
142         *          then normalizeHueXMulti and normalizeHueYMulti are applied.
143         *      normalizeHueXMulti: a multiplier to the distance in the x-axis if hue is normalized.
144         *      normalizeHueYMulti: a multiplier to the distance in the y-axis if hue is normalized.
145         * @return the RGB hex string of black or white.
146         */
147        base.getReadableColor = function (hex, args) {
148            args = $.extend({
149                amount: 0.5,
150                xMulti: 1,
151                // We want to achieve white a bit sooner in the y axis
152                yMulti: 1.5,
153                normalizeHue: [20, 180],
154                // For colors that appear lighter (yellow, green, light blue) we reduce the distance in the x direction,
155                // stretching the radius in the x axis allowing more black than before.
156                normalizeHueXMulti: 1 / 2.5,
157                normalizeHueYMulti: 1
158            }, args);
159            var color = tinycolor(hex);
160            var hsv = color.toHsv();
161            // Origin is white
162            var coord = {x: hsv.s, y: 1 - hsv.v};
163            // Multipliers
164            coord.x *= args.xMulti;
165            coord.y *= args.yMulti;
166            if (args.normalizeHue && hsv.h > args.normalizeHue[0] && hsv.h < args.normalizeHue[1]) {
167                coord.x *= args.normalizeHueXMulti;
168                coord.y *= args.normalizeHueYMulti;
169            }
170            var dist = Math.sqrt(Math.pow(coord.x, 2) + Math.pow(coord.y, 2));
171            if (dist < args.amount) {
172                hsv.v = 0; // black
173            } else {
174                hsv.v = 1; // white
175            }
176            hsv.s = 0;
177            return tinycolor(hsv).toHexString();
178        };
179
180        base.removeChars = function (chars, str) {
181            var re = new RegExp('[' + chars + ']', 'gmi');
182            return str.replace(re, '');
183        }
184
185    };
186
187    $(document).ready(function () {
188        UrvanovSyntaxHighlighterUtil.init();
189    });
190
191    // http://stackoverflow.com/questions/2360655/jquery-event-handlers-always-execute-in-order-they-were-bound-any-way-around-t
192
193    // [name] is the name of the event "click", "mouseover", ..
194    // same as you'd pass it to bind()
195    // [fn] is the handler function
196    $.fn.bindFirst = function (name, fn) {
197        // bind as you normally would
198        // don't want to miss out on any jQuery magic
199        this.bind(name, fn);
200        // Thanks to a comment by @Martin, adding support for
201        // namespaced events too.
202        var handlers = this.data('events')[name.split('.')[0]];
203        // take out the handler we just inserted from the end
204        var handler = handlers.pop();
205        // move it at the beginning
206        handlers.splice(0, 0, handler);
207    };
208
209    // http://stackoverflow.com/questions/4079274/how-to-get-an-objects-properties-in-javascript-jquery
210    $.keys = function (obj) {
211        var keys = [];
212        for (var key in obj) {
213            keys.push(key);
214        }
215        return keys;
216    }
217
218    // Prototype modifications
219
220    RegExp.prototype.execAll = function (string) {
221        var matches = [];
222        var match = null;
223        while ((match = this.exec(string)) != null) {
224            var matchArray = [];
225            for (var i in match) {
226                if (parseInt(i) == i) {
227                    matchArray.push(match[i]);
228                }
229            }
230            matches.push(matchArray);
231        }
232        return matches;
233    };
234
235    // Escape regex chars with \
236    RegExp.prototype.escape = function (text) {
237        return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
238    };
239
240    String.prototype.sliceReplace = function (start, end, repl) {
241        return this.substring(0, start) + repl + this.substring(end);
242    };
243
244    String.prototype.escape = function () {
245        var tagsToReplace = {
246            '&': '&amp;',
247            '<': '&lt;',
248            '>': '&gt;'
249        };
250        return this.replace(/[&<>]/g, function (tag) {
251            return tagsToReplace[tag] || tag;
252        });
253    };
254
255    String.prototype.linkify = function (target) {
256        target = typeof target != 'undefined' ? target : '';
257        return this.replace(/(http(s)?:\/\/(\S)+)/gmi, '<a href="$1" target="' + target + '">$1</a>');
258    };
259
260    String.prototype.toTitleCase = function () {
261        var parts = this.split(/\s+/);
262        var title = '';
263        $.each(parts, function (i, part) {
264            if (part != '') {
265                title += part.slice(0, 1).toUpperCase() + part.slice(1, part.length);
266                if (i != parts.length - 1 && parts[i + 1] != '') {
267                    title += ' ';
268                }
269            }
270        });
271        return title;
272    };
273
274})(jQueryUrvanovSyntaxHighlighter);
275// Default Settings
276jqueryPopup = Object();
277jqueryPopup.defaultSettings = {
278		centerBrowser:0, // center window over browser window? {1 (YES) or 0 (NO)}. overrides top and left
279		centerScreen:0, // center window over entire screen? {1 (YES) or 0 (NO)}. overrides top and left
280		height:500, // sets the height in pixels of the window.
281		left:0, // left position when the window appears.
282		location:0, // determines whether the address bar is displayed {1 (YES) or 0 (NO)}.
283		menubar:0, // determines whether the menu bar is displayed {1 (YES) or 0 (NO)}.
284		resizable:0, // whether the window can be resized {1 (YES) or 0 (NO)}. Can also be overloaded using resizable.
285		scrollbars:0, // determines whether scrollbars appear on the window {1 (YES) or 0 (NO)}.
286		status:0, // whether a status line appears at the bottom of the window {1 (YES) or 0 (NO)}.
287		width:500, // sets the width in pixels of the window.
288		windowName:null, // name of window set from the name attribute of the element that invokes the click
289		windowURL:null, // url used for the popup
290		top:0, // top position when the window appears.
291		toolbar:0, // determines whether a toolbar (includes the forward and back buttons) is displayed {1 (YES) or 0 (NO)}.
292		data:null,
293		event:'click'
294	};
295
296(function ($) {
297
298	popupWindow = function (object, instanceSettings, beforeCallback, afterCallback) {
299		beforeCallback = typeof beforeCallback !== 'undefined' ? beforeCallback : null;
300		afterCallback = typeof afterCallback !== 'undefined' ? afterCallback : null;
301	
302		if (typeof object == 'string') {
303			object = jQuery(object);
304		}
305		if (!(object instanceof jQuery)) {
306			return false;
307		}
308		var settings = jQuery.extend({}, jqueryPopup.defaultSettings, instanceSettings || {});
309		object.handler = jQuery(object).bind(settings.event, function() {
310			
311			if (beforeCallback) {
312				beforeCallback();
313			}
314			
315			var windowFeatures =    'height=' + settings.height +
316									',width=' + settings.width +
317									',toolbar=' + settings.toolbar +
318									',scrollbars=' + settings.scrollbars +
319									',status=' + settings.status + 
320									',resizable=' + settings.resizable +
321									',location=' + settings.location +
322									',menuBar=' + settings.menubar;
323		
324			settings.windowName = settings.windowName || jQuery(this).attr('name');
325			var href = jQuery(this).attr('href');
326			if (!settings.windowURL && !(href == '#') && !(href == '')) {
327				settings.windowURL = jQuery(this).attr('href');
328			}
329			
330			var centeredY,centeredX;
331			
332			var win = null;
333			if (settings.centerBrowser) {
334				if (typeof window.screenY == 'undefined') {// not defined for old IE versions
335					centeredY = (window.screenTop - 120) + ((((document.documentElement.clientHeight + 120)/2) - (settings.height/2)));
336					centeredX = window.screenLeft + ((((document.body.offsetWidth + 20)/2) - (settings.width/2)));
337				} else {
338					centeredY = window.screenY + (((window.outerHeight/2) - (settings.height/2)));
339					centeredX = window.screenX + (((window.outerWidth/2) - (settings.width/2)));
340				}
341				win = window.open(settings.windowURL, settings.windowName, windowFeatures+',left=' + centeredX +',top=' + centeredY);
342			} else if (settings.centerScreen) {
343				centeredY = (screen.height - settings.height)/2;
344				centeredX = (screen.width - settings.width)/2;
345				win = window.open(settings.windowURL, settings.windowName, windowFeatures+',left=' + centeredX +',top=' + centeredY);
346			} else {
347				win = window.open(settings.windowURL, settings.windowName, windowFeatures+',left=' + settings.left +',top=' + settings.top);
348			}
349			if (win != null) {
350				win.focus();
351				if (settings.data) {
352					win.document.write(settings.data);
353				}
354			}
355			
356			if (afterCallback) {
357				afterCallback();
358			}
359		});
360		return settings;
361	};
362
363	popdownWindow = function(object, event) {
364		if (typeof event == 'undefined') {
365			event = 'click';
366		}
367		object = jQuery(object);
368		if (!(object instanceof jQuery)) {
369			return false;
370		}
371		object.unbind(event, object.handler);
372	};
373
374})(jQueryUrvanovSyntaxHighlighter);
375
376// Urvanov Syntax Highlighter JavaScript
377
378(function ($) {
379
380
381	
382    // BEGIN AUXILIARY FUNCTIONS
383
384    $.fn.exists = function () {
385        return this.length !== 0;
386    };
387
388    $.fn.style = function (styleName, value, priority) {
389        // DOM node
390        var node = this.get(0);
391        // Ensure we have a DOM node
392        if (typeof node == 'undefined') {
393            return;
394        }
395        // CSSStyleDeclaration
396        var style = node.style;
397        // Getter/Setter
398        if (typeof styleName != 'undefined') {
399            if (typeof value != 'undefined') {
400                // Set style property
401                priority = typeof priority != 'undefined' ? priority : '';
402                if (typeof style.setProperty != 'undefined') {
403                    style.setProperty(styleName, value, priority);
404                } else {
405                    // XXX Using priority breaks on IE 7 & 8
406//                    if (priority) {
407//                        value = value + ' !' + priority;
408//                    }
409                    style[styleName] = value;
410                }
411            } else {
412                // Get style property
413                return style[styleName];
414            }
415        } else {
416            // Get CSSStyleDeclaration
417            return style;
418        }
419    };
420
421    // END AUXILIARY FUNCTIONS
422
423    var PRESSED = 'crayon-pressed';
424    var UNPRESSED = '';
425
426    var URVANOV_SYNTAX_HIGHLIGHTER_SYNTAX = 'div.urvanov-syntax-highlighter-syntax';
427    var URVANOV_SYNTAX_HIGHLIGHTER_TOOLBAR = '.crayon-toolbar';
428    var URVANOV_SYNTAX_HIGHLIGHTER_INFO = '.crayon-info';
429    var URVANOV_SYNTAX_HIGHLIGHTER_PLAIN = '.urvanov-syntax-highlighter-plain';
430    var URVANOV_SYNTAX_HIGHLIGHTER_MAIN = '.urvanov-syntax-highlighter-main';
431    var URVANOV_SYNTAX_HIGHLIGHTER_TABLE = '.crayon-table';
432    var URVANOV_SYNTAX_HIGHLIGHTER_LOADING = '.urvanov-syntax-highlighter-loading';
433    var URVANOV_SYNTAX_HIGHLIGHTER_CODE = '.urvanov-syntax-highlighter-code';
434    var URVANOV_SYNTAX_HIGHLIGHTER_TITLE = '.crayon-title';
435    var URVANOV_SYNTAX_HIGHLIGHTER_TOOLS = '.crayon-tools';
436    var URVANOV_SYNTAX_HIGHLIGHTER_NUMS = '.crayon-nums';
437    var URVANOV_SYNTAX_HIGHLIGHTER_NUM = '.crayon-num';
438    var URVANOV_SYNTAX_HIGHLIGHTER_LINE = '.crayon-line';
439    var URVANOV_SYNTAX_HIGHLIGHTER_WRAPPED = 'urvanov-syntax-highlighter-wrapped';
440    var URVANOV_SYNTAX_HIGHLIGHTER_NUMS_CONTENT = '.urvanov-syntax-highlighter-nums-content';
441    var URVANOV_SYNTAX_HIGHLIGHTER_NUMS_BUTTON = '.urvanov-syntax-highlighter-nums-button';
442    var URVANOV_SYNTAX_HIGHLIGHTER_WRAP_BUTTON = '.urvanov-syntax-highlighter-wrap-button';
443    var URVANOV_SYNTAX_HIGHLIGHTER_EXPAND_BUTTON = '.urvanov-syntax-highlighter-expand-button';
444    var URVANOV_SYNTAX_HIGHLIGHTER_EXPANDED = 'urvanov-syntax-highlighter-expanded urvanov-syntax-highlighter-toolbar-visible';
445    var URVANOV_SYNTAX_HIGHLIGHTER_PLACEHOLDER = 'urvanov-syntax-highlighter-placeholder';
446    var URVANOV_SYNTAX_HIGHLIGHTER_POPUP_BUTTON = '.urvanov-syntax-highlighter-popup-button';
447    var URVANOV_SYNTAX_HIGHLIGHTER_COPY_BUTTON = '.urvanov-syntax-highlighter-copy-button';
448    var URVANOV_SYNTAX_HIGHLIGHTER_PLAIN_BUTTON = '.urvanov-syntax-highlighter-plain-button';
449
450    UrvanovSyntaxHighlighterSyntax = new function () {
451        var base = this;
452        var urvanov_syntax_highlighters = new Object();
453        var settings;
454        var strings;
455        var currUID = 0;
456        var touchscreen;
457
458        base.init = function () {
459            if (typeof urvanov_syntax_highlighters == 'undefined') {
460                urvanov_syntax_highlighters = new Object();
461            }
462            settings = UrvanovSyntaxHighlighterSyntaxSettings;
463            strings = UrvanovSyntaxHighlighterSyntaxStrings;
464            $(URVANOV_SYNTAX_HIGHLIGHTER_SYNTAX).each(function () {
465                base.process(this);
466            });
467        };
468
469        base.process = function (c, replace) {
470            c = $(c);
471            var uid = c.attr('id');
472            if (uid == 'urvanov-syntax-highlighter-') {
473                // No ID, generate one
474                uid += getUID();
475            }
476            c.attr('id', uid);
477            UrvanovSyntaxHighlighterUtil.log(uid);
478
479            if (typeof replace == 'undefined') {
480                replace = false;
481            }
482
483            if (!replace && !makeUID(uid)) {
484                // Already a UrvanovSyntaxHighlighter
485                return;
486            }
487
488            var toolbar = c.find(URVANOV_SYNTAX_HIGHLIGHTER_TOOLBAR);
489            var info = c.find(URVANOV_SYNTAX_HIGHLIGHTER_INFO);
490            var plain = c.find(URVANOV_SYNTAX_HIGHLIGHTER_PLAIN);
491            var main = c.find(URVANOV_SYNTAX_HIGHLIGHTER_MAIN);
492            var table = c.find(URVANOV_SYNTAX_HIGHLIGHTER_TABLE);
493            var code = c.find(URVANOV_SYNTAX_HIGHLIGHTER_CODE);
494            var title = c.find(URVANOV_SYNTAX_HIGHLIGHTER_TITLE);
495            var tools = c.find(URVANOV_SYNTAX_HIGHLIGHTER_TOOLS);
496            var nums = c.find(URVANOV_SYNTAX_HIGHLIGHTER_NUMS);
497            var numsContent = c.find(URVANOV_SYNTAX_HIGHLIGHTER_NUMS_CONTENT);
498            var numsButton = c.find(URVANOV_SYNTAX_HIGHLIGHTER_NUMS_BUTTON);
499            var wrapButton = c.find(URVANOV_SYNTAX_HIGHLIGHTER_WRAP_BUTTON);
500            var expandButton = c.find(URVANOV_SYNTAX_HIGHLIGHTER_EXPAND_BUTTON);
501            var popupButton = c.find(URVANOV_SYNTAX_HIGHLIGHTER_POPUP_BUTTON);
502            var copyButton = c.find(URVANOV_SYNTAX_HIGHLIGHTER_COPY_BUTTON);
503            var plainButton = c.find(URVANOV_SYNTAX_HIGHLIGHTER_PLAIN_BUTTON);
504
505            urvanov_syntax_highlighters[uid] = c;
506            urvanov_syntax_highlighters[uid].toolbar = toolbar;
507            urvanov_syntax_highlighters[uid].plain = plain;
508            urvanov_syntax_highlighters[uid].info = info;
509            urvanov_syntax_highlighters[uid].main = main;
510            urvanov_syntax_highlighters[uid].table = table;
511            urvanov_syntax_highlighters[uid].code = code;
512            urvanov_syntax_highlighters[uid].title = title;
513            urvanov_syntax_highlighters[uid].tools = tools;
514            urvanov_syntax_highlighters[uid].nums = nums;
515            urvanov_syntax_highlighters[uid].nums_content = numsContent;
516            urvanov_syntax_highlighters[uid].numsButton = numsButton;
517            urvanov_syntax_highlighters[uid].wrapButton = wrapButton;
518            urvanov_syntax_highlighters[uid].expandButton = expandButton;
519            urvanov_syntax_highlighters[uid].popup_button = popupButton;
520            urvanov_syntax_highlighters[uid].copy_button = copyButton;
521            urvanov_syntax_highlighters[uid].plainButton = plainButton;
522            urvanov_syntax_highlighters[uid].numsVisible = true;
523            urvanov_syntax_highlighters[uid].wrapped = false;
524            urvanov_syntax_highlighters[uid].plainVisible = false;
525
526            urvanov_syntax_highlighters[uid].toolbar_delay = 0;
527            urvanov_syntax_highlighters[uid].time = 1;
528
529            // Set plain
530            $(URVANOV_SYNTAX_HIGHLIGHTER_PLAIN).css('z-index', 0);
531
532            // XXX Remember CSS dimensions
533            var mainStyle = main.style();
534            urvanov_syntax_highlighters[uid].mainStyle = {
535                'height': mainStyle && mainStyle.height || '',
536                'max-height': mainStyle && mainStyle.maxHeight || '',
537                'min-height': mainStyle && mainStyle.minHeight || '',
538                'width': mainStyle && mainStyle.width || '',
539                'max-width': mainStyle && mainStyle.maxWidth || '',
540                'min-width': mainStyle && mainStyle.minWidth || ''
541            };
542            urvanov_syntax_highlighters[uid].mainHeightAuto = urvanov_syntax_highlighters[uid].mainStyle.height == '' && urvanov_syntax_highlighters[uid].mainStyle['max-height'] == '';
543
544            var load_timer;
545            var i = 0;
546            urvanov_syntax_highlighters[uid].loading = true;
547            urvanov_syntax_highlighters[uid].scrollBlockFix = false;
548
549            // Register click events
550            numsButton.click(function () {
551                UrvanovSyntaxHighlighterSyntax.toggleNums(uid);
552            });
553            wrapButton.click(function () {
554                UrvanovSyntaxHighlighterSyntax.toggleWrap(uid);
555            });
556            expandButton.click(function () {
557                UrvanovSyntaxHighlighterSyntax.toggleExpand(uid);
558            });
559            plainButton.click(function () {
560                UrvanovSyntaxHighlighterSyntax.togglePlain(uid);
561            });
562            copyButton.click(function () {
563                UrvanovSyntaxHighlighterSyntax.copyPlain(uid);
564            });
565
566            // Enable retina if supported
567            retina(uid);
568
569            var load_func = function () {
570                // If nums hidden by default
571                if (nums.filter('[data-settings~="hide"]').length != 0) {
572                    numsContent.ready(function () {
573                        UrvanovSyntaxHighlighterUtil.log('function' + uid);
574                        UrvanovSyntaxHighlighterSyntax.toggleNums(uid, true, true);
575                    });
576                } else {
577                    updateNumsButton(uid);
578                }
579
580                if (typeof urvanov_syntax_highlighters[uid].expanded == 'undefined') {
581                    // Determine if we should enable code expanding toggling
582                    if (Math.abs(urvanov_syntax_highlighters[uid].main.outerWidth() - urvanov_syntax_highlighters[uid].table.outerWidth()) < 10) {
583                        urvanov_syntax_highlighters[uid].expandButton.hide();
584                    } else {
585                        urvanov_syntax_highlighters[uid].expandButton.show();
586                    }
587                }
588
589                // TODO If width has changed or timeout, stop timer
590                if (/*last_num_width != nums.outerWidth() ||*/ i == 5) {
591                    clearInterval(load_timer);
592                    //urvanov_syntax_highlighters[uid].removeClass(URVANOV_SYNTAX_HIGHLIGHTER_LOADING);
593                    urvanov_syntax_highlighters[uid].loading = false;
594                }
595                i++;
596            };
597            load_timer = setInterval(load_func, 300);
598            fixScrollBlank(uid);
599
600            // Add ref to num for each line
601            $(URVANOV_SYNTAX_HIGHLIGHTER_NUM, urvanov_syntax_highlighters[uid]).each(function () {
602                var lineID = $(this).attr('data-line');
603                var line = $('#' + lineID);
604                var height = line.style('height');
605                if (height) {
606                    line.attr('data-height', height);
607                }
608            });
609
610            // Used for toggling
611            main.css('position', 'relative');
612            main.css('z-index', 1);
613
614            // Disable certain features for touchscreen devices
615            touchscreen = (c.filter('[data-settings~="touchscreen"]').length != 0);
616
617            // Used to hide info
618            if (!touchscreen) {
619                main.click(function () {
620                    urvanovSyntaxHighlighterInfo(uid, '', false);
621                });
622                plain.click(function () {
623                    urvanovSyntaxHighlighterInfo(uid, '', false);
624                });
625                info.click(function () {
626                    urvanovSyntaxHighlighterInfo(uid, '', false);
627                });
628            }
629
630            // Used for code popup
631            if (c.filter('[data-settings~="no-popup"]').length == 0) {
632                urvanov_syntax_highlighters[uid].popup_settings = popupWindow(popupButton, {
633                    height: screen.height - 200,
634                    width: screen.width - 100,
635                    top: 75,
636                    left: 50,
637                    scrollbars: 1,
638                    windowURL: '',
639                    data: '' // Data overrides URL
640                }, function () {
641                    codePopup(uid);
642                }, function () {
643                    //UrvanovSyntaxHighlighterUtil.log('after');
644                });
645            }
646
647            plain.css('opacity', 0);
648
649            urvanov_syntax_highlighters[uid].toolbarVisible = true;
650            urvanov_syntax_highlighters[uid].hasOneLine = table.outerHeight() < toolbar.outerHeight() * 2;
651            urvanov_syntax_highlighters[uid].toolbarMouseover = false;
652            // If a toolbar with mouseover was found
653            if (toolbar.filter('[data-settings~="mouseover"]').length != 0 && !touchscreen) {
654                urvanov_syntax_highlighters[uid].toolbarMouseover = true;
655                urvanov_syntax_highlighters[uid].toolbarVisible = false;
656
657                toolbar.css('margin-top', '-' + toolbar.outerHeight() + 'px');
658                toolbar.hide();
659                // Overlay the toolbar if needed, only if doing so will not hide the
660                // whole code!
661                if (toolbar.filter('[data-settings~="overlay"]').length != 0
662                    && !urvanov_syntax_highlighters[uid].hasOneLine) {
663                    toolbar.css('position', 'absolute');
664                    toolbar.css('z-index', 2);
665                    // Hide on single click when overlayed
666                    if (toolbar.filter('[data-settings~="hide"]').length != 0) {
667                        main.click(function () {
668                            toggleToolbar(uid, undefined, undefined, 0);
669                        });
670                        plain.click(function () {
671                            toggleToolbar(uid, false, undefined, 0);
672                        });
673                    }
674                } else {
675                    toolbar.css('z-index', 4);
676                }
677                // Enable delay on mouseout
678                if (toolbar.filter('[data-settings~="delay"]').length != 0) {
679                    urvanov_syntax_highlighters[uid].toolbar_delay = 500;
680                }
681                // Use .hover() for chrome, but in firefox mouseover/mouseout worked best
682                c.mouseenter(function () {
683                    toggleToolbar(uid, true);
684                })
685                    .mouseleave(function () {
686                        toggleToolbar(uid, false);
687                    });
688            } else if (touchscreen) {
689                toolbar.show();
690            }
691
692            // Minimize
693            if (c.filter('[data-settings~="minimize"]').length == 0) {
694                base.minimize(uid);
695            }
696
697            // Plain show events
698            if (plain.length != 0 && !touchscreen) {
699                if (plain.filter('[data-settings~="dblclick"]').length != 0) {
700                    main.dblclick(function () {
701                        UrvanovSyntaxHighlighterSyntax.togglePlain(uid);
702                    });
703                } else if (plain.filter('[data-settings~="click"]').length != 0) {
704                    main.click(function () {
705                        UrvanovSyntaxHighlighterSyntax.togglePlain(uid);
706                    });
707                } else if (plain.filter('[data-settings~="mouseover"]').length != 0) {
708                    c.mouseenter(function () {
709                        UrvanovSyntaxHighlighterSyntax.togglePlain(uid, true);
710                    })
711                        .mouseleave(function () {
712                            UrvanovSyntaxHighlighterSyntax.togglePlain(uid, false);
713                        });
714                    numsButton.hide();
715                }
716                if (plain.filter('[data-settings~="show-plain-default"]').length != 0) {
717                    // XXX
718                    UrvanovSyntaxHighlighterSyntax.togglePlain(uid, true);
719                }
720            }
721
722            // Scrollbar show events
723            var expand = c.filter('[data-settings~="expand"]').length != 0;
724//            urvanov_syntax_highlighters[uid].mouse_expand = expand;
725            if (!touchscreen && c.filter('[data-settings~="scroll-mouseover"]').length != 0) {
726                // Disable on touchscreen devices and when set to mouseover
727                main.css('overflow', 'hidden');
728                plain.css('overflow', 'hidden');
729                c.mouseenter(function () {
730                    toggle_scroll(uid, true, expand);
731                })
732                .mouseleave(function () {
733                    toggle_scroll(uid, false, expand);
734                });
735            }
736
737            if (expand) {
738                c.mouseenter(function () {
739                    toggleExpand(uid, true);
740                })
741                    .mouseleave(function () {
742                        toggleExpand(uid, false);
743                    });
744            }
745
746            // Disable animations
747            if (c.filter('[data-settings~="disable-anim"]').length != 0) {
748                urvanov_syntax_highlighters[uid].time = 0;
749            }
750
751            // Wrap
752            if (c.filter('[data-settings~="wrap"]').length != 0) {
753                urvanov_syntax_highlighters[uid].wrapped = true;
754            }
755
756            // Determine if Mac
757            urvanov_syntax_highlighters[uid].mac = c.hasClass('urvanov-syntax-highlighter-os-mac');
758
759            // Update clickable buttons
760            updateNumsButton(uid);
761            updatePlainButton(uid);
762            updateWrap(uid);
763        };
764
765        var makeUID = function (uid) {
766            UrvanovSyntaxHighlighterUtil.log(urvanov_syntax_highlighters);
767            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
768                urvanov_syntax_highlighters[uid] = $('#' + uid);
769                UrvanovSyntaxHighlighterUtil.log('make ' + uid);
770                return true;
771            }
772
773            UrvanovSyntaxHighlighterUtil.log('no make ' + uid);
774            return false;
775        };
776
777        var getUID = function () {
778            return currUID++;
779        };
780
781        var codePopup = function (uid) {
782            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
783                return makeUID(uid);
784            }
785            var settings = urvanov_syntax_highlighters[uid].popup_settings;
786            if (settings && settings.data) {
787                // Already done
788                return;
789            }
790
791            var clone = urvanov_syntax_highlighters[uid].clone(true);
792            clone.removeClass('urvanov-syntax-highlighter-wrapped');
793
794            // Unwrap
795            if (urvanov_syntax_highlighters[uid].wrapped) {
796                $(URVANOV_SYNTAX_HIGHLIGHTER_NUM, clone).each(function () {
797                    var line_id = $(this).attr('data-line');
798                    var line = $('#' + line_id);
799                    var height = line.attr('data-height');
800                    height = height ? height : '';
801                    if (typeof height != 'undefined') {
802                        line.css('height', height);
803                        $(this).css('height', height);
804                    }
805                });
806            }
807            clone.find(URVANOV_SYNTAX_HIGHLIGHTER_MAIN).css('height', '');
808
809            var code = '';
810            if (urvanov_syntax_highlighters[uid].plainVisible) {
811                code = clone.find(URVANOV_SYNTAX_HIGHLIGHTER_PLAIN);
812            } else {
813                code = clone.find(URVANOV_SYNTAX_HIGHLIGHTER_MAIN);
814            }
815
816            settings.data = base.getAllCSS() + '<body class="urvanov-syntax-highlighter-popup-window" style="padding:0; margin:0;"><div class="' + clone.attr('class') +
817                ' urvanov-syntax-highlighter-popup">' + base.removeCssInline(base.getHtmlString(code)) + '</div></body>';
818        };
819
820        base.minimize = function (uid) {
821            var button = $('<div class="urvanov-syntax-highlighter-minimize urvanov-syntax-highlighter-button"><div>');
822            urvanov_syntax_highlighters[uid].tools.append(button);
823            // TODO translate
824            urvanov_syntax_highlighters[uid].origTitle = urvanov_syntax_highlighters[uid].title.html();
825            if (!urvanov_syntax_highlighters[uid].origTitle) {
826                urvanov_syntax_highlighters[uid].title.html(strings.minimize);
827            };
828            var cls = 'urvanov-syntax-highlighter-minimized';
829            var show = function () {
830                urvanov_syntax_highlighters[uid].toolbarPreventHide = false;
831                button.remove();
832                urvanov_syntax_highlighters[uid].removeClass(cls);
833                urvanov_syntax_highlighters[uid].title.html(urvanov_syntax_highlighters[uid].origTitle);
834                var toolbar = urvanov_syntax_highlighters[uid].toolbar;
835                if (toolbar.filter('[data-settings~="never-show"]').length != 0) {
836                    toolbar.remove();
837                }
838            };
839            urvanov_syntax_highlighters[uid].toolbar.click(show);
840            button.click(show);
841            urvanov_syntax_highlighters[uid].addClass(cls);
842            urvanov_syntax_highlighters[uid].toolbarPreventHide = true;
843            toggleToolbar(uid, undefined, undefined, 0);
844        }
845
846        base.getHtmlString = function (object) {
847            return $('<div>').append(object.clone()).remove().html();
848        };
849
850        base.removeCssInline = function (string) {
851            var reStyle = /style\s*=\s*"([^"]+)"/gmi;
852            var match = null;
853            while ((match = reStyle.exec(string)) != null) {
854                var repl = match[1];
855                repl = repl.replace(/\b(?:width|height)\s*:[^;]+;/gmi, '');
856                string = string.sliceReplace(match.index, match.index + match[0].length, 'style="' + repl + '"');
857            }
858            return string;
859        };
860
861        // Get all CSS on the page as a string
862        base.getAllCSS = function () {
863            var css_str = '';
864            var css = $('link[rel="stylesheet"]');
865            var filtered = [];
866            if (css.length == 1) {
867                // For minified CSS, only allow a single file
868                filtered = css;
869            } else {
870                // Filter all others for UrvanovSyntaxHighlighter CSS
871                filtered = css.filter('[href*="urvanov-syntax-highlighter"], [href*="min/"]');
872            }
873            filtered.each(function () {
874                var string = base.getHtmlString($(this));
875                css_str += string;
876            });
877            return css_str;
878        };
879
880        base.copyPlain = function (uid, hover) {
881            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
882                return makeUID(uid);
883            }
884
885            var plain = urvanov_syntax_highlighters[uid].plain;
886            
887            var plainTextCode = plain[0].value;
888
889            navigator.clipboard.writeText(plainTextCode)
890                .then(value => urvanovSyntaxHighlighterInfo(uid, strings.copy));
891            return false;
892        };
893
894        var urvanovSyntaxHighlighterInfo = function (uid, text, show) {
895            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
896                return makeUID(uid);
897            }
898
899            var info = urvanov_syntax_highlighters[uid].info;
900
901            if (typeof text == 'undefined') {
902                text = '';
903            }
904            if (typeof show == 'undefined') {
905                show = true;
906            }
907
908            if (isSlideHidden(info) && show) {
909                info.html('<div>
909' + text + '</div>');
910                info.css('margin-top', -info.outerHeight());
911                info.show();
912                urvanovSyntaxHighlighterSlide(uid, info, true);
913                setTimeout(function () {
914                    urvanovSyntaxHighlighterSlide(uid, info, false);
915                }, 5000);
916            }
917
918            if (!show) {
919                urvanovSyntaxHighlighterSlide(uid, info, false);
920            }
921
922        };
923
924        var retina = function (uid) {
925            if (window.devicePixelRatio > 1) {
926                var buttons = $('.urvanov-syntax-highlighter-button-icon', urvanov_syntax_highlighters[uid].toolbar);
927                buttons.each(function () {
928                    var lowres = $(this).css('background-image');
929                    var highres = lowres.replace(/\.(?=[^\.]+$)/g, '@2x.');
930                    $(this).css('background-size', '48px 128px');
931                    $(this).css('background-image', highres);
932                });
933            }
934        };
935
936        var isSlideHidden = function (object) {
937            var object_neg_height = '-' + object.outerHeight() + 'px';
938            if (object.css('margin-top') == object_neg_height || object.css('display') == 'none') {
939                return true;
940            } else {
941                return false;
942            }
943        };
944
945        var urvanovSyntaxHighlighterSlide = function (uid, object, show, animTime, hideDelay, callback) {
946            var complete = function () {
947                if (callback) {
948                    callback(uid, object);
949                }
950            }
951            var objectNegHeight = '-' + object.outerHeight() + 'px';
952
953            if (typeof show == 'undefined') {
954                if (isSlideHidden(object)) {
955                    show = true;
956                } else {
957                    show = false;
958                }
959            }
960            // Instant means no time delay for showing/hiding
961            if (typeof animTime == 'undefined') {
962                animTime = 100;
963            }
964            if (animTime == false) {
965                animTime = false;
966            }
967            if (typeof hideDelay == 'undefined') {
968                hideDelay = 0;
969            }
970            object.stop(true);
971            if (show == true) {
972                object.show();
973                object.animate({
974                    marginTop: 0
975                }, animt(animTime, uid), complete);
976            } else if (show == false) {
977                // Delay if fully visible
978                if (/*instant == false && */object.css('margin-top') == '0px' && hideDelay) {
979                    object.delay(hideDelay);
980                }
981                object.animate({
982                    marginTop: objectNegHeight
983                }, animt(animTime, uid), function () {
984                    object.hide();
985                    complete();
986                });
987            }
988        };
989
990        base.togglePlain = function (uid, hover, select) {
991            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
992                return makeUID(uid);
993            }
994
995            var main = urvanov_syntax_highlighters[uid].main;
996            var plain = urvanov_syntax_highlighters[uid].plain;
997
998            if ((main.is(':animated') || plain.is(':animated')) && typeof hover == 'undefined') {
999                return;
1000            }
1001
1002            reconsileDimensions(uid);
1003
1004            var visible, hidden;
1005            if (typeof hover != 'undefined') {
1006                if (hover) {
1007                    visible = main;
1008                    hidden = plain;
1009                } else {
1010                    visible = plain;
1011                    hidden = main;
1012                }
1013            } else {
1014                if (main.css('z-index') == 1) {
1015                    visible = main;
1016                    hidden = plain;
1017                } else {
1018                    visible = plain;
1019                    hidden = main;
1020                }
1021            }
1022
1023            urvanov_syntax_highlighters[uid].plainVisible = (hidden == plain);
1024
1025            // Remember scroll positions of visible
1026            urvanov_syntax_highlighters[uid].top = visible.scrollTop();
1027            urvanov_syntax_highlighters[uid].left = visible.scrollLeft();
1028
1029            /* Used to detect a change in overflow when the mouse moves out
1030             * of the UrvanovSyntaxHighlighter. If it does, then overflow has already been changed,
1031             * no need to revert it after toggling plain. */
1032            urvanov_syntax_highlighters[uid].scrollChanged = false;
1033
1034            // Hide scrollbars during toggle to avoid Chrome weird draw error
1035            // visible.css('overflow', 'hidden');
1036            // hidden.css('overflow', 'hidden');
1037
1038            fixScrollBlank(uid);
1039
1040            // Show hidden, hide visible
1041            visible.stop(true);
1042            visible.fadeTo(animt(500, uid), 0,
1043                function () {
1044                    visible.css('z-index', 0);
1045                });
1046            hidden.stop(true);
1047            hidden.fadeTo(animt(500, uid), 1,
1048                function () {
1049                    hidden.css('z-index', 1);
1050                    // Give focus to plain code
1051                    if (hidden == plain) {
1052                        if (select) {
1053                            plain.select();
1054                        } else {
1055                            // XXX not needed
1056                            // plain.focus();
1057                        }
1058                    }
1059
1060                    // Refresh scrollbar draw
1061                    hidden.scrollTop(urvanov_syntax_highlighters[uid].top + 1);
1062                    hidden.scrollTop(urvanov_syntax_highlighters[uid].top);
1063                    hidden.scrollLeft(urvanov_syntax_highlighters[uid].left + 1);
1064                    hidden.scrollLeft(urvanov_syntax_highlighters[uid].left);
1065                });
1066
1067            // Restore scroll positions to hidden
1068            hidden.scrollTop(urvanov_syntax_highlighters[uid].top);
1069            hidden.scrollLeft(urvanov_syntax_highlighters[uid].left);
1070
1071            updatePlainButton(uid);
1072
1073            // Hide toolbar if possible
1074            toggleToolbar(uid, false);
1075            return false;
1076        };
1077
1078        base.toggleNums = function (uid, hide, instant) {
1079            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
1080                makeUID(uid);
1081                return false;
1082            }
1083
1084            if (urvanov_syntax_highlighters[uid].table.is(':animated')) {
1085                return false;
1086            }
1087            var numsWidth = Math.round(urvanov_syntax_highlighters[uid].nums_content.outerWidth() + 1);
1088            var negWidth = '-' + numsWidth + 'px';
1089
1090            // Force hiding
1091            var numHidden;
1092            if (typeof hide != 'undefined') {
1093                numHidden = false;
1094            } else {
1095                // Check hiding
1096                numHidden = (urvanov_syntax_highlighters[uid].table.css('margin-left') == negWidth);
1097            }
1098
1099            var numMargin;
1100            if (numHidden) {
1101                // Show
1102                numMargin = '0px';
1103                urvanov_syntax_highlighters[uid].numsVisible = true;
1104            } else {
1105                // Hide
1106                urvanov_syntax_highlighters[uid].table.css('margin-left', '0px');
1107                urvanov_syntax_highlighters[uid].numsVisible = false;
1108                numMargin = negWidth;
1109            }
1110
1111            if (typeof instant != 'undefined') {
1112                urvanov_syntax_highlighters[uid].table.css('margin-left', numMargin);
1113                updateNumsButton(uid);
1114                return false;
1115            }
1116
1117            // Stop jerking animation from scrollbar appearing for a split second due to
1118            // change in width. Prevents scrollbar disappearing if already visible.
1119            var h_scroll_visible = (urvanov_syntax_highlighters[uid].table.outerWidth() + pxToInt(urvanov_syntax_highlighters[uid].table.css('margin-left')) > urvanov_syntax_highlighters[uid].main.outerWidth());
1120            var v_scroll_visible = (urvanov_syntax_highlighters[uid].table.outerHeight() > urvanov_syntax_highlighters[uid].main.outerHeight());
1121            if (!h_scroll_visible && !v_scroll_visible) {
1122                urvanov_syntax_highlighters[uid].main.css('overflow', 'hidden');
1123            }
1124            urvanov_syntax_highlighters[uid].table.animate({
1125                marginLeft: numMargin
1126            }, animt(200, uid), function () {
1127                if (typeof urvanov_syntax_highlighters[uid] != 'undefined') {
1128                    updateNumsButton(uid);
1129                    if (!h_scroll_visible && !v_scroll_visible) {
1130                        urvanov_syntax_highlighters[uid].main.css('overflow', 'auto');
1131                    }
1132                }
1133            });
1134            return false;
1135        };
1136
1137        base.toggleWrap = function (uid) {
1138            urvanov_syntax_highlighters[uid].wrapped = !urvanov_syntax_highlighters[uid].wrapped;
1139            updateWrap(uid);
1140        };
1141
1142        base.toggleExpand = function (uid) {
1143            var expand = !UrvanovSyntaxHighlighterUtil.setDefault(urvanov_syntax_highlighters[uid].expanded, false);
1144            toggleExpand(uid, expand);
1145        };
1146
1147        var updateWrap = function (uid, restore) {
1148            restore = UrvanovSyntaxHighlighterUtil.setDefault(restore, true);
1149            if (urvanov_syntax_highlighters[uid].wrapped) {
1150                urvanov_syntax_highlighters[uid].addClass(URVANOV_SYNTAX_HIGHLIGHTER_WRAPPED);
1151            } else {
1152                urvanov_syntax_highlighters[uid].removeClass(URVANOV_SYNTAX_HIGHLIGHTER_WRAPPED);
1153            }
1154            updateWrapButton(uid);
1155            if (!urvanov_syntax_highlighters[uid].expanded && restore) {
1156                restoreDimensions(uid);
1157            }
1158            urvanov_syntax_highlighters[uid].wrapTimes = 0;
1159            clearInterval(urvanov_syntax_highlighters[uid].wrapTimer);
1160            urvanov_syntax_highlighters[uid].wrapTimer = setInterval(function () {
1161                if (urvanov_syntax_highlighters[uid].is(':visible')) {
1162                    // XXX if hidden the height can't be determined
1163                    reconsileLines(uid);
1164                    urvanov_syntax_highlighters[uid].wrapTimes++;
1165                    if (urvanov_syntax_highlighters[uid].wrapTimes == 5) {
1166                        clearInterval(urvanov_syntax_highlighters[uid].wrapTimer);
1167                    }
1168                }
1169            }, 200);
1170        };
1171
1172        var fixTableWidth = function (uid) {
1173            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
1174                makeUID(uid);
1175                return false;
1176            }
1177        };
1178
1179        // Convert '-10px' to -10
1180        var pxToInt = function (pixels) {
1181            if (typeof pixels != 'string') {
1182                return 0;
1183            }
1184            var result = pixels.replace(/[^-0-9]/g, '');
1185            if (result.length == 0) {
1186                return 0;
1187            } else {
1188                return parseInt(result);
1189            }
1190        };
1191
1192        var updateNumsButton = function (uid) {
1193            if (typeof urvanov_syntax_highlighters[uid] == 'undefined' || typeof urvanov_syntax_highlighters[uid].numsVisible == 'undefined') {
1194                return;
1195            }
1196            if (urvanov_syntax_highlighters[uid].numsVisible) {
1197                urvanov_syntax_highlighters[uid].numsButton.removeClass(UNPRESSED);
1198                urvanov_syntax_highlighters[uid].numsButton.addClass(PRESSED);
1199            } else {
1200                // TODO doesn't work on iPhone
1201                urvanov_syntax_highlighters[uid].numsButton.removeClass(PRESSED);
1202                urvanov_syntax_highlighters[uid].numsButton.addClass(UNPRESSED);
1203            }
1204        };
1205
1206        var updateWrapButton = function (uid) {
1207            if (typeof urvanov_syntax_highlighters[uid] == 'undefined' || typeof urvanov_syntax_highlighters[uid].wrapped == 'undefined') {
1208                return;
1209            }
1210            if (urvanov_syntax_highlighters[uid].wrapped) {
1211                urvanov_syntax_highlighters[uid].wrapButton.removeClass(UNPRESSED);
1212                urvanov_syntax_highlighters[uid].wrapButton.addClass(PRESSED);
1213            } else {
1214                // TODO doesn't work on iPhone
1215                urvanov_syntax_highlighters[uid].wrapButton.removeClass(PRESSED);
1216                urvanov_syntax_highlighters[uid].wrapButton.addClass(UNPRESSED);
1217            }
1218        };
1219
1220        var updateExpandButton = function (uid) {
1221            if (typeof urvanov_syntax_highlighters[uid] == 'undefined' || typeof urvanov_syntax_highlighters[uid].expanded == 'undefined') {
1222                return;
1223            }
1224
1225            if (urvanov_syntax_highlighters[uid].expanded) {
1226                urvanov_syntax_highlighters[uid].expandButton.removeClass(UNPRESSED);
1227                urvanov_syntax_highlighters[uid].expandButton.addClass(PRESSED);
1228            } else {
1229                // TODO doesn't work on iPhone
1230                urvanov_syntax_highlighters[uid].expandButton.removeClass(PRESSED);
1231                urvanov_syntax_highlighters[uid].expandButton.addClass(UNPRESSED);
1232            }
1233        };
1234
1235        var updatePlainButton = function (uid) {
1236            if (typeof urvanov_syntax_highlighters[uid] == 'undefined' || typeof urvanov_syntax_highlighters[uid].plainVisible == 'undefined') {
1237                return;
1238            }
1239
1240            if (urvanov_syntax_highlighters[uid].plainVisible) {
1241                urvanov_syntax_highlighters[uid].plainButton.removeClass(UNPRESSED);
1242                urvanov_syntax_highlighters[uid].plainButton.addClass(PRESSED);
1243            } else {
1244                // TODO doesn't work on iPhone
1245                urvanov_syntax_highlighters[uid].plainButton.removeClass(PRESSED);
1246                urvanov_syntax_highlighters[uid].plainButton.addClass(UNPRESSED);
1247            }
1248        };
1249
1250        var toggleToolbar = function (uid, show, animTime, hideDelay) {
1251            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
1252                return makeUID(uid);
1253            } else if (!urvanov_syntax_highlighters[uid].toolbarMouseover) {
1254                return;
1255            } else if (show == false && urvanov_syntax_highlighters[uid].toolbarPreventHide) {
1256                return;
1257            } else if (touchscreen) {
1258                return;
1259            }
1260            var toolbar = urvanov_syntax_highlighters[uid].toolbar;
1261
1262            if (typeof hideDelay == 'undefined') {
1263                hideDelay = urvanov_syntax_highlighters[uid].toolbar_delay;
1264            }
1265
1266            urvanovSyntaxHighlighterSlide(uid, toolbar, show, animTime, hideDelay, function () {
1267                urvanov_syntax_highlighters[uid].toolbarVisible = show;
1268            });
1269        };
1270
1271        var addSize = function (orig, add) {
1272            var copy = $.extend({}, orig);
1273            copy.width += add.width;
1274            copy.height += add.height;
1275            return copy;
1276        };
1277
1278        var minusSize = function (orig, minus) {
1279            var copy = $.extend({}, orig);
1280            copy.width -= minus.width;
1281            copy.height -= minus.height;
1282            return copy;
1283        };
1284
1285        var initSize = function (uid) {
1286            if (typeof urvanov_syntax_highlighters[uid].initialSize == 'undefined') {
1287                // Shared for scrollbars and expanding
1288                urvanov_syntax_highlighters[uid].toolbarHeight = urvanov_syntax_highlighters[uid].toolbar.outerHeight();
1289                urvanov_syntax_highlighters[uid].innerSize = {width: urvanov_syntax_highlighters[uid].width(), height: urvanov_syntax_highlighters[uid].height()};
1290                urvanov_syntax_highlighters[uid].outerSize = {width: urvanov_syntax_highlighters[uid].outerWidth(), height: urvanov_syntax_highlighters[uid].outerHeight()};
1291                urvanov_syntax_highlighters[uid].borderSize = minusSize(urvanov_syntax_highlighters[uid].outerSize, urvanov_syntax_highlighters[uid].innerSize);
1292                urvanov_syntax_highlighters[uid].initialSize = {width: urvanov_syntax_highlighters[uid].main.outerWidth(), height: urvanov_syntax_highlighters[uid].main.outerHeight()};
1293                urvanov_syntax_highlighters[uid].initialSize.height += urvanov_syntax_highlighters[uid].toolbarHeight;
1294                urvanov_syntax_highlighters[uid].initialOuterSize = addSize(urvanov_syntax_highlighters[uid].initialSize, urvanov_syntax_highlighters[uid].borderSize);
1295                urvanov_syntax_highlighters[uid].finalSize = {width: urvanov_syntax_highlighters[uid].table.outerWidth(), height: urvanov_syntax_highlighters[uid].table.outerHeight()};
1296                urvanov_syntax_highlighters[uid].finalSize.height += urvanov_syntax_highlighters[uid].toolbarHeight;
1297                // Ensure we don't shrink
1298                urvanov_syntax_highlighters[uid].finalSize.width = 
1298UrvanovSyntaxHighlighterUtil.setMin(urvanov_syntax_highlighters[uid].finalSize.width, urvanov_syntax_highlighters[uid].initialSize.width);
1299                urvanov_syntax_highlighters[uid].finalSize.height = UrvanovSyntaxHighlighterUtil.setMin(urvanov_syntax_highlighters[uid].finalSize.height, urvanov_syntax_highlighters[uid].initialSize.height);
1300                urvanov_syntax_highlighters[uid].diffSize = minusSize(urvanov_syntax_highlighters[uid].finalSize, urvanov_syntax_highlighters[uid].initialSize);
1301                urvanov_syntax_highlighters[uid].finalOuterSize = addSize(urvanov_syntax_highlighters[uid].finalSize, urvanov_syntax_highlighters[uid].borderSize);
1302                urvanov_syntax_highlighters[uid].initialSize.height += urvanov_syntax_highlighters[uid].toolbar.outerHeight();
1303            }
1304        };
1305
1306        var toggleExpand = function (uid, expand) {
1307            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
1308                return makeUID(uid);
1309            }
1310            if (typeof expand == 'undefined') {
1311                return;
1312            }
1313
1314            var main = urvanov_syntax_highlighters[uid].main;
1315            var plain = urvanov_syntax_highlighters[uid].plain;
1316
1317            if (expand) {
1318                if (typeof urvanov_syntax_highlighters[uid].expanded == 'undefined') {
1319                    initSize(uid);
1320                    urvanov_syntax_highlighters[uid].expandTime = UrvanovSyntaxHighlighterUtil.setRange(urvanov_syntax_highlighters[uid].diffSize.width / 3, 300, 800);
1321                    urvanov_syntax_highlighters[uid].expanded = false;
1322                    var placeHolderSize = urvanov_syntax_highlighters[uid].finalOuterSize;
1323                    urvanov_syntax_highlighters[uid].placeholder = $('<div></div>');
1324                    urvanov_syntax_highlighters[uid].placeholder.addClass(URVANOV_SYNTAX_HIGHLIGHTER_PLACEHOLDER);
1325                    urvanov_syntax_highlighters[uid].placeholder.css(placeHolderSize);
1326                    urvanov_syntax_highlighters[uid].before(urvanov_syntax_highlighters[uid].placeholder);
1327                    urvanov_syntax_highlighters[uid].placeholder.css('margin', urvanov_syntax_highlighters[uid].css('margin'));
1328                    $(window).bind('resize', placeholderResize);
1329                }
1330
1331                var expandHeight = {
1332                    'height': 'auto',
1333                    'min-height': 'none',
1334                    'max-height': 'none'
1335                };
1336                var expandWidth = {
1337                    'width': 'auto',
1338                    'min-width': 'none',
1339                    'max-width': 'none'
1340                };
1341
1342                urvanov_syntax_highlighters[uid].outerWidth(urvanov_syntax_highlighters[uid].outerWidth());
1343                urvanov_syntax_highlighters[uid].css({
1344                    'min-width': 'none',
1345                    'max-width': 'none'
1346                });
1347                var newSize = {
1348                    width: urvanov_syntax_highlighters[uid].finalOuterSize.width
1349                };
1350                if (!urvanov_syntax_highlighters[uid].mainHeightAuto && !urvanov_syntax_highlighters[uid].hasOneLine) {
1351                    newSize.height = urvanov_syntax_highlighters[uid].finalOuterSize.height;
1352                    urvanov_syntax_highlighters[uid].outerHeight(urvanov_syntax_highlighters[uid].outerHeight());
1353                }
1354
1355                main.css(expandHeight);
1356                main.css(expandWidth);
1357                urvanov_syntax_highlighters[uid].stop(true);
1358
1359                urvanov_syntax_highlighters[uid].animate(newSize, animt(urvanov_syntax_highlighters[uid].expandTime, uid), function () {
1360                    urvanov_syntax_highlighters[uid].expanded = true;
1361                    updateExpandButton(uid);
1362                });
1363
1364                urvanov_syntax_highlighters[uid].placeholder.show();
1365                $('body').prepend(urvanov_syntax_highlighters[uid]);
1366                urvanov_syntax_highlighters[uid].addClass(URVANOV_SYNTAX_HIGHLIGHTER_EXPANDED);
1367                placeholderResize();
1368            } else {
1369                var initialSize = urvanov_syntax_highlighters[uid].initialOuterSize;
1370                var delay = urvanov_syntax_highlighters[uid].toolbar_delay;
1371                if (initialSize) {
1372                    urvanov_syntax_highlighters[uid].stop(true);
1373                    if (!urvanov_syntax_highlighters[uid].expanded) {
1374                        urvanov_syntax_highlighters[uid].delay(delay);
1375                    }
1376                    var newSize = {
1377                        width: initialSize.width
1378                    };
1379                    if (!urvanov_syntax_highlighters[uid].mainHeightAuto && !urvanov_syntax_highlighters[uid].hasOneLine) {
1380                        newSize.height = initialSize.height;
1381                    }
1382                    urvanov_syntax_highlighters[uid].animate(newSize, animt(urvanov_syntax_highlighters[uid].expandTime, uid), function () {
1383                        expandFinish(uid);
1384                    });
1385                } else {
1386                    setTimeout(function () {
1387                       expandFinish(uid);
1388                    }, delay);
1389                }
1390                urvanov_syntax_highlighters[uid].placeholder.hide();
1391                urvanov_syntax_highlighters[uid].placeholder.before(urvanov_syntax_highlighters[uid]);
1392                urvanov_syntax_highlighters[uid].css({left: 'auto', top: 'auto'});
1393                urvanov_syntax_highlighters[uid].removeClass(URVANOV_SYNTAX_HIGHLIGHTER_EXPANDED);
1394            }
1395
1396            reconsileDimensions(uid);
1397            if (expand) {
1398                updateWrap(uid, false);
1399            }
1400        };
1401
1402        var placeholderResize = function () {
1403            for (uid in urvanov_syntax_highlighters) {
1404                if (urvanov_syntax_highlighters[uid].hasClass(URVANOV_SYNTAX_HIGHLIGHTER_EXPANDED)) {
1405                    urvanov_syntax_highlighters[uid].css(urvanov_syntax_highlighters[uid].placeholder.offset());
1406                }
1407            }
1408        };
1409
1410        var expandFinish = function(uid) {
1411            urvanov_syntax_highlighters[uid].expanded = false;
1412            restoreDimensions(uid);
1413            updateExpandButton(uid);
1414            if (urvanov_syntax_highlighters[uid].wrapped) {
1415                updateWrap(uid);
1416            }
1417        };
1418
1419        var toggle_scroll = function (uid, show, expand) {
1420            if (typeof urvanov_syntax_highlighters[uid] == 'undefined') {
1421                return makeUID(uid);
1422            }
1423            if (typeof show == 'undefined' || expand || urvanov_syntax_highlighters[uid].expanded) {
1424                return;
1425            }
1426
1427            var main = urvanov_syntax_highlighters[uid].main;
1428            var plain = urvanov_syntax_highlighters[uid].plain;
1429
1430            if (show) {
1431                // Show scrollbars
1432                main.css('overflow', 'auto');
1433                plain.css('overflow', 'auto');
1434                if (typeof urvanov_syntax_highlighters[uid].top != 'undefined') {
1435                    visible = (main.css('z-index') == 1 ? main : plain);
1436                    // Browser will not render until scrollbar moves, move it manually
1437                    visible.scrollTop(urvanov_syntax_highlighters[uid].top - 1);
1438                    visible.scrollTop(urvanov_syntax_highlighters[uid].top);
1439                    visible.scrollLeft(urvanov_syntax_highlighters[uid].left - 1);
1440                    visible.scrollLeft(urvanov_syntax_highlighters[uid].left);
1441                }
1442            } else {
1443                // Hide scrollbars
1444                visible = (main.css('z-index') == 1 ? main : plain);
1445                urvanov_syntax_highlighters[uid].top = visible.scrollTop();
1446                urvanov_syntax_highlighters[uid].left = visible.scrollLeft();
1447                main.css('overflow', 'hidden');
1448                plain.css('overflow', 'hidden');
1449            }
1450            // Register that overflow has changed
1451            urvanov_syntax_highlighters[uid].scrollChanged = true;
1452            fixScrollBlank(uid);
1453        };
1454
1455        /* Fix weird draw error, causes blank area to appear where scrollbar once was. */
1456        var fixScrollBlank = function (uid) {
1457            // Scrollbar draw error in Chrome
1458            urvanov_syntax_highlighters[uid].table.style('width', '100%', 'important');
1459            var redraw = setTimeout(function () {
1460                urvanov_syntax_highlighters[uid].table.style('width', '');
1461                clearInterval(redraw);
1462            }, 10);
1463        };
1464
1465        var restoreDimensions = function (uid) {
1466            // Restore dimensions
1467            var main = urvanov_syntax_highlighters[uid].main;
1468            var mainStyle = urvanov_syntax_highlighters[uid].mainStyle;
1469            main.css(mainStyle);
1470            // Width styles also apply to urvanovSyntaxHighlighter
1471            urvanov_syntax_highlighters[uid].css('height', 'auto');
1472            urvanov_syntax_highlighters[uid].css('width', mainStyle['width']);
1473            urvanov_syntax_highlighters[uid].css('max-width', mainStyle['max-width']);
1474            urvanov_syntax_highlighters[uid].css('min-width', mainStyle['min-width']);
1475        };
1476
1477        var reconsileDimensions = function (uid) {
1478            // Reconsile dimensions
1479            urvanov_syntax_highlighters[uid].plain.outerHeight(urvanov_syntax_highlighters[uid].main.outerHeight());
1480        };
1481
1482        var reconsileLines = function (uid) {
1483            $(URVANOV_SYNTAX_HIGHLIGHTER_NUM, urvanov_syntax_highlighters[uid]).each(function () {
1484                var lineID = $(this).attr('data-line');
1485                var line = $('#' + lineID);
1486                var height = null;
1487                if (urvanov_syntax_highlighters[uid].wrapped) {
1488                    line.css('height', '');
1489                    height = line.outerHeight();
1490                    height = height ? height : '';
1491                    // TODO toolbar should overlay title if needed
1492                } else {
1493                    height = line.attr('data-height');
1494                    height = height ? height : '';
1495                    line.css('height', height);
1496                    //line.css('height', line.css('line-height'));
1497                }
1498                $(this).css('height', height);
1499            });
1500        };
1501
1502        var animt = function (x, uid) {
1503            if (x == 'fast') {
1504                x = 200;
1505            } else if (x == 'slow') {
1506                x = 600;
1507            } else if (!isNumber(x)) {
1508                x = parseInt(x);
1509                if (isNaN(x)) {
1510                    return 0;
1511                }
1512            }
1513            return x * urvanov_syntax_highlighters[uid].time;
1514        };
1515
1516        var isNumber = function (x) {
1517            return typeof x == 'number';
1518        };
1519
1520    };
1521
1522    $(document).ready(function () {
1523        UrvanovSyntaxHighlighterSyntax.init();
1524    });
1525})(jQueryUrvanovSyntaxHighlighter);

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.