3
if (typeof self === 'undefined' || !self.Prism || !self.document || !Function.prototype.bind) {
8
* Returns the absolute X, Y offsets for an element
9
* @param {HTMLElement} element
10
* @returns {{top: number, right: number, bottom: number, left: number}}
12
var getOffset = function (element) {
13
var left = 0, top = 0, el = element;
17
left += el.offsetLeft;
19
} while ((el = el.offsetParent) && el.nodeType < 9);
24
left -= el.scrollLeft;
26
} while ((el = el.parentNode) && !/body/i.test(el.nodeName));
31
right: innerWidth - left - element.offsetWidth,
32
bottom: innerHeight - top - element.offsetHeight,
37
var tokenRegexp = /(?:^|\s)token(?=$|\s)/;
38
var activeRegexp = /(?:^|\s)active(?=$|\s)/g;
39
var flippedRegexp = /(?:^|\s)flipped(?=$|\s)/g;
42
* Previewer constructor
43
* @param {string} type Unique previewer type
44
* @param {function} updater Function that will be called on mouseover.
45
* @param {string[]|string=} supportedLanguages Aliases of the languages this previewer must be enabled for. Defaults to "*", all languages.
48
var Previewer = function (type, updater, supportedLanguages, initializer) {
51
this._clsRegexp = RegExp('(?:^|\\s)' + type + '(?=$|\\s)');
53
this.updater = updater;
54
this._mouseout = this.mouseout.bind(this);
55
this.initializer = initializer;
59
if (!supportedLanguages) {
60
supportedLanguages = ['*'];
62
if (Prism.util.type(supportedLanguages) !== 'Array') {
63
supportedLanguages = [supportedLanguages];
65
supportedLanguages.forEach(function (lang) {
66
if (typeof lang !== 'string') {
69
if (!Previewer.byLanguages[lang]) {
70
Previewer.byLanguages[lang] = [];
72
if (Previewer.byLanguages[lang].indexOf(self) < 0) {
73
Previewer.byLanguages[lang].push(self);
76
Previewer.byType[type] = this;
80
* Creates the HTML element for the previewer.
82
Previewer.prototype.init = function () {
86
this._elt = document.createElement('div');
87
this._elt.className = 'prism-previewer prism-previewer-' + this._type;
88
document.body.appendChild(this._elt);
89
if(this.initializer) {
95
* Checks the class name of each hovered element
98
Previewer.prototype.check = function (token) {
100
if (tokenRegexp.test(token.className) && this._clsRegexp.test(token.className)) {
103
} while(token = token.parentNode);
105
if (token && token !== this._token) {
114
Previewer.prototype.mouseout = function() {
115
this._token.removeEventListener('mouseout', this._mouseout, false);
121
* Shows the previewer positioned properly for the current token.
123
Previewer.prototype.show = function () {
131
if (this.updater.call(this._elt, this._token.textContent)) {
132
this._token.addEventListener('mouseout', this._mouseout, false);
134
var offset = getOffset(this._token);
135
this._elt.className += ' active';
137
if (offset.top - this._elt.offsetHeight > 0) {
138
this._elt.className = this._elt.className.replace(flippedRegexp, '');
139
this._elt.style.top = offset.top + 'px';
140
this._elt.style.bottom = '';
142
this._elt.className += ' flipped';
143
this._elt.style.bottom = offset.bottom + 'px';
144
this._elt.style.top = '';
147
this._elt.style.left = offset.left + Math.min(200, this._token.offsetWidth / 2) + 'px';
154
* Hides the previewer.
156
Previewer.prototype.hide = function () {
157
this._elt.className = this._elt.className.replace(activeRegexp, '');
161
* Map of all registered previewers by language
164
Previewer.byLanguages = {};
167
* Map of all registered previewers by type
170
Previewer.byType = {};
173
* Initializes the mouseover event on the code block.
174
* @param {HTMLElement} elt The code block (env.element)
175
* @param {string} lang The language (env.language)
177
Previewer.initEvents = function (elt, lang) {
179
if (Previewer.byLanguages[lang]) {
180
previewers = previewers.concat(Previewer.byLanguages[lang]);
182
if (Previewer.byLanguages['*']) {
183
previewers = previewers.concat(Previewer.byLanguages['*']);
185
elt.addEventListener('mouseover', function (e) {
186
var target = e.target;
187
previewers.forEach(function (previewer) {
188
previewer.check(target);
192
Prism.plugins.Previewer = Previewer;
194
// Initialize the previewers only when needed
195
Prism.hooks.add('after-highlight', function (env) {
196
if(Previewer.byLanguages['*'] || Previewer.byLanguages[env.language]) {
197
Previewer.initEvents(env.element, env.language);
b'\\ No newline at end of file'