Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(796)

Unified Diff: lib/src/prism/plugins/previewer-base/prism-previewer-base.js

Issue 1418513006: update elements and fix some bugs (Closed) Base URL: git@github.com:dart-lang/polymer_elements.git@master
Patch Set: code review updates Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/src/prism/plugins/previewer-base/prism-previewer-base.js
diff --git a/lib/src/prism/plugins/previewer-base/prism-previewer-base.js b/lib/src/prism/plugins/previewer-base/prism-previewer-base.js
new file mode 100644
index 0000000000000000000000000000000000000000..a5eb59adc6fd6626b86f00bf5a3ccb64f2c2e5e6
--- /dev/null
+++ b/lib/src/prism/plugins/previewer-base/prism-previewer-base.js
@@ -0,0 +1,201 @@
+(function() {
+
+ if (typeof self === 'undefined' || !self.Prism || !self.document) {
+ return;
+ }
+
+ /**
+ * Returns the absolute X, Y offsets for an element
+ * @param {HTMLElement} element
+ * @returns {{top: number, right: number, bottom: number, left: number}}
+ */
+ var getOffset = function (element) {
+ var left = 0, top = 0, el = element;
+
+ if (el.parentNode) {
+ do {
+ left += el.offsetLeft;
+ top += el.offsetTop;
+ } while ((el = el.offsetParent) && el.nodeType < 9);
+
+ el = element;
+
+ do {
+ left -= el.scrollLeft;
+ top -= el.scrollTop;
+ } while ((el = el.parentNode) && !/body/i.test(el.nodeName));
+ }
+
+ return {
+ top: top,
+ right: innerWidth - left - element.offsetWidth,
+ bottom: innerHeight - top - element.offsetHeight,
+ left: left
+ };
+ };
+
+ var tokenRegexp = /(?:^|\s)token(?=$|\s)/;
+ var activeRegexp = /(?:^|\s)active(?=$|\s)/g;
+ var flippedRegexp = /(?:^|\s)flipped(?=$|\s)/g;
+
+ /**
+ * Previewer constructor
+ * @param {string} type Unique previewer type
+ * @param {function} updater Function that will be called on mouseover.
+ * @param {string[]|string=} supportedLanguages Aliases of the languages this previewer must be enabled for. Defaults to "*", all languages.
+ * @constructor
+ */
+ var Previewer = function (type, updater, supportedLanguages, initializer) {
+ this._elt = null;
+ this._type = type;
+ this._clsRegexp = RegExp('(?:^|\\s)' + type + '(?=$|\\s)');
+ this._token = null;
+ this.updater = updater;
+ this._mouseout = this.mouseout.bind(this);
+ this.initializer = initializer;
+
+ var self = this;
+
+ if (!supportedLanguages) {
+ supportedLanguages = ['*'];
+ }
+ if (Prism.util.type(supportedLanguages) !== 'Array') {
+ supportedLanguages = [supportedLanguages];
+ }
+ supportedLanguages.forEach(function (lang) {
+ if (typeof lang !== 'string') {
+ lang = lang.lang;
+ }
+ if (!Previewer.byLanguages[lang]) {
+ Previewer.byLanguages[lang] = [];
+ }
+ if (Previewer.byLanguages[lang].indexOf(self) < 0) {
+ Previewer.byLanguages[lang].push(self);
+ }
+ });
+ Previewer.byType[type] = this;
+ };
+
+ /**
+ * Creates the HTML element for the previewer.
+ */
+ Previewer.prototype.init = function () {
+ if (this._elt) {
+ return;
+ }
+ this._elt = document.createElement('div');
+ this._elt.className = 'prism-previewer prism-previewer-' + this._type;
+ document.body.appendChild(this._elt);
+ if(this.initializer) {
+ this.initializer();
+ }
+ };
+
+ /**
+ * Checks the class name of each hovered element
+ * @param token
+ */
+ Previewer.prototype.check = function (token) {
+ do {
+ if (tokenRegexp.test(token.className) && this._clsRegexp.test(token.className)) {
+ break;
+ }
+ } while(token = token.parentNode);
+
+ if (token && token !== this._token) {
+ this._token = token;
+ this.show();
+ }
+ };
+
+ /**
+ * Called on mouseout
+ */
+ Previewer.prototype.mouseout = function() {
+ this._token.removeEventListener('mouseout', this._mouseout, false);
+ this._token = null;
+ this.hide();
+ };
+
+ /**
+ * Shows the previewer positioned properly for the current token.
+ */
+ Previewer.prototype.show = function () {
+ if (!this._elt) {
+ this.init();
+ }
+ if (!this._token) {
+ return;
+ }
+
+ if (this.updater.call(this._elt, this._token.textContent)) {
+ this._token.addEventListener('mouseout', this._mouseout, false);
+
+ var offset = getOffset(this._token);
+ this._elt.className += ' active';
+
+ if (offset.top - this._elt.offsetHeight > 0) {
+ this._elt.className = this._elt.className.replace(flippedRegexp, '');
+ this._elt.style.top = offset.top + 'px';
+ this._elt.style.bottom = '';
+ } else {
+ this._elt.className += ' flipped';
+ this._elt.style.bottom = offset.bottom + 'px';
+ this._elt.style.top = '';
+ }
+
+ this._elt.style.left = offset.left + Math.min(200, this._token.offsetWidth / 2) + 'px';
+ } else {
+ this.hide();
+ }
+ };
+
+ /**
+ * Hides the previewer.
+ */
+ Previewer.prototype.hide = function () {
+ this._elt.className = this._elt.className.replace(activeRegexp, '');
+ };
+
+ /**
+ * Map of all registered previewers by language
+ * @type {{}}
+ */
+ Previewer.byLanguages = {};
+
+ /**
+ * Map of all registered previewers by type
+ * @type {{}}
+ */
+ Previewer.byType = {};
+
+ /**
+ * Initializes the mouseover event on the code block.
+ * @param {HTMLElement} elt The code block (env.element)
+ * @param {string} lang The language (env.language)
+ */
+ Previewer.initEvents = function (elt, lang) {
+ var previewers = [];
+ if (Previewer.byLanguages[lang]) {
+ previewers = previewers.concat(Previewer.byLanguages[lang]);
+ }
+ if (Previewer.byLanguages['*']) {
+ previewers = previewers.concat(Previewer.byLanguages['*']);
+ }
+ elt.addEventListener('mouseover', function (e) {
+ var target = e.target;
+ previewers.forEach(function (previewer) {
+ previewer.check(target);
+ });
+ }, false);
+ };
+ Prism.plugins.Previewer = Previewer;
+
+ // Initialize the previewers only when needed
+ Prism.hooks.add('after-highlight', function (env) {
+ if(Previewer.byLanguages['*'] || Previewer.byLanguages[env.language]) {
+ Previewer.initEvents(env.element, env.language);
+ }
+ });
+
+}());

Powered by Google App Engine
This is Rietveld 408576698