User:Thundercraft5/CodeFiddle.js

/* jshint undef: true, jquery: true, maxerr: 9999 */

/* global mw, CodeFiddle, ace */ mw.loader.using(['mediawiki.widgets', 'mediawiki.widgets.SearchInputWidget'], function {	if (mw.config.get('wgPageName') !== 'Special:CodeFiddle' || window.ReadyCodeFiddle) return;	var noop = function{};	/* Constructor */	window.CodeFiddle = function CodeFiddle {		this.mw = mw.config.get([ 'wgArticlePath', 'wgSiteName', 'wgServer', 'wgPageName', ]);		this.mw.wgArticlePath = this.mw.wgArticlePath.replace(/\$1/, );		document.title = 'Wiki Code Fiddle | ' + this.mw.wgSiteName + ' | Fandom';		this.wikiHref = mw.config.get('wgServer') + this.mw.wgArticlePath;		this.onFrameLoad = this.onFrameLoad.bind(this);		this.updateEditorCSS = this.updateEditorCSS.bind(this);		this.wikiHrefText = this.wikiHref.replace(/^.*?:\/{2}/, );

// Setup Output iframe this.$outputFrame = $(' ', {			id: "code-fiddle-output-frame",			src: this.wikiHref,		}); this.childWindow = this.$outputFrame[0].contentWindow; this.$inputStyles = $(' ', {			type: "text/css",			id: "code-fiddle-injected-styles",		}); this.$inputScript = $(' ', {			type: "text/javascript",			id: "code-fiddle-injected-script",		}); this.$titleInput = new mw.widgets.TitleInputWidget({			id: "code-fiddle-titleinput",		}); this.$console = $(' ', {			id: "code-fiddle-console-output",			html: [				this.createConsoleMessage('log', 'Welcome to the CodeFiddle console.'),			],		}); $('body') .find('.main-container') .empty .end .prepend(this.createMainUI); // Setup editors ace.config.set('basePath', '/extensions-ucp/CodeEditor/modules/ace'); this.jsEditor = ace.edit('code-fiddle-js-editor'); this.cssEditor = ace.edit('code-fiddle-css-editor'); this.cssEditor.session.setMode(new (ace.require("ace/mode/css").Mode)); this.jsEditor.session.setMode(new (ace.require("ace/mode/javascript").Mode)); this.activeEditor = this.jsEditor; this.cssEditor.on('change', this.updateEditorCSS); // Add event listeners $('.code-fiddle-reload').click( => {			this.childWindow.location.reload;			this.setFrameLoading;		}); $('.code-fiddle-stop').click( => {			this.blockFrameLoad;		}); $('.code-fiddle-tab').click(e => {			var $this = $(e.target);			if ($this.hasClass('active')) return;			$('.code-fiddle-tab, .code-fiddle-panel').removeClass('active');			// Find sibling index of tab			const index = $this				.parent				.children				.toArray				.indexOf($this[0]);			$('.code-fiddle-panel').eq(index).addClass('active');			$this.addClass('active');		}); $('.code-fiddle-reload').click(this.toggleReloading.bind(this)); $('.code-fiddle-fullscreen').click(this.toFullScreenPreview.bind(this)); $([window, document]).on('keyup', function(e) {			e.key = e.key.toLowerCase;			if (e.key === 'f11' && e.ctrlKey) this.toFullScreenPreview;		}.bind(this)); // Block default page reload keybind & change it to ctrl-alt-f5/ctrl-alt $([window, document]).on('keydown', function(e) {			e.key = e.key.toLowerCase;			// For frame			if ((e.key === 'f5' || e.key === 'r' && e.ctrlKey) && !e.altKey) {				e.preventDefault;				this.childWindow.location.reload;				this.setOutputLoading;			// Allow normal			} else if ((e.key === 'f5' || e.key === 'r' && e.ctrlKey) && e.altKey) {				window.location.reload;			}		}.bind(this)); this.$titleInput.on('enter', => {			this.$outputFrame.attr('src', this.wikiHref + encodeURIComponent(this.$titleInput.getValue) + '?useskin=FandomDesktop&noexternals=1');			this.setOutputLoading;		}); this.setOutputLoading; };

CodeFiddle.prototype = $.extend({		/* Define variables that will be used */		activeEditor: null,		jsEditor: null,		cssEditor: null,		childWindow: null,		wikiHref: null,		wikiHrefText: null,		$outputFrame: null,		$titleInput: null,		$inputStyles: null,		reloading: false,		createMainUI {			return $(' ', { class: "code-fiddle", html: [ this.createSideBarUI, $(' ', {						class: "code-fiddle-output-wrapper",						html: $(' ', { html: [ $(' ', {									class: "code-fiddle-output-header-wrapper",									html: $(' ', { text: "Code Fiddle Output", class: "code-fiddle-output-header", }),								}),								this.createAddressBarUI, $(' ', {									class: "code-fiddle-frame-wrapper",									html: [										this.$outputFrame,										$(' ', { class: "code-fiddle-frame-overlay", html: $(' ', {												class: "fandom-spinner code-fiddle-frame-spinner",												html: '  ',											}), }),									],								}),							],						}),					}),				],			});		},		createSideBarUI {			return $(' ', { class: "code-fiddle-sidebar", html: [ $(' ', {						class: "code-fiddle-header",						html: [							$(' ', { html: "Wiki Code Fiddle", }),						],					}),					$('', {						class: "code-fiddle-editor-tabs",						html: [							$('', { class: "code-fiddle-tab active", text: "CSS", }),							$('', { class: "code-fiddle-tab", text: "JS", }),							$('', { class: "code-fiddle-tab", text: "Console", }),						],					}),					$(' ', {						class: "code-fiddle-editor-wrapper",						html: [							$(' ', { class: "code-fiddle-editors code-fiddle-panels", html: [ $(' ', {										class: "code-fiddle-panel",										html: [											$(' ', { class: "code-fiddle-editor", id: "code-fiddle-css-editor", }),										],									}),									$(' ', {										class: "code-fiddle-panel active",										html: [											$(' ', { class: "code-fiddle-editor", id: "code-fiddle-js-editor", }),										],									}),									$(' ', {										class: "code-fiddle-panel",										html: [											this.$console,										],									}) ],							}),						],					}),				],			});		},		createAddressBarUI {			return $(' ', { class: "code-fiddle-addressbar", html: [ $(' ', {						class: "code-fiddle-wiki-wrapper",						html: [							$(' ', { class: "code-fiddle-favicon", html: $(' ', { src: $('link[rel="shortcut icon"]').attr('href'), }), }),							$('', { class: "code-fiddle-wiki", href: this.wikiHref, text: this.wikiHrefText, title: this.wikiHref, target: "_blank", }),						],					}),					$(' ', {						class: "code-fiddle-input-wrapper",						html: this.$titleInput.$element,					}), $(' ', {						class: "code-fiddle-addressbar-controls",						html: [							$(' ', { class: "code-fiddle-reload", html: ' ', title: "Reload the Code Output", }),							$(' ', {								class: "code-fiddle-stop", html: ' ', css: { display: "none", },								title: "Stop loading the Code Output", }),							$(" ", {								class: "code-fiddle-fullscreen", html: ' ', title: "Enter fullscreen for the Code Output", })						],					}),				],			});		},		onFrameLoad {			this.childWindow = this.$outputFrame[0].contentWindow;			$('.code-fiddle-frame-wrapper').removeClass('loading');			this.injectEditorCSS				.toggleReloading				.registerServiceWorker				.setupConsolePipe				.addOnFrameLinkClick				.injectEditorJS;		},		setFrameLoading {			$('.code-fiddle-frame-wrapper').addClass('loading');			this.$outputFrame.one('load', this.onFrameLoad);			return this;		},		blockFrameLoad {			this.childWindow.stop;			this.toggleReloading;			$('.code-fiddle-frame-wrapper').removeClass('loading');			return this;		},		setupConsolePipe {			['info', 'debug', 'log', 'warn', 'error'].forEach(function(method) { var oldMethod = this.childWindow.console[method]; this.childWindow.console[method] = function { const data = Array.from(arguments); oldMethod.apply(null, data); this.$console.append(this.createConsoleMessage.apply(this, [method].concat(data))); }.bind(this); }, this);			return this;		},		createConsoleMessage(type) {			const data = Array.from(arguments).slice(1);			return $(' ', { class: "code-fiddle-consolemessage code-fiddle-consolemessage-" + type, html: $(' ', {					class: "code-fiddle-consolemessage-text",					text: '[' + type.toUpperCase + ']: ' + data.join(' '),				}), });		},		injectEditorCSS {			this.updateEditorCSS;			$(this.childWindow.document.head).append(this.$inputStyles);			return this;		},		injectEditorJS {			this.$inputScript.text(this.jsEditor.getValue);			$(this.childWindow.document.head).append(this.$inputScript.clone);				return this;		},		updateEditorCSS {			this.$inputStyles.text(this.cssEditor.getValue);			return this;		},		toggleReloading {			if (this.reloading) {				$('.code-fiddle-stop').hide;				$('.code-fiddle-reload').show;			} else {				$('.code-fiddle-stop').show;				$('.code-fiddle-reload').hide;			}			this.reloading = !this.reloading;			return this;		},		toFullScreenPreview {			this.$outputFrame[0].requestFullscreen.catch(noop);			return this;		},		setOutputLoading {			this.setFrameLoading				.toggleReloading				.addFrameKeyBindings;			return this;		},		addFrameKeyBindings {			$(this.childWindow).on('keyup', function(e) { console.log(e); e.preventDefault; if (e.key.toLowerCase === 'r' && e.ctrlKey) this.childWindow.reload; }.bind(this));			return this;		},		addOnFrameLinkClick {			$(this.childWindow.document).on('click', 'a', function(e) { var href = $(e.target).attr('href'); if (!href) return; href = new mw.Uri(href); var hrefStr = href.toString; const curHref = new mw.Uri(window.location.href); console.log(href.path.replace(this.mw.wgArticlePath, '')); const page = new mw.Title(href.path.replace(this.mw.wgArticlePath, ''));

if (curHref.host !== href.host || !hrefStr.includes(this.mw.wgArticlePath) || page.namespace === -1 || hrefStr.includes('action')) { e.preventDefault; open(hrefStr); return; } else { this.$titleInput.setValue(page.toString); this.$outputFrame.attr('src', hrefStr); this.setOutputLoading; }			}.bind(this));			return this;		},		onSwMessage(e) {			console.log("serviceWorker Message recived:", e.data);			},		registerServiceWorker {			function addWorker {				this.childWindow.navigator.serviceWorker.register('/wiki/User:Thundercraft5/CodeFiddle.js/sw.js?action=raw&ctype=text/javascript').then(reg => { this.serviceWorker = reg.active; this.serviceWorkerRegistration = reg; this.serviceWorker.addEventListener('message', this.onSwMessage.bind(this)); });			}			// Remove old service worker			if (this.serviceWorker) {				console.log(this);				window.navigator.serviceWorker.getRegistrations.then(function(registrations) { registrations[0].unregister; addWorker.call(this); }.bind(this));			} else {				console.log(this);				addWorker.call(this);			}			return this;		},	}, window.CodeFiddle); window.ReadyCodeFiddle = new CodeFiddle; });