mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-27 10:41:15 +00:00
284 lines
8 KiB
JavaScript
284 lines
8 KiB
JavaScript
|
/* ***** BEGIN LICENSE BLOCK *****
|
||
|
* Distributed under the BSD license:
|
||
|
*
|
||
|
* Copyright (c) 2010, Ajax.org B.V.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
* * Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* * Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
* * Neither the name of Ajax.org B.V. nor the
|
||
|
* names of its contributors may be used to endorse or promote products
|
||
|
* derived from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
|
||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
* ***** END LICENSE BLOCK ***** */
|
||
|
|
||
|
define(function(require, exports, module) {
|
||
|
"use strict";
|
||
|
|
||
|
if (typeof document == "undefined")
|
||
|
return;
|
||
|
|
||
|
var XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||
|
|
||
|
exports.getDocumentHead = function(doc) {
|
||
|
if (!doc)
|
||
|
doc = document;
|
||
|
return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
|
||
|
}
|
||
|
|
||
|
exports.createElement = function(tag, ns) {
|
||
|
return document.createElementNS ?
|
||
|
document.createElementNS(ns || XHTML_NS, tag) :
|
||
|
document.createElement(tag);
|
||
|
};
|
||
|
|
||
|
exports.hasCssClass = function(el, name) {
|
||
|
var classes = el.className.split(/\s+/g);
|
||
|
return classes.indexOf(name) !== -1;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Add a CSS class to the list of classes on the given node
|
||
|
*/
|
||
|
exports.addCssClass = function(el, name) {
|
||
|
if (!exports.hasCssClass(el, name)) {
|
||
|
el.className += " " + name;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Remove a CSS class from the list of classes on the given node
|
||
|
*/
|
||
|
exports.removeCssClass = function(el, name) {
|
||
|
var classes = el.className.split(/\s+/g);
|
||
|
while (true) {
|
||
|
var index = classes.indexOf(name);
|
||
|
if (index == -1) {
|
||
|
break;
|
||
|
}
|
||
|
classes.splice(index, 1);
|
||
|
}
|
||
|
el.className = classes.join(" ");
|
||
|
};
|
||
|
|
||
|
exports.toggleCssClass = function(el, name) {
|
||
|
var classes = el.className.split(/\s+/g), add = true;
|
||
|
while (true) {
|
||
|
var index = classes.indexOf(name);
|
||
|
if (index == -1) {
|
||
|
break;
|
||
|
}
|
||
|
add = false;
|
||
|
classes.splice(index, 1);
|
||
|
}
|
||
|
if(add)
|
||
|
classes.push(name);
|
||
|
|
||
|
el.className = classes.join(" ");
|
||
|
return add;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Add or remove a CSS class from the list of classes on the given node
|
||
|
* depending on the value of <tt>include</tt>
|
||
|
*/
|
||
|
exports.setCssClass = function(node, className, include) {
|
||
|
if (include) {
|
||
|
exports.addCssClass(node, className);
|
||
|
} else {
|
||
|
exports.removeCssClass(node, className);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
exports.hasCssString = function(id, doc) {
|
||
|
var index = 0, sheets;
|
||
|
doc = doc || document;
|
||
|
|
||
|
if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
|
||
|
while (index < sheets.length)
|
||
|
if (sheets[index++].owningElement.id === id) return true;
|
||
|
} else if ((sheets = doc.getElementsByTagName("style"))) {
|
||
|
while (index < sheets.length)
|
||
|
if (sheets[index++].id === id) return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
exports.importCssString = function importCssString(cssText, id, doc) {
|
||
|
doc = doc || document;
|
||
|
// If style is already imported return immediately.
|
||
|
if (id && exports.hasCssString(id, doc))
|
||
|
return null;
|
||
|
|
||
|
var style;
|
||
|
|
||
|
if (doc.createStyleSheet) {
|
||
|
style = doc.createStyleSheet();
|
||
|
style.cssText = cssText;
|
||
|
if (id)
|
||
|
style.owningElement.id = id;
|
||
|
} else {
|
||
|
style = doc.createElementNS
|
||
|
? doc.createElementNS(XHTML_NS, "style")
|
||
|
: doc.createElement("style");
|
||
|
|
||
|
style.appendChild(doc.createTextNode(cssText));
|
||
|
if (id)
|
||
|
style.id = id;
|
||
|
|
||
|
exports.getDocumentHead(doc).appendChild(style);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
exports.importCssStylsheet = function(uri, doc) {
|
||
|
if (doc.createStyleSheet) {
|
||
|
doc.createStyleSheet(uri);
|
||
|
} else {
|
||
|
var link = exports.createElement('link');
|
||
|
link.rel = 'stylesheet';
|
||
|
link.href = uri;
|
||
|
|
||
|
exports.getDocumentHead(doc).appendChild(link);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
exports.getInnerWidth = function(element) {
|
||
|
return (
|
||
|
parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
|
||
|
parseInt(exports.computedStyle(element, "paddingRight"), 10) +
|
||
|
element.clientWidth
|
||
|
);
|
||
|
};
|
||
|
|
||
|
exports.getInnerHeight = function(element) {
|
||
|
return (
|
||
|
parseInt(exports.computedStyle(element, "paddingTop"), 10) +
|
||
|
parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
|
||
|
element.clientHeight
|
||
|
);
|
||
|
};
|
||
|
|
||
|
if (window.pageYOffset !== undefined) {
|
||
|
exports.getPageScrollTop = function() {
|
||
|
return window.pageYOffset;
|
||
|
};
|
||
|
|
||
|
exports.getPageScrollLeft = function() {
|
||
|
return window.pageXOffset;
|
||
|
};
|
||
|
}
|
||
|
else {
|
||
|
exports.getPageScrollTop = function() {
|
||
|
return document.body.scrollTop;
|
||
|
};
|
||
|
|
||
|
exports.getPageScrollLeft = function() {
|
||
|
return document.body.scrollLeft;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
if (window.getComputedStyle)
|
||
|
exports.computedStyle = function(element, style) {
|
||
|
if (style)
|
||
|
return (window.getComputedStyle(element, "") || {})[style] || "";
|
||
|
return window.getComputedStyle(element, "") || {};
|
||
|
};
|
||
|
else
|
||
|
exports.computedStyle = function(element, style) {
|
||
|
if (style)
|
||
|
return element.currentStyle[style];
|
||
|
return element.currentStyle;
|
||
|
};
|
||
|
|
||
|
exports.scrollbarWidth = function(document) {
|
||
|
var inner = exports.createElement("ace_inner");
|
||
|
inner.style.width = "100%";
|
||
|
inner.style.minWidth = "0px";
|
||
|
inner.style.height = "200px";
|
||
|
inner.style.display = "block";
|
||
|
|
||
|
var outer = exports.createElement("ace_outer");
|
||
|
var style = outer.style;
|
||
|
|
||
|
style.position = "absolute";
|
||
|
style.left = "-10000px";
|
||
|
style.overflow = "hidden";
|
||
|
style.width = "200px";
|
||
|
style.minWidth = "0px";
|
||
|
style.height = "150px";
|
||
|
style.display = "block";
|
||
|
|
||
|
outer.appendChild(inner);
|
||
|
|
||
|
var body = document.documentElement;
|
||
|
body.appendChild(outer);
|
||
|
|
||
|
var noScrollbar = inner.offsetWidth;
|
||
|
|
||
|
style.overflow = "scroll";
|
||
|
var withScrollbar = inner.offsetWidth;
|
||
|
|
||
|
if (noScrollbar == withScrollbar) {
|
||
|
withScrollbar = outer.clientWidth;
|
||
|
}
|
||
|
|
||
|
body.removeChild(outer);
|
||
|
|
||
|
return noScrollbar-withScrollbar;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Optimized set innerHTML. This is faster than plain innerHTML if the element
|
||
|
* already contains a lot of child elements.
|
||
|
*
|
||
|
* See http://blog.stevenlevithan.com/archives/faster-than-innerhtml for details
|
||
|
*/
|
||
|
exports.setInnerHtml = function(el, innerHtml) {
|
||
|
var element = el.cloneNode(false);//document.createElement("div");
|
||
|
element.innerHTML = innerHtml;
|
||
|
el.parentNode.replaceChild(element, el);
|
||
|
return element;
|
||
|
};
|
||
|
|
||
|
if ("textContent" in document.documentElement) {
|
||
|
exports.setInnerText = function(el, innerText) {
|
||
|
el.textContent = innerText;
|
||
|
};
|
||
|
|
||
|
exports.getInnerText = function(el) {
|
||
|
return el.textContent;
|
||
|
};
|
||
|
}
|
||
|
else {
|
||
|
exports.setInnerText = function(el, innerText) {
|
||
|
el.innerText = innerText;
|
||
|
};
|
||
|
|
||
|
exports.getInnerText = function(el) {
|
||
|
return el.innerText;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
exports.getParentWindow = function(document) {
|
||
|
return document.defaultView || document.parentWindow;
|
||
|
};
|
||
|
|
||
|
});
|