blob: 0f96a71dc9d454ec8b31a81b141396d6eef91a9d [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
/* global jQuery, ace, document, setTimeout, clearTimeout, console */
jQuery(function ($) {
'use strict';
var currentState = 'source';
// Limits the number of times the function gets called for event handlers
function debounce(fn, delay) {
var timer = null;
return function () {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
/**
* The editor object, it will take it's configuration from following attributes:
* id: The unique identifier of the editor (will be used as key in the Editor.all map object).
* data-src: The URL from which the editor's content has to be loaded.
* data-mode: The ACE editor's language mode.
* data-writeable: Boolean attribute to make the editor persisted to the data-src location.
*/
function Editor(DOMElement, reloadOutputCallback) {
var that = this;
var element = $(DOMElement);
var editor = ace.edit(DOMElement);
var mode = element.data('mode');
var url = element.data('src');
var isWriteable = element.is('[data-writeable]');
function attachSaveHandler() {
if (isWriteable) {
editor.session.on('change', debounce(function () {
that.saveChanges();
}), 500);
}
}
function init() {
Editor.all[element.attr('id')] = that;
editor.renderer.setShowGutter(false);
editor.setHighlightActiveLine(false);
editor.setShowPrintMargin(false);
editor.setReadOnly(!isWriteable);
editor.session.setUseWorker(false);
editor.session.setMode(mode);
if (element.is(':visible')) {
that.loadContent(attachSaveHandler);
} else {
attachSaveHandler();
}
}
that.saveChanges = function (cb) {
if (isWriteable) {
$.ajax({
url: url,
type: 'PUT',
data: editor.getValue(),
contentType: 'plain/text',
success: reloadOutputCallback,
complete: cb
});
}
};
that.loadContent = function (cb) {
$.ajax(url, {
type: 'GET',
dataType: 'text',
cache: false,
processData: false,
success: function (data) {
editor.setValue(data);
editor.clearSelection();
},
error: function (req, textStatus, message) {
editor.setValue(req.responseText);
editor.clearSelection();
console.error(message);
},
complete: cb
});
};
init();
}
// A map of all the editors, the id attribute of their parent DOM element is used as key.
Editor.all = {};
// Refreshes the output after changes were made
function reloadOutput() {
if (Editor.all[currentState] !== undefined) {
Editor.all[currentState].loadContent();
} else {
document.getElementsByTagName('iframe')[0].contentDocument.location.reload(true);
}
}
function init() {
// Setup editors
$('.editor').each(function () {
new Editor(this, reloadOutput);
});
// Setup output tabs
var allTargets = $('.output-view');
$('a[data-toggle=tab]').each(function () {
var link = $(this);
var target = allTargets.filter(link.attr('href'));
var state = target.attr('id');
link.click(function () {
currentState = state;
allTargets.addClass('hidden');
target.removeClass('hidden');
reloadOutput();
});
});
}
init();
});